如何在指定日志级别禁用Spring Sleuth?及解决引入Sleuth后的日志内容缺失问题
解决Spring Sleuth日志格式冲突的几种方案
我来给你梳理几个实际项目里验证过的可行方案,既能保留原有日志格式,又能按级别控制Sleuth的trace信息展示:
方案一:直接自定义Sleuth日志Pattern(最省心)
Spring Sleuth会默认覆盖日志输出格式,你可以直接修改它的pattern,加入原来的自定义前缀,同时用日志框架的条件判断控制不同级别下的显示内容。
如果用application.yml配置(适合简单场景):
spring: sleuth: log: pattern: "%d{yyyy-MM-dd HH:mm:ss.SSS} [(ID:%X{customId})(CUSTOMER ID:%X{customerId} TYPE:%X{type})] %if(%level >= INFO) [%X{traceId:-},%X{spanId:-},%X{sampled:-}] %level %pid --- [%t] %logger : %msg%n" logging: level: com.h.d.s.staticdata: DEBUG
这里的%X{customId}等变量对应你原来日志里的自定义信息,只要这些信息存在MDC中,日志框架就能自动读取。配置后:
- DEBUG级别:只显示你原来的
[(ID:xxx)(CUSTOMER ID:xxx TYPE:xxx)]前缀 - INFO及以上级别:同时显示原有前缀和Sleuth的
[traceId,spanId,sampled]信息
方案二:用Logback配置实现复杂自定义逻辑
如果你的原有日志前缀是通过自定义转换器实现的(不是存在MDC里),可以直接修改logback-spring.xml,用Logback的条件判断精准控制:
<configuration> <!-- 注册你原来的自定义前缀转换器 --> <conversionRule conversionWord="customPrefix" converterClass="com.yourpackage.CustomPrefixConverter"/> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} <!-- 核心逻辑:INFO及以上显示Sleuth信息,否则显示原有自定义前缀 --> %if(%level >= INFO) [%X{traceId:-},%X{spanId:-},%X{sampled:-}] %else %customPrefix %level %pid --- [%t] %logger : %msg%n </pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> <logger name="com.h.d.s.staticdata" level="DEBUG"/> </configuration>
同时关闭Sleuth自动修改日志的功能避免冲突:
spring: sleuth: log: enabled: false
方案三:通过AOP手动控制Trace信息添加(灵活性最高)
如果需要更灵活的控制(比如只在特定业务方法中添加Trace信息),可以用AOP切面实现:
- 先关闭Sleuth的日志自动增强:
spring: sleuth: log: enabled: false
- 编写AOP切面,只在INFO及以上级别的日志中添加Trace信息到MDC:
@Aspect @Component public class TraceLogAspect { @Autowired(required = false) private Tracer tracer; // 切点:匹配你需要监控的业务方法 @Around("execution(* com.h.d.s.staticdata..*.*(..))") public Object addTraceInfo(ProceedingJoinPoint joinPoint) throws Throwable { Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass()); if (tracer != null && logger.isInfoEnabled()) { Span currentSpan = tracer.currentSpan(); if (currentSpan != null) { MDC.put("traceId", currentSpan.context().traceId()); MDC.put("spanId", currentSpan.context().spanId()); MDC.put("sampled", String.valueOf(currentSpan.context().sampled())); } } try { return joinPoint.proceed(); } finally { // 清理MDC避免内存泄漏 MDC.remove("traceId"); MDC.remove("spanId"); MDC.remove("sampled"); } } }
- 最后在日志Pattern中配置,根据级别选择是否显示Trace信息:
logging: pattern: console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [(ID:%X{customId})(CUSTOMER ID:%X{customerId} TYPE:%X{type})] %if(%level >= INFO) [%X{traceId:-},%X{spanId:-},%X{sampled:-}] %level %pid --- [%t] %logger : %msg%n"
内容的提问来源于stack exchange,提问作者Amin Shahimian
相关产品推荐
相关产品推荐

