python日志模块-logging

日志模块

logging

 
logging模块主要可以根据自定义日志信息,在程序运行的时候将日志打印在终端及记录日志到文件中。在这先了解一下logging支持的日志五个级别
debug() 调试级别,一般用于记录程序运行的详细信息
info() 事件级别,一般用于记录程序的运行过程
warnning() 警告级别,,一般用于记录程序出现潜在错误的情形
error() 错误级别,一般用于记录程序出现错误,但不影响整体运行
critical 严重错误级别 , 出现该错误已经影响到整体运行

  • 简单用法,将日志打印到终端
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5
#owner:fuzj

import logging

logging.debug("User %s is loging" % 'jeck')
logging.info("User %s attempted wrong password" % 'fuzj')
logging.warning("user %s attempted wrong password more than 3 times" % 'mary')
logging.error("select db is timeout")
logging.critical("server is down")

输出结果:

WARNING:root:user mary attempted wrong password more than 3 times
ERROR:root:select db is timeout
CRITICAL:root:server is down

发现怎么没有debug和info的日志呢? 原来默认情况下,logging将日志打印到屏幕,日志级别为WARNING。而debug和info在warnning级别之下,所以不打印。我们可以调整一下终端输出级别,为美观一下,自定义日志格式

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5
#owner:fuzj

import logging

logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',                      datefmt='%a, %d %b %Y %H:%M:%S')

logging.debug("User %s is loging" % 'jeck')
logging.info("User %s attempted wrong password" % 'fuzj')
logging.warning("user %s attempted wrong password more than 3 times" % 'mary')
logging.error("select db is timeout")
logging.critical("server is down")

输出结果

Thu, 09 Jun 2016 11:42:08 日志.py[line:13] DEBUG User jeck is loging
Thu, 09 Jun 2016 11:42:08 日志.py[line:14] INFO User fuzj attempted wrong password
Thu, 09 Jun 2016 11:42:08 日志.py[line:15] WARNING user mary attempted wrong password more than 3 times
Thu, 09 Jun 2016 11:42:08 日志.py[line:16] ERROR select db is timeout
Thu, 09 Jun 2016 11:42:08 日志.py[line:17] CRITICAL server is down

这样的输出结果看着还过得去。现在脑补一下上面用到的logging.basicConfig函数

  • logging.basicConfig

    主要可以对日志的输出格式及方式做相关配置支持的参数由:

    • filename: 指定日志文件名
    • filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
      • SDAD
    • format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
      • %(levelno)s: 打印日志级别的数值
      • %(levelname)s: 打印日志级别名称
      • %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
      • %(filename)s: 打印当前执行程序名
      • %(funcName)s: 打印日志的当前函数
      • %(lineno)d: 打印日志的当前行号
      • %(asctime)s: 打印日志的时间
      • %(thread)d: 打印线程ID
      • %(threadName)s: 打印线程名称
      • %(process)d: 打印进程ID
      • %(message)s: 打印日志信息
    • datefmt: 指定时间格式,同time.strftime()
    • level: 设置日志级别,默认为logging.WARNING,可选 logging.DEBUG logging.INFO logging.WARNING logging.ERROR logging.CRITICAL
    • stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
  • 记录日志到文件

现在有了新需求,我不能只打印日志到终端呀,我想记录日志咋办?
很简单,使用上面的logging.basicConfig即可搞定

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5
#owner:fuzj

import logging

#在logging.basciConfig中指定文件和写入方式
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',                      datefmt='%a, %d %b %Y %H:%M:%S',filename="test.log",filemode='a')

logging.debug("User %s is loging" % 'jeck')
logging.info("User %s attempted wrong password" % 'fuzj')
logging.warning("user %s attempted wrong password more than 3 times" % 'mary')
logging.error("select db is timeout")
logging.critical("server is down")

输出效果:
此没有终端输出,发现在同级目录生成了一个test.log文件,打开看看,原来日志都已经写进去了,和上面终端输出的一样

