如何用python-json-logger实现指定嵌套结构的JSON日志格式化
python-json-logger 自定义嵌套Body字段解决方案
完整可运行代码
import logging from pythonjsonlogger import jsonlogger from datetime import datetime logger = logging.getLogger() # 清理已有handler避免重复输出日志 if logger.handlers: logger.handlers.clear() logHandler = logging.StreamHandler() class CustomJsonFormatter(jsonlogger.JsonFormatter): def add_fields(self, log_record, record, message_dict): super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict) # 生成DateTime字段 if not log_record.get('DateTime'): now = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ') log_record['DateTime'] = now # 生成Level字段 log_record['Level'] = record.levelname # 构造嵌套Body结构 log_record['Body'] = { "text": log_record.pop('message'), "SensorID": str(log_record.pop('sensor_id')) } # 移除不需要的顶层字段 log_record.pop('level', None) formatter = CustomJsonFormatter('%(DateTime)s %(Level)s') logHandler.setFormatter(formatter) logger.addHandler(logHandler) logger.setLevel(logging.INFO) # 直接传递结构化参数,不需要手动拼接JSON字符串 logger.info("the log message", extra={"sensor_id": 1})
运行后输出的JSON格式和你要求的完全一致。
核心修改说明
- 补充了缺失的
logging导入,修正了datetime的导入路径 - 不再手动拼接JSON格式的body字符串,直接通过extra传递结构化参数,避免生成非法的JSON转义内容,你之前输出的body是字符串而非嵌套对象就是手动拼接字符串导致的
- 在自定义格式化方法中手动构造
Body嵌套结构,通过pop方法把原本在顶层的message、sensor_id移动到Body内部,同时删除顶层多余字段 - 统一处理字段大小写,和目标输出格式保持一致
动态参数适配(可选)
如果需要支持向Body中传入多个动态字段,可以修改Body构造逻辑,自动把所有extra参数合并到Body中:
# 提取所有自定义extra参数 extra_params = {} for key in list(log_record.keys()): if key not in ["DateTime", "Level", "message", "level"]: extra_params[key] = str(log_record.pop(key)) # 构造Body log_record["Body"] = { "text": log_record.pop("message"), **extra_params }
内容的提问来源于stack exchange,提问作者Shmuel
相关产品推荐
相关产品推荐

