如何在运行时根据事件类型向stdout输出不同格式日志?
实现运行时动态切换日志格式的方案
核心思路
通过给日志记录添加自定义标记属性,配合自定义Formatter根据该属性动态选择输出格式;同时在自定义Logger类中封装专门的安全日志方法,自动给对应日志打上标记,实现调用时的格式切换。
代码实现
1. 自定义动态格式处理器
import logging from datetime import datetime class DynamicFormatter(logging.Formatter): def format(self, record): # 统一格式化日志时间 log_datetime = datetime.fromtimestamp(record.created).strftime("%Y-%m-%d %H:%M:%S") # 根据标记选择输出格式 if hasattr(record, "is_security") and record.is_security: return f"SEC EVENT,{record.levelname}, {log_datetime}, {record.getMessage()}" else: return f"{record.levelname}, {log_datetime}, {record.getMessage()}"
2. 自定义Logger子类
class CustomLogClass(logging.Logger): def __init__(self, logger_name): super().__init__(logger_name) # 绑定stdout处理器和动态格式器 stdout_handler = logging.StreamHandler() stdout_handler.setFormatter(DynamicFormatter()) self.addHandler(stdout_handler) # 设置默认日志级别 self.setLevel(logging.INFO) # 封装安全日志的info级别方法 def sec_info(self, msg, *args, **kwargs): if self.isEnabledFor(logging.INFO): # 创建日志记录并添加安全标记 record = self.makeRecord( self.name, logging.INFO, "", 0, msg, args, None ) record.is_security = True self.handle(record) # 同理可扩展其他安全日志级别 def sec_warning(self, msg, *args, **kwargs): if self.isEnabledFor(logging.WARNING): record = self.makeRecord( self.name, logging.WARNING, "", 0, msg, args, None ) record.is_security = True self.handle(record)
使用示例
log = CustomLogClass("app_log") # 常规日志输出 log.info("系统模块初始化完成") # 输出样例:INFO, 2024-05-20 15:40:22, 系统模块初始化完成 # 安全事件日志输出 log.sec_info("用户admin登录认证成功") # 输出样例:SEC EVENT,INFO, 2024-05-20 15:40:30, 用户admin登录认证成功 log.sec_warning("用户guest连续3次认证失败") # 输出样例:SEC EVENT,WARNING, 2024-05-20 15:40:45, 用户guest连续3次认证失败
方案说明
- 完全基于Python标准
logging模块扩展,无额外依赖,兼容性强 - 自定义Formatter通过检查日志记录的标记属性,实现运行时动态格式切换
- 封装的
sec_*方法调用方式和常规日志方法一致,降低使用成本
内容的提问来源于stack exchange,提问作者abak1802
相关产品推荐
相关产品推荐