Thu, 09 Jun 2016 11:57:41 日志.py[line:15] DEBUG User jeck is loging
Thu, 09 Jun 2016 11:57:41 日志.py[line:16] INFO User fuzj attempted wrong password
Thu, 09 Jun 2016 11:57:41 日志.py[line:17] WARNING user mary attempted wrong password more than 3 times
Thu, 09 Jun 2016 11:57:41 日志.py[line:18] ERROR select db is timeout
Thu, 09 Jun 2016 11:57:41 日志.py[line:19] CRITICAL server is down

  • 同输出屏幕和记录日志

    现在又有了新需求,我不能只把日志记录到文件,有些日志信息我还是想直接在屏幕输出,而且还不影响日志记录文件,此过程比较复杂,先准备点基础知识

    • logging的四大组件

      • Loggers 提供应用程序可直接使用的接口
      • Handlers 发送日志到适当的目的地
      • Filters 提供了过滤日志信息的方法
      • Formatters 指定日志显示格式

下面看代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5
#owner:fuzj

import logging

logger = logging.getLogger("test.conf")   #创建一个logger,默认为root logger
logger.setLevel(logging.DEBUG)   #设置全局log级别为debug。注意全局的优先级最高

hterm =  logging.StreamHandler()    #创建一个终端输出的handler,设置级别为error
hterm.setLevel(logging.ERROR)

hfile = logging.FileHandler("access.log")    #创建一个文件记录日志的handler,设置级别为info
hfile.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')   #创建一个全局的日志格式

hterm.setFormatter(formatter)   #将日志格式应用到终端handler
hfile.setFormatter(formatter)   #将日志格式应用到文件handler

logger.addHandler(hterm)    #将终端handler添加到logger
logger.addHandler(hfile)    #将文件handler添加到logger

#定义日志msg,注意此时是logger,不是logging了
logger.debug("User %s is loging" % 'jeck')
logger.info("User %s attempted wrong password" % 'fuzj')
logger.warning("user %s attempted wrong password more than 3 times" % 'mary')
logger.error("select db is timeout")
logger.critical("server is down")

结果:
在终端输出:

2016-06-09 12:22:25,283 - test.conf - ERROR - select db is timeout
2016-06-09 12:22:25,283 - test.conf - CRITICAL - server is down

在日志文件里写入:

2016-06-09 12:22:25,283 - test.conf - INFO - User fuzj attempted wrong password
2016-06-09 12:22:25,283 - test.conf - WARNING - user mary attempted wrong password more than 3 times
2016-06-09 12:22:25,283 - test.conf - ERROR - select db is timeout
2016-06-09 12:22:25,283 - test.conf - CRITICAL - server is down

是不是很高大上?不要激动,这只是简单实现了而已。logging模块的功能远不止这些。下面将深入剖析logging的四大组件

先来干货,请看下面脚本:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5
#owner:fuzj

import logging

#创建logger
logger = logging.getLogger()      #创建默认logger
logger1 = logging.getLogger("testlog")     #创建一个名为testlog1的logger实例logger1
logger2 = logging.getLogger("testlog")     #创建一个名为testlog1的logger实例logger2
logger3 = logging.getLogger("testlog.child")   #创建一个testlog子实例logger3

#设置logger的日志级别
logger1.setLevel(logging.DEBUG)     #将logger1日志级别设置为debug
logger2.setLevel(logging.INFO)     #将logger1日志级别设置为info
logger3.setLevel(logging.ERROR)     #将logger1日志级别设置为warning

#创建handler
hterm = logging.StreamHandler()     #输出到终端
hfile = logging.FileHandler("test.log")  #输出到文件

#定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#将日志格式应用到handler
hterm.setFormatter(formatter)
hfile.setFormatter(formatter)

#给logger添加handler
logger.addHandler(hterm)
logger.addHandler(hfile)

logger1.addHandler(hterm)
logger1.addHandler(hfile)

logger2.addHandler(hterm)
logger2.addHandler(hfile)

logger3.addHandler(hterm)
logger3.addHandler(hfile)

#记录日志信息

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

logger1.debug('logger1 debug message')
logger1.info('logger1 info message')
logger1.warning('logger1 warning message')
logger1.error('logger1 error message')
logger1.critical('logger1 critical message')

logger2.debug('logger2 debug message')
logger2.info('logger2 info message')
logger2.warning('logger2 warning message')
logger2.error('logger2 error message')
logger2.critical('logger2 critical message')

logger3.debug('logger3 debug message')
logger3.info('logger3 info message')
logger3.warning('logger3 warning message')
logger3.error('logger3 error message')
logger3.critical('logger3 critical message')

结果:文件和终端输出:

