1. logging模块的基本构成
logging(/usr/lib/python2.7/logging/)含有三个文件,
引用方法分别为
2 import logging.config
3 import logging.handlers
2. logging模块使用的基本概念
a. Logger
主要功能:
1) 输出log信息(debug, info, warning/warn, error, exception, critical/fatal, log等方法)
2) 根据log信息的严重程度通过Handler决定如何输出
Logger的初始化接收两个参数,name和level(默认为NOTSET=0), 其余的参数初始值为(parent, propagate, handlers, disabled)=(None, 1, [], 0), level的初始值通过函数_checklevel(level)来进行初始化。
Manager类主要用于管理Logger的继承关系, 其中的getLogger函数则用于返回返回"a.b.c"这类具有继承关系的Logger对象,对其父子关系进行修正。所以在这里可能出现父类'a'不存在,而子类‘a.b'存在的情形。
getLogger(name)函数这是对Manager.getLogger(name)的一次封装, 若无name,则返回RootLogger(WARNING), 也即是logging.root
b. level
level用来代表消息的严重程度,这些字段都有字符串表示和整型表示, 对应关系如下:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
c. Handler
Handler用于将信息分配到不同的目的地, logging模块中的Handler可以在__init__.py和handlers.py中找到:
__init__.py
class Handler(Filterer)
class StreamHandler(Handler)
class FileHandler(StreamHandler)
handlers.py
class BaseRotatingHandler(logging.FileHandler)
class RotatingFileHandler(BaseRotatingHandler)
class TimedRotatingFileHandler(BaseRotatingHandler)
class WatchedFileHandler(logging.FileHandler)
class SocketHandler(logging.Handler)
class DatagramHandler(SocketHandler)
class SysLogHandler(logging.Handler)
class SMTPHandler(logging.Handler)
class NTEventLogHandler(logging.Handler)
class HTTPHandler(logging.Handler)
class BufferingHandler(logging.Handler)
class MemoryHandler(logging.Handler)
Handlers | 参数 | 备注 |
---|---|---|
Handler | level=NOSET | _name=None, level=_checkLevel(level), formatter=None |
StreamHandler | stream=None | stream=sys.stderr, level=NOSET, _name=None, level=_checkLevel(level), formatter=None |
FileHandler | filename, mode='a', encoding=None, delay=0 | baseFilename=os.path.abspath(filename), 若delay为True则stream=None, 否则stream=self._open() |
BaseRotatingHandler | filename, mode, encoding=None, delay=0 | mode没有默认值的FileHandler初始化 |
RotatingFileHandler | filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0 | 若果maxBytes>0则mode被覆盖为'a' |
TimedRotatingFileHandler | filename, when='h', interval=1, backupCount=0, encoding=None, delay=0 | when=when.upper()为时间的单位, interval为时间的数字 |
WatchedFileHandler | filename, mode='a', encoding=None, delay=0 | dev=-1, ino=-1, 用于监控文件是否改变 |
SocketHandler | host, port | sock=None, closeOnError=0, retryTime=None, retryStart=0.1, retryMax=30.0, retryFactor=2.0, log信息以pickle形式写入一个stream socket |
DatagramHandler | host, port | closeOnError=0, log信息以pickle形式写入一个diagram socket |
SysLogHandler | address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=None | 如果address为一个string,则使用Unix socket, 若要把log信息发送给本地syslogd, 则可以使用(SysLogHandler(address="/dev/log") |
SMTPHandler | mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, _timeout=5.0 |
用于发送email传递log信息, 若要使用非标准SMTP断开,则mailhost使用(host, port)形式。 credentials使用(username, password)参数 |
NTEventLogHandler | appname, dllname=None, logtype='Application' | 发送log信息到NT Event Log, 若无dllname参数,则使用win32service.pyd |
HTTPHandler | host, url, method='GET' | method仅有'POST', 'GET'两个选项 |
BufferingHandler | capacity | buffer=[], 使用flush函数决定内存是否被flush |
MemoryHandler | capacity, flushLevel=logging.ERROR, target=None | 将log信息存入内存,周期性的flush到目标handler中 |
d. Fomatter
初始化方法: Fomatter(fmt=None, datefmt=None)
可选fmt和datefmt参数:
fmt: %(name)s, %(levelno)s, %(levelname)s, %(pathname)s, %(filename)s, %(module)s, %(lineno)d, %(funcName)s, %(created)f, %(asctime)s, %(msecs)d, %(relativeCreated)d, %(thread)d, %(threadName)s, %(process)d, %(message)s
datefmt: '%a, %d %b %Y %H:%M:%S', '%y%m%d %H:%M:%S'
e. Filterer
logging模块中的filter通过logger的名称来定义'a.b.c'等等
3. 函数定制logging的基本步骤
a. 定义logger, 通过函数logging.getLogger(name), 若name=None或者‘’,获得的是root,通过相同的name获得的logger是同一个对象实例
b. 定义handler, 通过前文介绍的Handler子类来定义
c. 为handler定义formatter, 通过logging.Formatter(fmt, datefmt)来定义,通过handler.setFormatter(formatter)来添加
d. 为handler添加level, 通过handler.setLevel(logging.INFO)
e. 为logger 添加handler, 通过logger.addHandler(handler)
4. 配置文件定制日志文件,基本步骤同上,形式上略有变化
a. 配置文件(log.conf为例)
2 [loggers]
3 keys=root, example01, example02
4 [logger_root]
5 level=DEBUG
6 handlers=hand01, hand02
7 [logger_example01]
8 handlers=hand01, hand02
9 qualname=example01
10 propagate=0
11 [logger_example02]
12 handlers=hand01, hand03
13 qualname=example02
14 propagate=0
15 #################################################################
16 [handlers]
17 keys=hand01, hand02, hand03
18 [handler_hand01]
19 class=StreamHandler
20 level=INFO
21 formatter=form02
22 args=[sys.stderr]
23 [handler_hand02]
24 class=FileHandler
25 level=DEBUG
26 formatter=form01
27 args=['test.log', 'a']
28 [handler_hand03]
29 class=handlers.RotatingFileHandler
30 level=INFO
31 formatter=form02
32 args=['log.txt', 'a', 10*1024*1024, 5]
33 ######################################################### [formatters]
34 keys=form01, form02
35 [formatter_form01]
36 format=%(asctime)s %(filename)s %(funcName)s [line: %(lineno)d] %(levelname)s '\n\r' %(message)s
37 datefmt=%a, %d %b %Y %H:%M:%S
38 [formatter_form02]
39 format=%(name)-12s %(levelname)-8s %(message)s
40 datefmt=
b. 调用配置文件
2 import logging
3
4
5 logging.config.fileConfig('log.conf')
6 logger = logging.getLogger('example02')
4. basicConfig
2 # basicConfig默认创建一个StreamHandler, 输出定向为sys.stderr, fomatter为BASIC_FORMAT, 然后将这个handler加到root logger
3 # BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
4 # 常用参数:
5 # filename: 创建一个FileHandler, 指定文件名,而不是StreamHandler
6 # filemode: 指定文件写模式
7 # format: 为handler指定输出格式
8 # datefmt: 指定日期时间格式
9 # level: 指定root logger的logging级别
10 # stream: 指定输出流来初始化StreamHandler, 与filename不可同时使用
11 # ### StreamHandler不会自动关闭输出流,而FileHandler会自动关闭文件
12 logging.basicConfig(
13 level=logging.INFO,
14 format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
15 datefmt='%m-%d %H:%M',
16 filename='a.log',
17 filemode='a')