Logback自定义JSON日志:解决SpringBoot下字符串与JSON混合问题
迁移SpringBoot后日志格式统一方案
一、解决message字段混合字符串与嵌套JSON问题
核心思路是把业务数据从message字段剥离,作为独立的结构化JSON字段存储,不要通过toString()把JSON塞进message里:
- 调整日志输出代码:
不要将MyLogObject转成字符串输出,而是作为日志参数传递:// 错误写法:message里会是JSON字符串 logger.info(myLogObject.toString()); // 正确写法:message是纯文本描述,数据作为参数 logger.info("用户下单操作", myLogObject); - 配置Logstash编码器:
在LoggingEventCompositeJsonEncoder中添加ArgumentsJsonProvider,它会自动将日志参数序列化为独立的JSON字段,同时保留message字段为纯文本:
这样message字段只会是“用户下单操作”这类纯文本,业务数据会放在<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <timestamp fieldName="timestamp"/> <level fieldName="level"/> <threadName fieldName="thread"/> <!-- 纯文本消息,仅存放日志描述 --> <message fieldName="message"/> <!-- 将日志参数序列化为args字段,自动解析MyLogObject的属性 --> <arguments fieldName="args"/> <!-- 统一处理异常堆栈为JSON数组 --> <stackTrace fieldName="stack_trace"> <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> <maxDepthPerThrowable>30</maxDepthPerThrowable> <rootCauseFirst>true</rootCauseFirst> </throwableConverter> </stackTrace> <loggerName fieldName="logger"/> </providers> </encoder>args字段里作为结构化JSON,彻底避免混合问题。
二、关于MyLogObject的取舍
不用完全舍弃,只需调整使用方式:
- 保留
MyLogObject作为日志数据的封装类,但日志输出时不要调用它的toString()方法,而是作为参数传递给日志框架,让Logstash编码器自动序列化。 - 如果之前重写
toString()是为了在非JSON环境下查看数据,可以保留该方法,但仅用于调试场景,不要用于正式日志输出。 - 若
MyLogObject没有额外业务逻辑,也可以替换成普通POJO,只要有标准getter方法,Logstash编码器就能正常解析。
三、统一Spring框架日志与应用日志格式
只需让Spring相关日志使用和应用日志相同的JSON appender即可:
- 定义通用JSON Appender:
将之前配置的JSON编码器封装成一个可复用的appender:<appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <!-- 这里复用上面的providers配置 --> </encoder> </appender> - 给Spring日志指定该Appender:
为Spring核心包的logger配置相同的appender,并关闭日志传递(additivity="false")避免重复输出:<logger name="org.springframework" level="INFO" additivity="false"> <appender-ref ref="JSON_CONSOLE"/> </logger> <logger name="org.springframework.web" level="DEBUG" additivity="false"> <appender-ref ref="JSON_CONSOLE"/> </logger> - 根Logger统一配置:
确保根Logger也使用该JSON appender,覆盖所有未单独配置的日志:
这样Spring框架的日志(比如启动日志、请求日志)和应用业务日志都会统一成标准JSON格式,异常堆栈也会被自动结构化处理。<root level="INFO"> <appender-ref ref="JSON_CONSOLE"/> </root>
内容的提问来源于stack exchange,提问作者dpcllalala
相关产品推荐
相关产品推荐