2016-06-09 14:55:46,136 - root - WARNING - logger warning message
2016-06-09 14:55:46,136 - root - ERROR - logger error message
2016-06-09 14:55:46,136 - root - CRITICAL - logger critical message
2016-06-09 14:55:46,136 - testlog - INFO - logger1 info message
2016-06-09 14:55:46,136 - testlog - INFO - logger1 info message
2016-06-09 14:55:46,137 - testlog - WARNING - logger1 warning message
2016-06-09 14:55:46,137 - testlog - WARNING - logger1 warning message
2016-06-09 14:55:46,137 - testlog - ERROR - logger1 error message
2016-06-09 14:55:46,137 - testlog - ERROR - logger1 error message
2016-06-09 14:55:46,137 - testlog - CRITICAL - logger1 critical message
2016-06-09 14:55:46,137 - testlog - CRITICAL - logger1 critical message
2016-06-09 14:55:46,137 - testlog - INFO - logger2 info message
2016-06-09 14:55:46,137 - testlog - INFO - logger2 info message
2016-06-09 14:55:46,137 - testlog - WARNING - logger2 warning message
2016-06-09 14:55:46,137 - testlog - WARNING - logger2 warning message
2016-06-09 14:55:46,137 - testlog - ERROR - logger2 error message
2016-06-09 14:55:46,137 - testlog - ERROR - logger2 error message
2016-06-09 14:55:46,137 - testlog - CRITICAL - logger2 critical message
2016-06-09 14:55:46,137 - testlog - CRITICAL - logger2 critical message
2016-06-09 14:55:46,137 - testlog.child - ERROR - logger3 error message
2016-06-09 14:55:46,137 - testlog.child - ERROR - logger3 error message
2016-06-09 14:55:46,137 - testlog.child - ERROR - logger3 error message
2016-06-09 14:55:46,137 - testlog.child - CRITICAL - logger3 critical message
2016-06-09 14:55:46,137 - testlog.child - CRITICAL - logger3 critical message
2016-06-09 14:55:46,137 - testlog.child - CRITICAL - logger3 critical message
  • logger

logger一个树形层级结构,输出信息之前都要获得一个Logger,logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置.
从输出中发现,
1)root logger由于没有定义loglevel,所以默认是warning,所以输出三天记录
2)logger1 testlog.logger 定义的loglevel是debug,怎么输出的信息是虫info开始呢? 原来logger1和logger2对应的同一个logger实例,logger2重新定义了loglevel,所以logger1和logger2对应的实例loglevel级别就成了info,小心在这里出错
3)从日志条数上看,怎么logger1 和logger2重复输出了2次,logger2重复输出了三次呢,原来和logger的结构有关,他是树形结构,logger = logging.getLogger()显示的创建了root Logger,而我们继续创建的logger1 logger2 则是root logger实例的子实例,而logger3是logger1和logger2的子实例

logger2 = logging.getLogger("testlog")
logger3 = logging.getLogger("testlog.child")

看出来了吧,logger2对应的是testlog,而logger3对应的是testlog.child。这样可得知,一个logger不仅需要自己的handler处理消息,还会把消息发送给自己的父logger的handler。,而子logger如果没有定义日志级别、Handler、Filter等设置,会逐层继承父logger的设置,所以父logger会优先按子logger的属性进行处理,否则就按自己的处理,所以就出现了多次重复日志现象

  • handler

    负责发送相关的信息到指定目的地

    • 常用的Handler方法:

      • Handler.setLevel(lel):指定日志级别,低于lel级别的日志将被忽略
      • Handler.setFormatter():给这个handler选择一个Formatter
      • Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
    • 可用的handler类型有:
      • logging.StreamHandler 可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息
      • logging.FileHandler 用于向一个文件输出日志信息
      • logging.handlers.RotatingFileHandler 类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出
      • logging.handlers.TimedRotatingFileHandler 和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件
      • logging.handlers.SocketHandler 使用TCP协议,将日志信息发送到网络。
      • logging.handlers.DatagramHandler 使用UDP协议,将日志信息发送到网络。
      • logging.handlers.SysLogHandler 日志输出到syslog
      • logging.handlers.NTEventLogHandler 远程输出日志到Windows NT/2000/XP的事件日志
      • ogging.handlers.SMTPHandler 远程输出日志到邮件地址
      • logging.handlers.MemoryHandler 日志输出到内存中的制定buffer
      • logging.handlers.HTTPHandler 通过GETPOST远程输出到HTTP服务器

    具体参考:
    https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers

  • filter

定义handler处理的规则
如定义一个规则

