Spring Boot下如何为同一包配置多个日志级别并分别输出到独立文件
同包下多日志级别独立文件输出配置方案
实现思路
- 不需要拆分包结构,通过日志标记(Marker) 区分同一包下的不同业务场景日志
- 为不同场景配置独立的日志输出器(Appender),分别绑定对应级别和标记过滤规则
- 最终实现Scheduler类日志输出debug级到专属文件、客户端请求类日志输出info级到专属文件,互不干扰
代码侧标记配置
业务代码中给不同场景的日志添加专属Marker标识,示例如下:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.MarkerFactory; public class ExampleService { private static final Logger logger = LoggerFactory.getLogger(ExampleService.class); // 定义两个专属标记区分业务场景 private static final Marker SCHEDULER_MARKER = MarkerFactory.getMarker("SCHEDULER"); private static final Marker REQUEST_MARKER = MarkerFactory.getMarker("CLIENT_REQUEST"); // Scheduler调度方法 public void runScheduledTask(Object params) { // 带SCHEDULER标记的debug日志 logger.debug(SCHEDULER_MARKER, "调度任务执行开始,参数:{}", params); // 该场景下其他debug日志都会进入调度专属日志文件 } // 客户端请求处理方法 public void handleClientRequest(long costTime) { // 带CLIENT_REQUEST标记的info日志 logger.info(REQUEST_MARKER, "客户端请求处理完成,响应耗时:{}ms", costTime); } }
日志框架配置(以Logback为例)
在logback.xml中配置两个独立的输出器,分别过滤对应标记和日志级别:
<configuration scan="true" scanPeriod="60 seconds"> <!-- 控制台输出器(可选) --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 调度任务debug日志专属输出器 --> <appender name="SCHEDULER_DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/scheduler-debug.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>logs/scheduler-debug.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!-- 只接收DEBUG及以上级别、且带SCHEDULER标记的日志 --> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator> <expression>marker == null || !marker.getName().equals("SCHEDULER") || level < DEBUG</expression> </evaluator> <onMismatch>DENY</onMismatch> <onMatch>ACCEPT</onMatch> </filter> </appender> <!-- 客户端请求info日志专属输出器 --> <appender name="REQUEST_INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/client-request-info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>logs/client-request-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!-- 只接收INFO及以上级别、且带CLIENT_REQUEST标记的日志 --> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator> <expression>marker == null || !marker.getName().equals("CLIENT_REQUEST") || level < INFO</expression> </evaluator> <onMismatch>DENY</onMismatch> <onMatch>ACCEPT</onMatch> </filter> </appender> <!-- 绑定com.example包的日志配置 --> <logger name="com.example" level="debug" additivity="false"> <appender-ref ref="SCHEDULER_DEBUG_FILE"/> <appender-ref ref="REQUEST_INFO_FILE"/> </logger> <!-- 根日志默认配置 --> <root level="info"> <appender-ref ref="CONSOLE"/> </root> </configuration>
补充说明
- 上述配置中用到的表达式过滤器需要引入janino依赖,Maven配置如下:
<dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> <version>3.1.9</version> </dependency>
- 如果你不想使用Marker,也可以直接给不同场景的Logger单独命名,比如Scheduler相关代码的Logger用
LoggerFactory.getLogger("com.example.scheduler"),请求相关用LoggerFactory.getLogger("com.example.request"),之后直接配置两个不同name的logger分别设置级别和绑定对应Appender即可,不需要额外配置过滤器 - 配置中的
additivity设置为false是为了避免对应日志同时输出到根日志的其他输出器中,如果你需要同时在控制台或者其他公共日志文件看到这些日志,可以改为true
内容的提问来源于stack exchange,提问作者Deepak Murugesan
相关产品推荐
相关产品推荐

