一、日志模块介绍
在日常编程中,通过日志模块可以帮助开发者跟踪程序运行状态、调试问题以及记录重要事件。可以根据程序打印的日志进行问题的排查跟踪。Python标准库中内置了logging模块用于记录日志,它提供了灵活的日志记录系统。日志分为五个等级,分别为debug、info、warning、error、critical。
import logging
logging.debug('调试日志')
logging.info('消息日志')
logging.warning('警告日志')
logging.error('错误日志')
logging.critical('严重错误日志')
## 执行结果
WARNING:root:警告日志
ERROR:root:错误日志
CRITICAL:root:严重错误日志
这里没有打印debug和info日志,因为默认的日志级别为warning。root是日志的名字,日志默认打印到控制台,也可以配置输出到日志文件。
二、日志基本配置
在上文示例中,日志模块默认级别为warning且输出到控制台,这些都是可以利用日志的配置进行修改的。我们先看一个基本配置:
# 日志基本配置
# 日志基本配置
logging.basicConfig(
# 1、日志级别
level=30,
# DEBUG:10
# INFO:20
# WARNING:30
# ERROR:40
# CRITICAL:50
# 2、日志输出格式
# format='%(asctime)s %(name)s [%(pathname)s line:%(lineno)d] %(levelname)s %(message)s',
# 3、asctime的时间格式
# datefmt='%Y-%m-%d %H:%M:%S',
# 4、日志输出位置:终端/文件
# filename='user.log', # 不指定此配置,默认打印到终端
)
'''
%(name)s Logger的名字(getlogger时指定的名字)
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出日志的完整路径名
%(filename)s 调用日志输出日志的文件名
%(module)s 调用日志输出日志的模块名
%(funcName)s 调用日志输出日志的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
'''
如上所示,如果把level参数设置为10,那就是设置日志级别为debug。format用来控制日志输出格式,可以使用示例中的参数名获取相关的信息,例如%(asctime)s获取当前时间。filename指定日志输出的文件名,如果不指定默认输出到终端。基本配置仍然存在一些问题,例如无法指定编码,在windows默认编码是gbk,这样在输出日志到文件中使用pycharm打开就会乱码,因为pycharm默认是utf-8编码。
三、日志配置字典
日志的基本配置有些问题解决不了,例如指定日志文件的编码,同时输出日志到文件和终端等。这时候就需要日志字典了,如下是一个日志字典的配置:
点击查看日志字典配置
# 日志配置字典
LOGGING_DIC = {
'version': 1.0,
'disable_existing_loggers': False,
# 日志格式
'formatters': {
'standard': {
'format': '%(asctime)s %(threadName)s:%(thread)d [%(name)s] %(levelname)s [%(pathname)s:%(lineno)d] %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'simple': {
'format': '%(asctime)s [%(name)s] %(levelname)s %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'test': {
'format': '%(asctime)s %(message)s',
},
},
'filters': {},
# 日志处理器
'handlers': {
'console_debug_handler': {
'level': 'WARNING', # 日志处理的级别限制
'class': 'logging.StreamHandler', # 输出到终端
'formatter': 'simple' # 日志格式
},
'file_info_handler': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'filename': 'abc.log',
'maxBytes': 800, # 日志大小 10M
'backupCount': 3, # 日志文件保存数量限制
'encoding': 'utf-8',
'formatter': 'standard',
},
'file_debug_handler': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'filename': 'test.log', # 日志存放的路径
'encoding': 'utf-8', # 日志文件的编码
'formatter': 'test',
},
'file_deal_handler': {
'level': 'INFO',
'class': 'logging.FileHandler', # 保存到文件
'filename': 'deal.log', # 日志存放的路径
'encoding': 'utf-8', # 日志文件的编码
'formatter': 'standard',
},
'file_operate_handler': {
'level': 'INFO',
'class': 'logging.FileHandler', # 保存到文件
'filename': 'operate.log', # 日志存放的路径
'encoding': 'utf-8', # 日志文件的编码
'formatter': 'standard',
},
},
# 日志记录器
'loggers': {
'logger1': { # 导入时logging.getLogger时使用的app_name
'handlers': ['console_debug_handler'], # 日志分配到哪个handlers中
'level': 'DEBUG', # 日志记录的级别限制
'propagate': False, # 默认为True,向上(更高级别的logger)传递,设置为False即可,否则会一份日志向上层层传递
},
'logger2': {
'handlers': ['console_debug_handler', 'file_debug_handler'],
'level': 'INFO',
'propagate': False,
},
'': { # 名字匹配不上就用没有名字的这个
'handlers': ['console_debug_handler', 'file_info_handler'],
'level': 'INFO',
'propagate': False,
},
'用户操作': {
'handlers': ['console_debug_handler', 'file_operate_handler'],
'level': 'INFO',
'propagate': False,
},
}
}
这个日志字典可以大体分为四部分,分别是formatters(日志格式)、filters(过滤器)、handlers(日志处理器)、loggers(日志记录器)。这里filters(过滤器)不用管,基本用不到。
3.1、日志格式
日志格式formatters可以定义多个,使用不同的名字,在调用时使用指定的名字即可。例如示例中 simple 格式,输出为 时间 日志名字 日志等级 日志信息,datefmt指定时间格式。当然还可以根据需要配置其他自定义的日志格式,通过内置的变量名即可。
3.2、日志处理器
日志处理器和日志记录器是相对的,日志处理器负责处理日志记录器产生的日志。日志是写入到文件还是输出到控制台都是由日志处理器控制的。可以设置多个日志处理器,例如handler1输出到控制到,handler2输出到日志文件。通过示例可以看到,我们可以通过日志处理器配置日志的编码格式、文件名、日志等级、日志文件大小、保留的日志数量等。
3.3、日志记录器
日志记录器是用来产生日志的,日志记录器一样可以有多个。日志记录器可以指定使用一个或多个日志处理器,可以配置日志级别。这里的日志级别和日志处理器的日志级别并不冲突,可以视为两次筛选,例如日志记录器是debug,那它会记录所有日志丢给日志处理器,但是日志处理器的级别为info,那日志处理器会再过滤掉debug级别的日志。
这里还有一点需要注意的是,我们有一个没有的名字的日志记录器,它的作用是当使用logging.getLogger获取日志记录器时,如果传入的名字不存在,那就会默认使用这个无名字的记录器。但是%(name)s Logger的名字记录的传入的名字。
3.4、使用日志字典
日志字典配置完成后,需要让logging模块加载这个字典。就需要用到logging模块的子包config。这里需要说明的是,logging的__init__.py文件中并没有导入config的名字,因此不能直接用。因此使用config模块需要使用
from logging import config # 用不了logging的其他功能
或者
import logging.config # 可以使用logging的其他功能
这里具体的导入说明可以参考包的介绍。接下来我们看如何加载并使用日志字典:
import logging.config
import settings
logging.config.dictConfig(settings.LOGGING_DIC)
log1 = logging.getLogger('logger1')
log1.info('xxx充值了5毛')
如上,我们把日志字典存放到配置文件settings.py中,调用logging.getLogger获取到日志记录器的名字,就可以用过日志记录器写入日志,日志记录器内部再把日志传给日志处理器。
四、日志配置文件
除了支持日志配置字典外,logging模块还支持ini格式的配置文件,他们的使用方式是类似的。日志配置文件不常用,可参考日志配置文件
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
