python logging模块 在多个模块中记录日志
一、
无论对 logging.getLogger('someLogger')
进行多少次调用,都会返回同一个 logger 对象的引用。不仅在同一个模块内如此,只要是在同一个 Python 解释器进程中,跨模块调用也是一样。同样是引用同一个对象,应用程序也可以在一个模块中定义和配置一个父 logger,而在另一个单独的模块中创建(但不配置)子 logger,对于子 logger 的所有调用都会传给父 logger。
参考链接:https://docs.python.org/zh-cn/3/howto/logging-cookbook.html
二、
问题:python 中封装日志 logging,为何打印行号固定在同一行?
答:打印的行号是调用 logger 对象的所在行,所以自己进行封装时,应该返回 logger 对象,再调用相应logger.info、logger.debug等方法。
参考链接:https://testerhome.com/topics/26827
三、代码示例:
#!/usr/bin/env python # coding:utf-8 import logging,time import pathlib from src.utils.config import Config def get_logger(log_path=None): # log_path是存放日志的路径,如果不存在这个logs文件夹,那么需要创建出来。 if not log_path: conf = Config() log_path = conf.log_path else: log_path = pathlib.Path(log_path) if not log_path.exists(): log_path.mkdir() logname = str(log_path.joinpath('%s.log'%time.strftime('%Y_%m_%d'))) logger = logging.getLogger() logger.setLevel(logging.DEBUG) # 日志输出格式 formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') # 创建一个FileHandler,存储日志文件 fh = logging.FileHandler(logname, encoding='utf-8') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) # 创建一个StreamHandler,用于输出到控制台 sh = logging.StreamHandler() sh.setLevel(logging.DEBUG) sh.setFormatter(formatter)
# 如果不判断是否为空,那么在多次调用函数get_logger函数后,会添加多个handler到logger.handlers中,导致出现日志重复输出问题。
# 参考链接:https://www.cnblogs.com/huang-yc/p/9209096.html if not logger.handlers: logger.addHandler(sh) logger.addHandler(fh) return logger if __name__ == '__main__': log_path = "./log" log = get_logger(log_path) log.info(u'基础信息') log.debug(u'调试信息') log.warning(u'警告信息') log.error(u'错误信息')
测试代码bconfig.py
#!/usr/bin/env python # coding:utf-8 if __name__ == "__main__": from log import get_logger log_path = '/root/AutotestV2/log' log = get_logger(log_path) log.info("run test")
运行测试代码bconfig.py结果如下:
可以看到打印出了log.info("run test")所在文件和行号。
[root@localhost utils]# python bconfig.py 2022-01-25 18:54:42,386 bconfig.py[line:9] INFO run test