一、基本设置
import logging logging.basicConfig( filename='access.log', # 填入文件路径声明日志输出的文件位置,若不指定,则默认输出到终端并打印 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', # 编写日志格式 datefmt='%Y-%m-%d %H:%M:%S %p', # 编写时间格式 level=30, # 声明日志级别,只有大于等于该级别的日志会被输出 # logging.debug('调试debug') level=10,不会被输出 # logging.info('消息info') level=20,不会被输出 # logging.warning('警告warn') level=30,会被输出 # logging.error('egon提现失败') level=40,会被输出 # logging.critical('严重critical') level=50,会被输出 )
二、编写日志格式时涉及的参数
# %(name)s Logger的名字,即用getLogger时指定的名字 # %(levelno)s 数字形式的日志级别 # %(levelname)s 文本形式的日志级别 # %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 # %(filename)s 调用日志输出函数的模块的文件名 # %(module)s 调用日志输出函数的模块名 # %(funcName)s 调用日志输出函数的函数名 # %(lineno)d 调用日志输出函数的语句所在的代码行 # %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 # %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 # %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 # %(thread)d 线程ID。可能没有 # %(threadName)s 线程名。可能没有 # %(process)d 进程ID。可能没有 # %(message)s 用户输出的消息
三、配置日志字典
# 正式配置日志字典前,事先定义好三种格式,在字典中可以直接以变量名引用,若要修改,就可以在字典外操作 standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' \ '%(levelname)s - %(message)s' simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' test_format = '%(asctime)s] %(message)s' # 配置日志字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { # key 'formatters'是格式集 对应的每个子字典是一种格式 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, 'test': { 'format': test_format }, }, 'filters': {}, 'handlers': { # handlers 是日志的接收者,不同的 handler 定义了将日志输出到不同的位置 'console': { # 接收方案 'console' 'level': 'DEBUG', # 日志级别为 'DEBUG',即 level=10 'class': 'logging.StreamHandler', # 日志输出到终端并打印到屏幕 'formatter': 'simple' # 日志格式为 格式集子字典中的 'simple' 对应的格式 }, 'default': { # 接收方案 'default' 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 日志以轮转方式输出到文件 'maxBytes': 1000, # 每次轮转阀值为 1000bytes 'backupCount': 5, # 轮转备份文件数上限为 5,若新备份超过上限,会清理掉最早的备份 'filename': 'xxx.log', # 输出文件的路径 'encoding': 'utf-8', # 声明编码表 'formatter': 'standard' }, 'other': { # 接收方案 'other' 'level': 'DEBUG', 'class': 'logging.FileHandler', # 日志输出到某一文件 'filename': 'zzz.log', 'encoding': 'utf-8', 'formatter': 'test' }, }, 'loggers': { # loggers是日志的产生者,产生的日志会传递给handler然后控制输出 # 用logging.getLogger(__name__)拿到logger的配置 '某某某': { # 日志名 '某某某' 'handlers': ['console', 'other'], # 声明了两个handlers,即日志 既输出到文件又输出到终端打印 'level': 'DEBUG', # logger 声明的日志级别会被 handler 声明的日志级别覆盖,所以一般设置为与之相同 'propagate': False # 默认为True,向更高 level 的 logger 传递,通常设置为False即可,否则会一份日志向上层层传递 }, '终端提示': { 'handlers': ['console', ], # 只输出到终端打印 'level': 'DEBUG', 'propagate': False }, '': { # 不声日志名,则后续未定义的日志名都用此配置 'handlers': ['default', ], # 只输出到文件 'level': 'DEBUG', 'propagate': False }, }, }
四、产生日志
import conf # 日志字典一般存入配置文件夹 conf 里面的 settings.py中,所以要先导入 conf import logging.config # 导入 logging 模块及 logging 下的 config logging.config.dictConfig(conf.setting.LOGGING_DIC) # 加载日志字典 logger1 = logging.getLogger('某某某') logger1.info('info1') # 按照 '某某某' 的配置,'info1' 既输出到文件又输出到终端打印 logger2 = logging.getLogger('终端提示') logger2.info('终端提示:info2') # 按照 '终端提示' 的配置,'终端提示:info2' 只输出到终端打印 logger3 = logging.getLogger('用户交易') logger3.info('交易记录:info3') logger4 = logging.getLogger('用户常规') # 这两条未定义的日志名都按照 '' 的配置,只输出到文件 logger4.info('用户其他:info4')
五、重要提醒
1、日志名的命名:日志名是区别日志业务含义的一种重要提示,要尽量立意明确。
2、日志轮换的重要性
①因为程序运行过程中产生的日志数量会越来越多,为了使日志文件不至于太大而增加内存负担,应对高频使用的日志文件做轮换处理。
②为了能够长期保存日志文件,以便可以随时查看历史记录,轮换文件的上限应该在合理范围内尽量设置多一些。