目录:
一、logging四大组件:
- 记录器(Logger): 提供应用程序代码直接使用的接口
- 处理器(Handler): 将日志记录(由记录器创建)发送适当的目的地,即决定日志在不同端输出-->控制台、日志文件
- 筛选器(Filter):提供了更细粒度的功能,用于确定要输出的日志记录
- 格式器(Formatter):程序在最终输出日志记录的内容格式
-
日志器Logger
-
1创建日志器,若没有指定日志器名称,则默认root
-
logger = logging.getLogger()
print(logger)
输出结果: #<RootLogger root (WARNING)>
1.2 当有多个具有相同名称的日志器,调用任一日志器时将返回对同一记录对象的引用
注:这种情况下的handler是相互叠加的,由于logging每次输出日志记录数量 = handler数量,如有多个handler,实际结果也会打印多条日志记录
import logging
logger = logging.getLogger()
print(logger) #<RootLogger root (WARNING)>
logger1 = logging.getLogger()
print(logger1) #<<RootLogger root (WARNING)>
#设置两个处理器handler
console_handler = logging.StreamHandler()
console_handler1 = logging.StreamHandler()
#给两个相同名称的logger添加上处理器
logger.addHandler(console_handler)
logger1.addHandler(console_handler1)
#设置一下格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
console_handler1.setFormatter(formatter)
#输出日志记录
logger1.warning("=============this is a warning=================")
输出结果:
<RootLogger root (WARNING)>
<RootLogger root (WARNING)> #两个日志器名称相同,则对应的有几个handler就输出几条日志记录
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================
1.3. 通常建议使用__name__来命名日志器,或者自定义名称
import logging
logger = logging.getLogger(__name__)
print(logger) #<Logger __main__ (WARNING)>
logger1 = logging.getLogger("DIY")
print(logger1) #<Logger DIY (WARNING)>
#设置两个处理器handler
console_handler = logging.StreamHandler()
console_handler1 = logging.StreamHandler()
#给两个相同名称的logger添加上处理器
logger.addHandler(console_handler)
logger1.addHandler(console_handler1)
#设置一下格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
console_handler1.setFormatter(formatter)
#输出日志记录
logger1.warning("=============this is a warning=================")
输出结果:
2021-08-11 21:43:45,628 - DIY - WARNING - =============this is a warning=================
2. 处理器Handler
处理器负责将日志消息发送到不同目标,例如:控制台,日志文件,电子邮件等目标
logging模块提供很多个类型的处理器,其中NullHandler、StreamHandler、FileHandler类在核心日志包中定义,直接用,其它处理器在logging.handler中(还有另一个子模块logging.config,用于配置功能)
- SteamHandler: 日志记录发送到控制台,stream:默认为None,日志输出到sys.stder;指定stream的话,日志则输出到指定stream
logging.StreamHandler(stream=None)
- FileHandler: 日志记录发送到磁盘文件中
logging.FileHandler(filename='log.txt',mode='a',encoding=None,delay=False)
参数:
filename: 只填写文件名,则默认新增文件到当前工作目录;填写工作路径+文件名称,则新增到对应工作目录
mode: 默认a模式,可自定义
encoding: 默认为None,可自定义
delay: 默认为False, 如果为True时,将文件打开延迟到第一次调用时进行emit()
- NullHandler: 不做任何事情的处理器,防止sys.stderr在没有日志记录配置的情况下将库的记录事件输出
logging.NullHandler()
- WatchedFileHandler : 该处理器在linux / unix 下使用,它监视文件以查看自上一次发出以来是否已更改。(如果文件的设备或索引节点已更改,则认为改文件已更改),如果文件已更改,则关闭旧文件流,并打开该文件以获取新的流,不适合在window下使用
import logging.handlers
logging.handlers.WatchedFileHandler(filename='log.txt',mode='a',encoding='UTF-8',delay=False)
- RotatingFileHandler:日志记录到文件中,当文件到达指定大小时,打开一个新的文件接着记录,并重命名并增加其后缀为(例如:原文件名.1,原文件名.2)
参数:
maxBytes: 日志文件大小,单位为字节
backupcCount: 备份文件数量
logging.handlers.RotatingFileHandler(filename='log.txt',mode='a',maxBytes=200,backupCount=1)
输出:
- TimeRotatingFileHandler: 日志记录到文件中,支持按时间间隔来更新日志
参数 :
when: 不同值对应不同时间类型,以字符串填入,不区分大小写
3.过滤器Filter
Filters可以由级别使用,输出感兴趣的日志,过滤不感兴趣的日志
4.格式器Formatter
参数:
fmt: 日志格式参数,默认为None,如果不特别指定fmt,则使用'%(message)s'格式
datafmt: 时间格式参数,默认为None,如果不特别指定datafmt,则使用formatTime()文档中描述的格式
style: 风格参数,默认为'%',也支持'$','{' 格式
logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt=None,style='%')
二、Logging的工作流程:
- 一个Logger可以包含多个Handler
- 每个Handler可以设置自己的Filter和Formatter
三、设置日志级别
使用setLevel()方法设置日志级别,注意:若没有设置日志级别,日志器的日志级别默认为WARNING
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
四、输出日志记录
logging模块提供5个日志级别的输出方法
两种方法调用,分别是logging直接调用,或者日志器调用,我们常用的都是创建日志器对象来调用
#logger1为日志器
logger1.warning("=============this is a warning=================")
logger1.info("=================this is a info===================")
logger1.error("=================this is a error==================")
logger1.debug("=================this is a debug==================")
五、日志记录配置
logging模块提供一个配置方法,以字典为容器,设置日志器,处理器,格式器等参数,使用logging.conf.dictConfig(配置字典)方法生成对应的元器件
import logging.handlers
import logging.config
config = {
'version': 1, # 必填项,值只能为1
'disable_existing_loggers': True, # 选填,默认为True,将以向后兼容的方式启用旧行为,此行为是禁用任何现有的非根日志记录器,除非它们或它们的祖先在日志配置中显式命名。如果指定为False,则在进行此调用时存在的记录器将保持启用状态
'incremental': False, # 选填,默认为False,作用,为True时,logging完全忽略任何formatters和filters,仅处理handlers的level
'formatters': # 格式器配置专用key,在这里配置formatter,可配置复数formatter
{
'myformatter1': {
'class': 'logging.Formatter', # 必填,格式器对应的类
'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', # fmt格式
'datefmt': '%Y-%m-%d %H:%M:%S' # 日期时间格式
}
},
'handlers': # 处理器配置专用key,在这里配置handler,可配置复数handler
{
'console_handler': {
'class': 'logging.StreamHandler', # 必填,处理器对应的类
'level': logging.DEBUG, # 选填,处理器的日志级别,可填字符串'info',或者logging.INFO
'formatter': 'myformatter1', # 选填,这里要填写formatters字典中的键
},
'file_handler': {
'class': 'logging.handlers.RotatingFileHandler', # 必填,处理器对应的类
'level': logging.INFO, # 选填,处理器的日志级别,可填字符串'info',或者logging.INFO
'formatter': 'myformatter1', # 选填,这里要填写formatters字典中的键
'filename': './mylog.log', # filehandler特有参数,文件名
'maxBytes': 1024*1024, # 文件大小
'backupCount': 3, # 备份数量
'encoding': 'UTF-8', # 编码格式
}
},
'loggers': # 记录器配置专用key,在这里配置logger,可配置复数logger
{
'logger1': {
'handlers': ['console_handler', 'file_handler'], # 列表形式,元素填handlers字典中的handler
'level': logging.DEBUG, # 选填,记录器的日志级别,不填则默认Warning级别
'propagate': False, # 选填,为False时,禁止将日志消息传递给父级记录器
}
},
'root': # 根记录器专用key
{
'handlers': ['console_handler', 'file_handler'], # 列表形式,元素填handlers字典中的handler
'level': logging.DEBUG, # 选填,记录器的日志级别,不填则默认Warning级别
}
}
# 根据配置字典,配置对应元器件
logging.config.dictConfig(config)
if __name__ == '__main__':
logger = logging.getLogger('logger1') # 获取配置中的logger对象
# 输出logger日志记录
logger.debug("====================【debug】====================")
logger.info("====================【info】====================")
logger.warning("====================【warning】====================")
logger.error("====================【error】====================")
logger.critical("====================【critical】====================")
六、其它实用的方法
logging.basicConfig(**kwargs): 该方法可设置多项参数,来创建StreamHandler或者FileHandler,并添加到根记录器中,从代码上看,更方便更简洁