Python日志模块的配置和使用
Posted jiaowoxiaoming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python日志模块的配置和使用相关的知识,希望对你有一定的参考价值。
日志
一、日志的级别
CRITICAL : 50
ERROR : 40
WARNING : 30
INFO : 20
DEBUG : 10
NOTSET : 0 (无日志记录)
级别 常量 引用方式 critical 50 logging.CRITICAL error 40 logging.ERROR warning 30 logging.WARNING info 20 logging.INFO debug 10 logging.DEBUG noset 0 logging.NOSET
二、日志的流程
logger中的传递
- Logger 中的日志先经过等级筛选,将高于设定等级的日志信息创建LogRecord对象。
- 在__过滤器__中进行处理。
- 传递到处理器。
- 是否发送至父级日志进行处理
在handler中的传递
- 先经过等级筛选
- 处理器中的过滤器经行过滤
- 发送给响应的处理句柄
三、格式化消息
属性名称 | 格式 | 描述 |
---|---|---|
args | 不需要格式化。 | The tuple of arguments merged into msg to produce message , or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary). |
asctime | %(asctime)s |
|
created | %(created)f |
Time when the LogRecord was created (as returned by time.time() ). |
exc_info | 不需要格式化。 | Exception tuple (à la sys.exc_info ) or, if no exception has occurred, None . |
filename | %(filename)s |
Filename portion of pathname . |
funcName | %(funcName)s |
Name of function containing the logging call. |
levelname | %(levelname)s |
Text logging level for the message (‘DEBUG‘ , ‘INFO‘ , ‘WARNING‘ , ‘ERROR‘ , ‘CRITICAL‘ ). |
levelno | %(levelno)s |
Numeric logging level for the message (DEBUG , INFO , WARNING , ERROR , CRITICAL ). |
lineno | %(lineno)d |
Source line number where the logging call was issued (if available). |
message | %(message)s |
The logged message, computed as msg % args . This is set when Formatter.format() is invoked. |
module | %(module)s |
模块 (filename 的名称部分)。 |
msecs | %(msecs)d |
Millisecond portion of the time when the LogRecord was created. |
msg | 不需要格式化。 | The format string passed in the original logging call. Merged with args to produce message , or an arbitrary object (see 使用任意对象作为消息). |
name | %(name)s |
Name of the logger used to log the call. |
pathname | %(pathname)s |
Full pathname of the source file where the logging call was issued (if available). |
process | %(process)d |
进程ID(如果可用) |
processName | %(processName)s |
进程名(如果可用) |
relativeCreated | %(relativeCreated)d |
Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded. |
stack_info | 不需要格式化。 | Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record. |
thread | %(thread)d |
线程ID(如果可用) |
threadName | %(threadName)s |
线程名(如果可用) |
四、轮替日志
按数量轮替
# 配置文件中的字典参数
'handler_name':{
'class':'logging.handlers.RotatingFileHandler', # 日志轮替的类
'level':'DEBUG', # 记录等级
'formatter':'standard', # 使用的消息格式,填写formatters中的键名
'filename':log_file_name, # 日志文件路径
'maxBytes':512, # 单个日志最大体积,单位:字节
'backupCount':4, # 轮替最多保存数量
'encoding':'utf-8', # 字符编码
},
按时间轮替
# 配置文件中的字典参数
'handler_name':{
'class':'logging.handlers.TimedRotatingFileHandler', # 日志轮替的类
'level':'DEBUG', # 记录等级
'formatter':'standard', # 使用的消息格式,填写formatters中的键名
'filename':log_file_name, # 日志文件路径
'when':'S', # 时间单位。
'interval':10, # 间隔时常
'backupCount':4, # 轮替最多保存数量
'encoding':'utf-8', # 字符编码
},
when 是一个字符串,定义了日志切分的间隔时间单位,这是一个枚举类,可选参数如下:
"S":Second 秒
"M":Minutes 分钟
"H":Hour 小时
"D":Days 天
"W":Week day(0 = Monday)
"midnight":Roll over at midnight
五、日志配置
使用方法来配置日志
import logging
# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
使用配置文件来配置日志
.py脚本
import logging
import logging.config
logging.config.fileConfig('logging.conf')
# create logger
logger = logging.getLogger('simpleExample')
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
配置文件logging.conf:
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
使用字典来配置日志
- version - 用数字表示的模式版本,当前有效值只能为1,主要是为了后续配置升级后提供兼容性
- formatters - 格式化对象,值还是一个dict,该dict的键为格式化对象的id,值为一个dict,存储了formatter对象的配置内容
format
: Nonedatefmt
: None
- filters - 过滤器对象,逻辑同formatters
name
:‘‘
- handlers - 逻辑同formatters
class
(必须的): handler类的全限定名level
(可选的): handler对象级别formatter
(可选的):为formatters中定义的formatter对象idfilters
(可选的):为一个filter对象的列表,里面存放filters中定义的filter对象id
也可以存入其他的参数,视实际handler对象而定
- loggers - 逻辑同formatters,该logger对象的id也是logger name
level
(可选的):logger对象级别propagate
(可选的):logger对象的消息传递设置filters
(可选的):为一个filter对象的列表,里面存放filters中定义的filter对象idhandlers
(可选的):为一个handler对象的列表,里面存放handlers中定义的handler对象id
- root - 值为dict,存放root这个logger对象的配置,但是
propagate
这个值对root没用 - incremental - 该配置文件的配置是否作为已有配置的一个补充,该值默认为
False
,即覆盖原有配置,如果为True
,也不是完全覆盖,因为filter对象和formatter对象是匿名的,无法获取到具体的对象,也就无法修改,但是可以替代logger对象的level
和propagate
属性,handler对象的level
属性 - disable_existing_loggers - 是否禁用已存在的logger对象,默认是
True
,如果incremental是True
的话,该值就会被忽略
注:上述的id处理loggers里的id用来表示实际logger对象的name以外,其他对象的id只是作一个标识作用,用来表示对象之间的联系
通过字典配置参数调用日志,完整代码:
import os
import logging.config
full_formatter = '[%(asctime)s] - [%(levelname)s] - [%(name)s] - [%(module)s模块:%(lineno)d行] - [%(message)s]'
simple_formatter = '[%(asctime)s] - [%(levelname)s] - [%(name)s] - [%(message)s]'
logdir = os.path.join(os.path.dirname(__file__),'logs')
if not os.path.exists(logdir) or not os.path.isdir(logdir):
os.mkdir(logdir)
log_file_name = 'default.log'
log_file_name2 = 'common.log'
log_file_name = os.path.join(logdir,log_file_name)
log_file_name2 = os.path.join(logdir,log_file_name2)
LOGGING_DICT = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': full_formatter,
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'simple': {
'format': simple_formatter
}
},
'filters': {},
'handlers': {
'sh': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple'
},
'fh':{
'class':'logging.handlers.RotatingFileHandler',
'level':'DEBUG',
'formatter':'standard',
'filename':log_file_name,
'maxBytes':512,
'backupCount':4,
'encoding':'utf-8',
},
'fth':{
'class':'logging.handlers.TimedRotatingFileHandler',
'level':'WARNING',
'formatter':'standard',
'filename':log_file_name2,
'when':'S',
'interval':3,
'backupCount':10,
'encoding':'utf-8',
}
},
'loggers': {
'': {
'level': 'DEBUG',
'handlers': ['sh','fh','fth'],
'propagate': True,
}
}
}
def load_log_cfg():
logging.config.dictConfig(LOGGING_DICT)
logger2 = logging.getLogger(__name__)
return logger2
if __name__ == '__main__':
import time
log = load_log_cfg()
t = time.localtime(1111111111)
print(t)
while True:
log.error('这是一个错误日志')
log.critical('这是一个致命错误日志')
log.warning('这是一个警告日志')
log.info('这是一个信息日志')
time.sleep(3)
以上是关于Python日志模块的配置和使用的主要内容,如果未能解决你的问题,请参考以下文章