生产环境日志必须采用结构化JSON格式(如logstash-logback-encoder),含@timestamp、level、service、trace_id等必选字段,禁用%L/%l,ERROR需全堆栈,敏感信息须脱敏,强制UTF-8编码与%n换行。

Java 生产环境日志输出格式必须兼顾可读性、可解析性、安全性与排障效率,不能只图控制台看着顺眼。核心是统一结构、保留关键上下文、适配采集链路,同时规避敏感信息泄露和性能隐患。
统一结构化格式(推荐 JSON)
纯文本日志在 ELK / Loki 等平台中解析成本高、易出错。生产环境应强制使用结构化输出:
- 引入
logstash-logback-encoder依赖,配置LoggingEventCompositeJsonEncoder - 必含字段:时间戳(
@timestamp)、日志级别(level)、服务名(service)、TraceId(trace_id)、SpanId(span_id)、线程名(thread)、类/方法(logger_name、method)、原始消息(message)、异常堆栈(stack_trace) - MDC 中的业务字段(如
user_id、order_id)自动注入到 JSON,无需手动拼接
文本格式兜底方案(非结构化场景)
若暂未接入日志平台,或需保留控制台可读性,按以下规范约束文本格式:
-
INFO/WARN/ERROR 公共格式:
%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{trace_id:-}] [%thread] %-5level %C{1}.%M - %msg%n -
ERROR 单独增强:追加行号和完整异常(
%ex{full}),便于快速定位错误源头 -
禁止使用
%L(行号)或%l(全位置)作为常规输出——性能损耗大,且编译优化后可能不准 -
不打印堆栈到 INFO 日志;WARN 级别仅在必要时用
%ex{short},ERROR 才用%ex{full}
关键字段动态注入与脱敏
格式只是载体,内容质量决定排障效率:
立即学习“Java免费学习笔记(深入)”;
- 所有日志必须携带
trace_id,通过 MDC 自动注入(SkyWalking / Sleuth 可零代码支持;无组件时需 Filter + Interceptor 手动塞入) - 敏感字段(如身份证、手机号、token)必须在日志写入前脱敏,推荐在工具类或 AOP 中统一拦截处理,而非依赖格式模板
- 避免在日志中拼接 JSON 字符串(如
logger.info("req: " + JSON.toJSONString(req))),既影响性能,又破坏结构化
编码与换行强制约束
看似细节,却是线上日志乱码、截断、解析失败的高频原因:
-
encoder 必须显式声明
<charset>UTF-8</charset>,尤其在 Linux 容器中默认 locale 不一定为 UTF-8 -
每条日志末尾必须有
%n,缺失会导致多条日志合并成一行,Filebeat 采集时无法按行切分 - 禁用
ConsoleAppender,生产环境只允许RollingFileAppender或异步封装后的AsyncAppender


















