python logging 自定义formatter
问题
自定义log formatter, 如添加request_id
方法
- 定义Logging Filter
class ServerFilter(logging.Filter): ... def filter(self, record): record.request_id = xxx return True handler.addFilter(ServerFilter()) handler.setFormatter(ServerFormatter(f"%(asctime)s - {hostname} - [%(levelname)s] - %(filename)s:%(lineno)s: %(name)s: |%(request_id)s| %(message)s")) - 定义logging Formater
class ServerFormatter(logging.Formatter): ... def format(self, record): record.request_id = xxx return super(ServerFormatter, self).format(record) handler.setFormatter(ServerFormatter(f"%(asctime)s - {hostname} - [%(levelname)s] - %(filename)s:%(lineno)s: %(name)s: |%(request_id)s| %(message)s")) - 深度自定义Formatter
class JsonFormatter(logging.Formatter): def __init__(self, fmt=None, datefmt=None, style='%', mid="mid_unknown", event_id=None): super().__init__(fmt, datefmt, style) self.mid = mid self.event_id = event_id def format(self, record): # 将 record.message 转换为 JSON 字符串 if isinstance(record.msg, dict): record.msg = json.dumps(record.msg, ensure_ascii=False) # 添加 mid 到 record record.mid = self.mid if 'event_id' in record.__dict__: record.event_id = record.__dict__['event_id'] else: record.event_id = self.event_id # 创建日志字典 log_dict = { "time_stamp": self.formatTime(record, self.datefmt), "mid": record.mid, "event_id": record.event_id, "level": record.levelname, "message": record.msg, "msg_type": "json" if isinstance(record.msg, str) and record.msg.startswith('{') else "text" } # print(f"================={record}") # 将日志字典转换为 JSON 字符串 return json.dumps(log_dict, ensure_ascii=False) class ElapsedLog(logging.Logger): """ 日志记录 """ def __init__(self, name=None, verbose=False, file_handler=True, mid="mid_unknown", event_id=None): """ verbose==False, 表示INFO level verbose==True, 表示DEBUG level file_handler=False, 表示不写入到文件 file_handler=True, 表示写入到文件 """ super().__init__(name) super().setLevel(logging.DEBUG if verbose else logging.INFO) # 设置日志打印格式 self.formatter = JsonFormatter(mid=mid, event_id=event_id) if file_handler: if not os.path.exists(log_dir): os.makedirs(log_dir) file_handler = handlers.TimedRotatingFileHandler( filename=log_path, when=when, backupCount=backupCount, encoding="utf-8") file_handler.suffix = "%Y%m%d-%H-%M-%S.log" file_handler.extMatch = re.compile(r"^\d{8}-\d{2}-\d{2}-\d{2}.log$") file_handler.setFormatter(self.formatter) self.addHandler(file_handler) stream_handler = logging.StreamHandler() stream_handler.setFormatter(self.formatter) self.addHandler(stream_handler) def set_mid(self, mid): """设置 mid""" self.formatter.mid = mid def set_event_id(self, event_id): """设置 event id""" self.formatter.event_id = event_id
# 创建日志记录器实例
logger = ElapsedLog(file_handler=True)
if __name__ == '__main__':
# 设置 mid
logger.set_mid('123456789')
logger.set_event_id('ElapsedEvent')
a = {"x": True}
问题
- 如何对自定义变量赋值?比如上述record.request_id = xxx, xxx的值如何获取?
- 方式1: 使用app的request上下文,自动获取request_id并赋值
- 方式2: 在打印日志的时候,Formatter 手动赋值self.formatter.request_id = "xxxx"
- 方式3: 在打印日志的时候,手动赋值log.$filter.request_id = "xxxx" ,针对sanic可以在@bp.on_request阶段设置log.filter.request_id
- 方式4: 打印日志的时候,手动赋值extra, log.info("", extra=extra);extra["request_id"] = "xxx"

浙公网安备 33010602011771号