filter=logging.Filter('testlog.child')    #符合testlog.child的才能记录日志到文件
hterm.addFilter(filter)            #将filer应用到hterm的handle

执行结果:
终端输出:

2016-06-09 15:42:30,501 - testlog.child - ERROR - logger3 error message
2016-06-09 15:42:30,501 - testlog.child - ERROR - logger3 error message
2016-06-09 15:42:30,501 - testlog.child - ERROR - logger3 error message
2016-06-09 15:42:30,501 - testlog.child - CRITICAL - logger3 critical message
2016-06-09 15:42:30,501 - testlog.child - CRITICAL - logger3 critical message
2016-06-09 15:42:30,501 - testlog.child - CRITICAL - logger3 critical message

日志输出不变
此处是给logger加了filer,也可以给handler加,但是影响的酒不止一个logger了。他会影响所有使用这个handler的logger

  • formatters

用于定义输出的日志格式。用到的格式化内容可以参考logging.basicConfig()函数

#定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#将日志格式应用到handler
hterm.setFormatter(formatter)
hfile.setFormatter(formatter)
时间: 2024-08-24 17:09:56

python日志模块-logging的相关文章

python日志模块logging

1. 基础用法 python提供了一个标准的日志接口,就是logging模块.日志级别有DEBUG.INFO.WARNING.ERROR.CRITICAL五种(级别依次升高),分别对应的函数为debug().info().warning().error().critical(). >>> import logging >>> logging.debug("ni hao") >>> logging.info("ni hao2

Python之配置日志模块logging

一.定义日志打印方式 如果我们运行自己的程序,有时候需要记录程序运行过程中出现的问题或者信息.可以运用日志模块logging来记录,该模块日志格式可以根据用户需求来自己定义. 常见打印日志信息形式如下: import logging logging.debug("========定义要打印的内容====debug①===========") logging.info("=========定义要打印的内容====info②===========") logging.w

Python 日志工具(logging) 基础教程

什么是 logging ? 日志是跟踪软件运行时发生的事件,软件的开发人员可以通过日志快速的定位问题的位置.事件也分重要性即事件的严重程度. 什么时候使用日志? logging 提供了一组方便操作日志记录的功能,这些是 debug(), info(),warning(),error(),critical(). 通过想要执行的任务确定使用日志记录的方法. 你想要执行的任务 日志记录的最佳方法 一个脚本或程序显示在终端上 print() 程序正常运行过程中发生的事件 logging.info() o

Python标准模块--logging(转载)

转载地址:http://www.cnblogs.com/zhbzz2007/p/5943685.html#undefined Python标准模块--logging 1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息: print将所有信息都输出到标准输出中,严重影响开发者从

python常用模块——logging

日志模块 logging 默认情况下Python的logging模块的日志级别是warning,默认输出到标准输出stdout 默认的日志格式为 日志级别:Logger名称:用户输出消息: 设置logging的默认格式及输出位置使用basicConfig方法. 一. logging模块的常用方法 1. basicConfig(**kwargs) 配置日志基本配置:参数可以是如下: filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储

Python(2.7.6) 标准日志模块 - Logging Handler

Python 标准日志模块使用 Handler 控制日志消息写到不同的目的地,如文件.流.邮件.socket 等.除了StreamHandler. FileHandler 和 NullHandler 定义在 logging 模块中,其他的 Handler 均定义在  logging.hangdlers 模块中.这些 Handler 是:WatchedFileHandler.RotatingFileHandler.TimedRotatingFileHandler.SocketHandler.Dat

python中的日志模块logging

1.日志级别5个: 警告Warning 一般信息Info  调试 Debug  错误Error 致命Critical 2.禁用日志方法 logging.disable(logging.DEBUG) 3.将日志写入文件 logging.basicConfig(filename='log.txt', level=logging.CRITICAL, format=' %(asctime)s - %(levelname)s - %(message)s') 4.格式化输出日志信息 注意事项: 1.日志输出

python 重要的日志模块logging

一,logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息: print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据:logging则可以由开发者决定将信息输出到什么地方,以及怎么输出: logging模块主要分为四个部分: Loggers:提供应用程序直接使

python - 常用模块 - logging模块

python主要是通过logging模块来进行日志处理 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口, 你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error(), critical() 5个级别, 日志级别: DEBUG INFO WARNING ERROR CRITICAL等级依次提高(打印的信息越来越少,DE