当前位置:网站首页>封装logging模块
封装logging模块
2022-04-23 14:02:00 【沉觞流年】
封装logging模块
上篇文章,简要介绍了 Python中的logging日志模块
简单封装
logging日志功能,可以将其封装成一个独立的模块,这样,在需要使用到日志功能的地方,导入这个模块即可以使用
my_logger.py
import logging
class LoggerHandler():
# 初始化 Logger
def __init__(self,
name='root',
logger_level= 'DEBUG',
file=None,
logger_format = '%(asctime)s-%(message)s'
# logger_format = '%(asctime)s-%(filename)s-%(lineno)d-%(message)s'
):
# 1、初始化logger收集器
logger = logging.getLogger(name)
# 2、设置日志收集器level级别
logger.setLevel(logger_level)
# 5、初始化 handler 格式
fmt = logging.Formatter(logger_format)
# 3、初始化日志处理器
# 如果传递了文件,就会输出到file文件中
if file:
file_handler = logging.FileHandler(file)
# 4、设置 file_handler 级别
file_handler.setLevel(logger_level)
# 6、设置handler格式
file_handler.setFormatter(fmt)
# 7、添加handler
logger.addHandler(file_handler)
# 默认都输出到控制台
stream_handler = logging.StreamHandler()
# 4、设置 stream_handler 级别
stream_handler.setLevel(logger_level)
# 6、设置handler格式
stream_handler.setFormatter(fmt)
# 7、添加handler
logger.addHandler(stream_handler)
# 设置成实例属性
self.logger = logger
# 返回日志信息
def debug(self,msg):
return self.logger.debug(msg)
def info(self,msg):
return self.logger.info(msg)
def warning(self,msg):
return self.logger.warning(msg)
def error(self,msg):
return self.logger.error(msg)
def critical(self,msg):
return self.logger.critical(msg)
这样,需要用到日志的时候,通过导入 my_logger
模块,使用 LoggerHandler
类里的 debug
和info
函数即可
这种封装方式,相当于重写了一个日志模块的功能
然而,如果将init
里的内容,换成logger_format = '%(asctime)s-%(filename)s-%(lineno)d-%(message)s'
这种封装,会出现一些小问题,行号和文件会显示错误
新建立一个 test.py
文件
test.py
import my_logger
if __name__ == '__main__':
logger = my_logger.LoggerHandler()
logger.info('hello world!')
执行这个文件,打印的内容为:2021-08-29 21:12:25,462-my_logger.py-53-hello world!
,这里的行号为 53
,日志里的文件名称为my_logger.py
也就是说,打印的文件和行号,是封装的内容里的,而不是我们执行的 test.py
文件里的内容
这个问题出在了 1、初始化logger收集器 logger = logging.getLogger(name)
这一步
test.py
文件里调用的是LoggerHandler
类的内容,logger
初始化的时候,就已经把日志信息保存起来了,所以,调用 info
函数的时候, return self.logger.info(msg)
返回的是LoggerHandler
类的info
函数 logger
的内容
继承 logging 模块进行封装
如果要解决这个问题,就不要像上面一样,重写日志模块的功能,而是要采用继承 logging 模块的方式,去封装日志模块
logging 模块
中有一个 Logger 类
,所以,在定义类的时候,需要继承这个 Logger 类
按住Ctrl,点击 logger = logging.getLogger(name)
中的 getLogger
,查看getLogger
方法的内容
def getLogger(name=None):
""" Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """
if name:
return Logger.manager.getLogger(name)
else:
return root
备注的内容为:返回具有指定名称的日志收集器,并在必要时创建它。如果没有指定名称,则返回根日志收集器。
从备注中可以得知,这个函数的作用,是返回logger收集器。
按住Ctrl,点击 manager.getLogger(name)
中的 getLogger
,
里面有这样一行代码: rv = (self.loggerClass or _loggerClass)(name)
,
这行代码的作用,其实就是实例化一个类(日志Logger的类)。
所以,上面的问题,1、初始化logger收集器 logger = logging.getLogger(name)
这一步,实例化的是LoggerHandler
类,在 test.py
文件里打印的日志内容,返回的是LoggerHandler
类的info
函数 logger
的行号和文件名称
而采用继承的方式,继承logging 模块
中 Logger 类
,就不会出现这个问题了,因为调用的是logging 模块
中 Logger 类
,打印的日志内容,调用的的是logging 模块
的info
函数了,返回的行号和文件名称,就是正确的
所以,就不需要1、初始化logger收集器 logger = logging.getLogger(name)
这一步了,直接super().__init__(name)
继承logging 模块
中 Logger 类
,将相应的内容,替换成 self
就行了,也不需要再自定义 debug
、info
这些方法了
my_logger2.py
import logging
class LoggerHandler(logging.Logger):
# 初始化 Logger
def __init__(self,
name='root',
logger_level= 'DEBUG',
file=None,
logger_format = " [%(asctime)s] %(levelname)s %(filename)s [ line:%(lineno)d ] %(message)s"
):
# 1、设置logger收集器,继承logging.Logger
super().__init__(name)
# 2、设置日志收集器level级别
self.setLevel(logger_level)
# 5、设置 handler 格式
fmt = logging.Formatter(logger_format)
# 3、设置日志处理器
# 如果传递了文件,就会输出到file文件中
if file:
file_handler = logging.FileHandler(file)
# 4、设置 file_handler 级别
file_handler.setLevel(logger_level)
# 6、设置handler格式
file_handler.setFormatter(fmt)
# 7、添加handler
self.addHandler(file_handler)
# 默认都输出到控制台
stream_handler = logging.StreamHandler()
# 4、设置 stream_handler 级别
stream_handler.setLevel(logger_level)
# 6、设置handler格式
stream_handler.setFormatter(fmt)
# 7、添加handler
self.addHandler(stream_handler)
test.py
import my_logger2
if __name__ == '__main__':
logger = my_logger2.LoggerHandler()
logger.info('hello world!')
执行 test.py
文件 ,可以发现,打印的日志信息为:
[2021-08-29 22:47:33,124] INFO mytest.py [ line:5 ] hello world!
,这个就正确了
如果还想在日志中看到对应模块中的函数名称,可以再加上 funcName
即:logger_format = " [%(asctime)s] %(levelname)s [%(filename)s %(funcName)s] [ line:%(lineno)d ] %(message)s"
版权声明
本文为[沉觞流年]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_44614026/article/details/119985629
边栏推荐
猜你喜欢
随机推荐
Scientists say Australian plan to cull up to 10,000 wild horses doesn’t go far enough
_模_板_
Oracle alarm log alert Chinese trace and trace files
Un modèle universel pour la construction d'un modèle d'apprentissage scikit
nodejs通过require读取本地json文件出现Unexpected token / in JSON at position
Spark入门基本操作
json反序列化匿名数组/对象
Postman reference summary
基于ibeacons三点定位(微信小程序)
微信小程序获取登录用户信息、openid和access_token
程序编译调试学习记录
FBS(fman build system)打包
As a junior college student, I studied hard in closed doors for 56 days, won Ali offer with tears, five rounds of interviews and six hours of soul torture
Logging模块
多重继承虚基类习题
Pytorch 经典卷积神经网络 LeNet
redis如何解决缓存雪崩、缓存击穿和缓存穿透问题
PySide2
Qt Designer怎样加入资源文件
Analysis and understanding of atomicintegerarray source code