Python 的 logging 模块完成了灵敏的日志系统。整个模块仅仅 3 个类,不到 5000 行代码的样子,学习它可以加深对顺序日志的了解,本文分下面几个部分:
logging 简介
logging API 设计
记载器对象 Logger
日志记载对象 LogRecord
处置器对象 Hander
格式器对象 Formatter
滚动日志文件处置器
小结
小技巧
logging 简介本次代码运用的是 python 3.8.5 的版本,官方中文文档 3.8.8 。参考链接中官方中文文档十分详细,建议先看一遍了解日志运用。
类 功用我们主要研讨日志如何输入到标准窗口这一主线;日志的配置,日志的线程安全及各种特别的Handler等支线可以先疏忽。
logging API 设计先看看日志运用:
import logging
logging.basicConfig(level=logging.INFO, format='%(levelname)-8s %(name)-10s %(asctime)s %(message)s')
lang = {"name": "python", "age":20}
logging.info('This is a info message %s', lang)
logging.debug('This is a debug message')
logging.warning('This is a warning message')
logger = logging.getLogger(__name__)
logger.warning('This is a warning')
输入内容如下:
INFO root 2021-03-04 00:03:53,473 This is a info message {'name': 'python', 'age': 20}
WARNING root 2021-03-04 00:03:53,473 This is a warning message
WARNING __main__ 2021-03-04 00:03:53,473 This is a warning
可以看到 logging 的运用十分方便,模块直接提供了一组API。
root = RootLogger(WARNING) # 默许提供的logger
Logger.root = root
Logger.manager = Manager(Logger.root)
def debug(msg, *args, **kwargs): # info,warning等api相似
if len(root.handlers) == 0:
basicConfig() # 默许配置
root.debug(msg, *args, **kwargs)
def getLogger(name=None):
if name:
return Logger.manager.getLogger(name) # 创立特定的logger
else:
return root # 前往默许的logger
这种API的提供方式,我们在 requests 中也有看到。api中很重要的设置config的方式:
def basicConfig(**kwargs):
...
if handlers is None:
filename = kwargs.pop("filename", None)
mode = kwargs.pop("filemode", 'a')
if filename:
h = FileHandler(filename, mode)
else:
stream = kwargs.pop("stream", None)
h = StreamHandler(stream) # 默许的handler
handlers = [h]
dfs = kwargs.pop("datefmt", None)
style = kwargs.pop("style", '%')
fs = kwargs.pop("format", _STYLES[style][1])
fmt = Formatter(fs, dfs, style) # 生成formatter
for h in handlers:
if h.formatter is None:
h.setFormatter(fmt)
root.addHandler(h) # 设置root的handler
level = kwargs.pop("level", None)
if level is not None:
root.setLevel(level) # 设置日志级别
可以看到,日志的配置主要包括下面几项:
level 日志级别
format 信息格式化模版
filename 输入到文件
datefmt %Y-%m-%d %H:%M:%S,uuu 时间的格式模版
style [ % , { ,$] 格式样板
演示代码输入中,可以看到debug日志没有显示,是由于 debug < info :
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
记载器对象 Logger查看Logger之前,先看logger对象的管理类Manager
_loggerClass = Logger
class Manager(object):
def __init__(self, rootnode):
self.root = rootnode
self.disable = 0
self.loggerDict = {} # 一切日志记载对象的字典
...
def getLogger(self, name):
rv = None
if name in self.loggerDict:
rv = self.loggerDict[name] # 获取曾经创立过的同名logger
...
else:
rv = (self.loggerClass or _loggerClass)(name) # 创立新的logger
rv.manager = self
self.loggerDict[name] = rv
...
return rv
日志过滤器
class Filterer(object):
def __init__(self):
self.filters = []
def addFilter(self, filter):
self.filters.append(filter)
def removeFilter(self, filter):
self.filters.remove(filter)
def filter(self, record):
rv = True
for f in self.filters: # 过滤日志
if hasattr(f, 'filter'):
result = f.filter(record)
else:
(责任编辑:admin)