SpringBoot MDC

2022-08-28 14:28:54

SpringBoot MDC

在程序中,日志一直是一个至关重要的部分,排查问题、统计数据…

解决问题

SpringBoot添加全局自定义日志链路信息。

1.过滤器,拦截指定请求,可取出参数、请求头等信息,可根据业务自定义添加进日志进程(MDC)

2.时间拦截器,根据注解进行拦截,向进程日志(MDC)中,注入方法执行时间。

3.具体业务,可自行向进程日志(MDC)中注入所需信息。

1.MDCFilter

请求过滤器,用于向MDC中添加请求头等信息。

/**
 * 拦截请求信息,添加到日志
 *
 * @author litong
 * @date 2020/7/23 10:46
 */@Component@Log4j2@Order(2)@AllArgsConstructorpublicclassMDCFilterextendsOncePerRequestFilter{private MDCLogProperties mdcLogProperties;@OverrideprotectedvoiddoFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException{try{
            MDC.put(mdcLogProperties.getHeaderSessionKey(),
                    request.getHeader(mdcLogProperties.getHeaderSessionKey()));
            MDC.put("url", request.getRequestURI());
            chain.doFilter(request, response);}finally{
            MDC.clear();}}}

2.ApiTimerLog

注解,用于标注需要打印方法执行时间的标识。

/**
 * 时间记录annotation
 * 标注需要记录时间消耗的方法
 *
 * @author litong
 * @date 2020/7/23 15:30
 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interfaceApiTimerLog{}

3.TimeAspect

时间切片

/**
 * @author litong
 * @date 2020/7/23 15:31
 */@Aspect@Component@Slf4jpublicclassTimeAspect{// 修正Timer注解的全局唯一限定符@Pointcut("@annotation(com.ltz.ltzg.common.log.annotation.ApiTimerLog)")privatevoidpointcut(){}// 按包注入//    @Around("execution(* com.ltz.ltzg.auth.controller.*.*(..))" +//            "|| execution(* com.ltz.ltzg.api.controller.*.*(..))")// 按注解注入@Around("pointcut()")public Objectaround(ProceedingJoinPoint joinPoint)throws Throwable{// 开始时间long start= System.currentTimeMillis();// 调用目标方法
        Object result= R.err(ErrorEnums.SHOW_FAIL);try{
            result= joinPoint.proceed();}catch(Throwable throwable){throw throwable;}finally{// 获取执行时间long end= System.currentTimeMillis();long time= end- start;
            MDC.put("executionTime", time+"");

            R result1=newR();try{
                result1=(R) result;}catch(Exception e){}
            MDC.put("errcode", result1.getCode()+"");
            log.info("Api-Link");}return result;}}

4.logback-local.xml

<?xml version="1.0" encoding="UTF-8"?><!--该日志将日志级别不同的log信息保存到不同的文件中 --><configuration><includeresource="org/springframework/boot/logging/logback/defaults.xml"/><includeresource="org/springframework/boot/logging/logback/console-appender.xml"/><includeresource="org/springframework/boot/logging/logback/file-appender.xml"/><springPropertyscope="context"name="springAppName"source="spring.application.name"/><!-- 日志在工程中的输出位置 --><propertyname="LOG_FILE"value="C:/data/logs/${springAppName}"/><!--<property name="LOG_FILE" value="/data/ltz/logs/${springAppName}" />--><!-- 控制台的日志输出样式 --><propertyname="CONSOLE_LOG_PATTERN"value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- })[%thread] [url=%X{url};ltz-token=%X{ltz-token};executionTime=%X{executionTime};errcode=%X{errcode}] {magenta} %clr(---){faint} %clr([%15.15t]){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><!-- 控制台输出 --><appendername="console"class="ch.qos.logback.core.ConsoleAppender"><filterclass="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><!-- 日志输出编码 --><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder></appender><!-- 文件输出 --><appendername="localfile"class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE}.json</file><rollingPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.%i.gz</fileNamePattern><maxFileSize>${LOG_FILE_MAX_SIZE:-1000MB}</maxFileSize><maxHistory>${LOG_FILE_MAX_HISTORY:-7}</maxHistory></rollingPolicy><filterclass="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [url=%X{url};ltz-token=%X{ltz-token};executionTime=%X{executionTime};errcode=%X{errcode}]  %-5level %logger{35} - %msg%n</pattern></encoder></appender><!-- sql文件输出 --><appendername="sqlfile"class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_FILE}.sqllog</file><rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.sqlLog</fileNamePattern><maxHistory>3</maxHistory></rollingPolicy><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern></encoder></appender><!-- 日志输出级别 --><rootlevel="INFO"><appender-refref="console"/><appender-refref="localfile"/></root><loggername="dao"level="debug"additivity="false"><appender-refref="sqlfile"/></logger></configuration>

5.日志模板说明

MDC中添加的key,需要在日志模板中,用%X{url}的方式,打印。

使用案例

/**
 * @author litong
 * @date 2020/6/1 17:10
 */@RequestMapping("/test")@RestControllerpublicclassTestController{@ApiTimerLog@GetMapping("/a")public Ra(){return R.ok("a");}}

日志输出

2020-07-27 13:41:16.960  INFO 24052[http-nio-18989-exec-5] [url=/test/a;ltz-token=123;executionTime=0;errcode=1000]{magenta} --- [io-18989-exec-5] Api-Link
  • 作者:LitongZero
  • 原文链接:https://litongzero.blog.csdn.net/article/details/107610129
    更新时间:2022-08-28 14:28:54