SpringBoot 2.3+
Java 1.8+
Slf4j
记录日志,每条打印的日志都会有不同的ID,不方便追踪当前请求日志记录,给当前请求添加唯一ID,
网上找到一些比较老的文章,说的是过滤器
和AOP
实现,
现在主流是啥方式啊,大佬们
方案1
https://tlog.yomahub.com/pages/eea781/
找到个开源的轻量级包,适用于小项目
方案2,根据回答zxdposter
的思路
1.TraceInterceptor拦截器
@Component
public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MDC.put("TID", UUID.randomUUID().toString());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
MDC.clear();
}
}
2.TraceInterceptor注册
@Configuration
public class TraceConfig implements WebMvcConfigurer {
@Autowired
private TraceInterceptor traceInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(traceInterceptor)
.addPathPatterns("/**")//指定该类拦截的url
.excludePathPatterns("/static/**");//过滤静态资源
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS", "HEAD")
.allowedHeaders("*")
.maxAge(3600);
}
}
3.application.properties 文件路径
logging.file.path=/home/logs/baba
4.logback-spring.xml
配置文件
<configuration scan="true" scanPeriod="10 seconds">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<springProperty scope="context" name="fileActive" source="spring.profiles.active"/>
<property name="LOG_PATH" value="${LOG_PATH:-.}"/>
<property name="CONSOLE_LOG_PATTERN" value="%X{TID}|--${CONSOLE_LOG_PATTERN}"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/info.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/info-%d{yyyyMMdd}.log.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>16MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>10</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -[%X{TID}]- [%thread] %-5level %logger{36} -%msg%n
</Pattern>
</layout>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<File>${LOG_PATH}/error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/error-%d{yyyyMMdd}.log.%i
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>16MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>10</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</appender>
<!-- hibernate日志输入 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="INFO"/>
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="INFO"/>
<logger name="org.hibernate.SQL" level="TRACE"/>
<root level="INFO">
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="CONSOLE" />
</root>
</configuration>
我的方案
我认为最好的方案是用拦截器 +
LogFormat
+MDC
。利用日志框架自身提供的特性解决问题。
第一步
首先配置日志格式,下面的格式是我从 springboot 中拷贝的,可以直接使用,之后增加一个
%X{REQUEST_ID}
标志占位。第二步
增加一个 http 请求拦截器,我用的是
spring boot 2.7
,实现方式是增加WebMvcConfigurer
类型的bean
,再实现addInterceptors
方法,增加自定义的HandlerInterceptor
类。第三步
实现自定义
HandlerInterceptor
类中的方法preHandle
。在每次请求前,生成一个唯一 ID,调用
MDC
的静态方法put
。示例(kotlin)