Spring Boot 2中Logback LevelRemappingAppender的替代方案是什么?
Spring Boot 2.x 替代 LevelRemappingAppender 的方案
确实,org.springframework.boot.logging.logback.LevelRemappingAppender 在 Spring Boot 2.x 中被移除了,官方迁移指南也没专门提及这个点。不过我们可以用 Logback 原生的扩展能力来实现完全相同的日志级别重映射/日志转发功能,下面给你两种实用的方案:
方案一:自定义 Logback Appender(最贴近原组件逻辑)
这个方法直接模仿原 LevelRemappingAppender 的工作方式:接收指定来源的日志事件,可选修改级别后转发到目标 Logger。
1. 实现自定义 Appender
创建一个继承自 Logback UnsynchronizedAppenderBase 的类:
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.UnsynchronizedAppenderBase; import org.slf4j.LoggerFactory; public class LevelRemappingAppender extends UnsynchronizedAppenderBase<ILoggingEvent> { // 目标 Logger 的名称 private String destinationLogger; // 可选:要重映射到的目标级别(不设置则保留原级别) private Level targetLevel; @Override protected void append(ILoggingEvent event) { // 获取目标 Logger Logger targetLogger = (Logger) LoggerFactory.getLogger(destinationLogger); // 如果配置了目标级别,修改日志事件的级别 if (targetLevel != null) { event.setLevel(targetLevel); } // 将日志事件转发给目标 Logger targetLogger.log( event.getLoggerName(), event.getLevel(), event.getMessage(), event.getThrowableProxy() ); } // Logback 配置会调用这些 setter 方法注入参数 public void setDestinationLogger(String destinationLogger) { this.destinationLogger = destinationLogger; } public void setTargetLevel(Level targetLevel) { this.targetLevel = targetLevel; } }
2. 在 Logback 配置中使用
在你的 logback-spring.xml(或 logback.xml)里配置这个自定义 Appender,并关联到需要重映射的源 Logger:
<!-- 定义自定义重映射 Appender --> <appender name="DEBUG_LEVEL_REMAPPER" class="com.your.package.LevelRemappingAppender"> <!-- 指定要转发到的目标 Logger --> <destinationLogger>org.springframework.boot</destinationLogger> <!-- 可选:将所有经过此 Appender 的日志级别改为 DEBUG --> <!-- <targetLevel>DEBUG</targetLevel> --> </appender> <!-- 配置源 Logger,将其日志发送到重映射 Appender --> <logger name="your.source.logger.name" additivity="false"> <appender-ref ref="DEBUG_LEVEL_REMAPPER" /> </logger>
注意:设置
additivity="false"可以避免源 Logger 的日志被重复输出到根 Logger 的 Appender 中。
方案二:使用 TurboFilter(全局级别拦截)
如果你需要全局范围内对符合规则的日志进行重映射,TurboFilter 会更合适——它在日志事件生成的早期阶段就可以拦截并修改/转发日志。
1. 实现自定义 TurboFilter
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.turbo.TurboFilter; import ch.qos.logback.core.spi.FilterReply; import org.slf4j.Marker; public class LevelRemappingTurboFilter extends TurboFilter { // 源 Logger 的匹配正则(比如匹配某个包下的所有 Logger) private String sourceLoggerPattern; // 目标 Logger 名称 private String destinationLogger; // 可选:目标级别 private Level targetLevel; @Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) { // 匹配源 Logger if (logger.getName().matches(sourceLoggerPattern)) { Logger targetLogger = (Logger) LoggerFactory.getLogger(destinationLogger); // 转发日志到目标 Logger,可选修改级别 targetLogger.log( logger.getName(), targetLevel != null ? targetLevel : level, format, params, t ); // 返回 DENY,阻止原 Logger 继续处理此事件 return FilterReply.DENY; } // 不匹配则放行 return FilterReply.NEUTRAL; } // Logback 配置注入参数的 setter public void setSourceLoggerPattern(String sourceLoggerPattern) { this.sourceLoggerPattern = sourceLoggerPattern; } public void setDestinationLogger(String destinationLogger) { this.destinationLogger = destinationLogger; } public void setTargetLevel(Level targetLevel) { this.targetLevel = targetLevel; } }
2. 配置 TurboFilter
在 Logback 配置中添加这个 TurboFilter:
<turboFilter class="com.your.package.LevelRemappingTurboFilter"> <!-- 匹配所有 com.your.source 包下的 Logger --> <sourceLoggerPattern>com.your.source.*</sourceLoggerPattern> <!-- 转发到目标 Logger --> <destinationLogger>org.springframework.boot</destinationLogger> <!-- 可选:将日志级别重映射为 INFO --> <!-- <targetLevel>INFO</targetLevel> --> </turboFilter>
选择建议
- 如果只是针对单个/少数特定 Logger 做重映射,方案一更直观,贴近原组件的使用方式。
- 如果需要对一批符合规则的 Logger 做全局重映射,方案二的扩展性更好,不需要逐个配置 Logger。
内容的提问来源于stack exchange,提问作者Fletch
相关产品推荐
相关产品推荐

