日志改造"/>
logging日志改造
目录
- 一:需求
- 二:实现方式
- 三:存在的问题
- 3.1: 问题描述
- 3.2: 源码分析
- 3.3: 解决方案
- 四:相关链接
一:需求
- 需求:将自定义的参数,放在日志的指定格式中。
二:实现方式
- 例如:让debug, info,warning,error函数都允许传递一个trace_id, 并将这个trace_id输出到我们自定义日志指定的格式中。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2023/10/19 10:08 # @Author : shanwen.ren import logging import inspect import logging.configself_logger = logging.getLogger("debug")class Logger(logging.Logger):@staticmethoddef check_trace_id(kwargs):"""kwargs mush has trace_id and trace_id value type mush is str."""trace_id = str(kwargs.get("trace_id", ""))if "extra" not in kwargs:extra = {"trace_id": trace_id}else:assert isinstance(kwargs["extra"], dict)extra = kwargs["extra"]extra.update({"trace_id": trace_id})if "trace_id" in kwargs.keys():kwargs.pop("trace_id")return extra, kwargsdef debug(self, msg, *args, **kwargs):extra, kwargs = self.check_trace_id(kwargs)self_logger.debug(msg, *args, extra=extra, **kwargs)def info(self, msg, *args, **kwargs):extra, kwargs = self.check_trace_id(kwargs)self_logger.info(msg, *args, extra=extra, **kwargs)def warning(self, msg, *args, **kwargs):extra, kwargs = self.check_trace_id(kwargs)self_logger.warning(msg, *args, extra=extra, **kwargs)def error(self, msg, *args, **kwargs):extra, kwargs = self.check_trace_id(kwargs)self_logger.error(msg, *args, extra=extra, **kwargs)logger = Logger()def init_log(log_path, log_name, log_level="DEBUG"):log_level = log_level.upper()LOG_PATH_DEBUG = "%s/%s.log" % (log_path, log_name)LOG_FILE_BACKUP_COUNT = 10log_conf = {"version": 1,"formatters": {"format1": {"format": '|%(asctime)s.%(msecs)03d|%(levelname)s|%(trace_id)s|%(thread)d|%(filename)s %(lineno)d|%(message)s',"datefmt": '%Y-%m-%d %H:%M:%S',},},"handlers": {"handler": {"class": "logging.handlers.TimedRotatingFileHandler","level": log_level,"formatter": "format1","when": "midnight","backupCount": LOG_FILE_BACKUP_COUNT,"filename": LOG_PATH_DEBUG},},"loggers": {"debug": {"handlers": ["handler"],"level": log_level},}}logging.config.dictConfig(log_conf)def close_log():logging.shutdown()
三:存在的问题
3.1: 问题描述
- 上面代码中由于本质是使用的self_logger对象, 因此filename和lineno都会定位到我们自定义的Logger对象的debug, info,warning,error方法中, 无法真正的定位到真实代码所在地。
3.2: 源码分析
- 调用warning后会调用_log方法。
- findCaller会去取调用位置。
- 底层使用f_back获取上层调用, 返回上层调用的行号lno等信息。
- makeRecord最终作用于日志格式中。
3.3: 解决方案
- 基于源码分析, 发现底层用的inspect.currentframe().f_back,返回的上层调用者, 因此产生一个思路:废弃日志格式中的文件名和行号, 改成自己传递N-任意层调用的位置和行号。
- 代码调整:
- 改为自定义名称原因:
四:相关链接
- 官方文档:.html
更多推荐
logging日志改造
发布评论