SpringBoot MDC

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

解决问题

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

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

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

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

1.MDCFilter

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
java复制代码
/**
* 拦截请求信息,添加到日志
*
* @author litong
* @date 2020/7/23 10:46
*/
@Component
@Log4j2
@Order(2)
@AllArgsConstructor
public class MDCFilter extends OncePerRequestFilter {

private MDCLogProperties mdcLogProperties;

@Override
protected void doFilterInternal(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

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

1
2
3
4
5
6
7
8
9
10
11
java复制代码/**
* 时间记录annotation
* 标注需要记录时间消耗的方法
*
* @author litong
* @date 2020/7/23 15:30
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiTimerLog {
}

3.TimeAspect

时间切片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
java复制代码/**
* @author litong
* @date 2020/7/23 15:31
*/
@Aspect
@Component
@Slf4j
public class TimeAspect {

// 修正Timer注解的全局唯一限定符
@Pointcut("@annotation(com.ltz.ltzg.common.log.annotation.ApiTimerLog)")
private void pointcut() {
}

// 按包注入
// @Around("execution(* com.ltz.ltzg.auth.controller.*.*(..))" +
// "|| execution(* com.ltz.ltzg.api.controller.*.*(..))")

// 按注解注入
@Around("pointcut()")
public Object around(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 = new R();
try {
result1 = (R) result;
} catch (Exception e) {
}
MDC.put("errcode", result1.getCode() + "");
log.info("Api-Link");
}

return result;
}
}

4.logback-local.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
xml复制代码<?xml version="1.0" encoding="UTF-8"?>
<!--该日志将日志级别不同的log信息保存到不同的文件中 -->
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml"/>

<springProperty scope="context" name="springAppName"
source="spring.application.name" />

<!-- 日志在工程中的输出位置 -->
<property name="LOG_FILE" value="C:/data/logs/${springAppName}" />
<!--<property name="LOG_FILE" value="/data/ltz/logs/${springAppName}" />-->

<!-- 控制台的日志输出样式 -->
<property name="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}}" />

<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 日志输出编码 -->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>

<!-- 文件输出 -->
<appender name="localfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.json</file>
<rollingPolicy class="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>
<filter class="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文件输出 -->
<appender name="sqlfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.sqllog</file>
<rollingPolicy class="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>

<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="localfile"/>
</root>

<logger name="dao" level="debug" additivity="false">
<appender-ref ref="sqlfile" />
</logger>
</configuration>

5.日志模板说明

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

使用案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码/**
* @author litong
* @date 2020/6/1 17:10
*/
@RequestMapping("/test")
@RestController
public class TestController {


@ApiTimerLog
@GetMapping("/a")
public R a() {
return R.ok("a");
}
}

日志输出

1
ini复制代码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

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%