Logging has always been a vital part of the program, troubleshooting problems, statistics…..
To solve the problem
SpringBoot Adds global custom log link information.
1. Filter: intercepts specified requests and obtains parameters and request information, which can be added to the MDC process based on service customization.
2. Time interceptor, according to annotations to intercept, into the process log (MDC), method execution time.
3. For specific services, you can inject required information into process logs (MDC).
1.MDCFilter
Request filters, which are used to add request first-class information to MDC.
/** * Intercepts request information and adds it to log **@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(); }}}Copy the code
2.ApiTimerLog
Annotations used to mark the time required to print the execution of a method.
/** ** time logging annotation ** Method that needs to record time consumption **@author litong
* @date 2020/7/23 15:30
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiTimerLog {
}
Copy the code
3.TimeAspect
Time slice
/ * * *@author litong
* @date 2020/7/23 15:31
*/
@Aspect
@Component
@Slf4j
public class TimeAspect {
// Fix the globally unique qualifier for the Timer annotation
@Pointcut("@annotation(com.ltz.ltzg.common.log.annotation.ApiTimerLog)")
private void pointcut(a) {}// Inject by packet
// @Around("execution(* com.ltz.ltzg.auth.controller.*.*(..) ) + ""
// "|| execution(* com.ltz.ltzg.api.controller.*.*(..) )"
// Inject as annotated
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// Start time
long start = System.currentTimeMillis();
// Call the target method
Object result = R.err(ErrorEnums.SHOW_FAIL);
try {
result = joinPoint.proceed();
} catch (Throwable throwable) {
throw throwable;
} finally {
// Get the execution time
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");
}
returnresult; }}Copy the code
4.logback-local.xml
<! -- This log saves log information of different log levels to different files -->
<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" />
<! -- Log output position in the project -->
<property name="LOG_FILE" value="C:/data/logs/${springAppName}" />
<! --<property name="LOG_FILE" value="/data/ltz/logs/${springAppName}" />-->
<! -- Console log output style -->
<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 = {errcode}] {magenta} % X % CLR (-) {abbreviation} % CLR ([% 15.15 t]) {abbreviation} % m % n ${wEx LOG_EXCEPTION_CONVERSION_WORD: - %}}" />
<! -- Console output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<! -- Log output code -->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<! -- File output -->
<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 file output -->
<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>
<! -- Log output level -->
<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>
Copy the code
5. Log template description
The key added to the MDC node must be printed in %X{url} format in the log template.
Use case
/ * * *@author litong
* @date2020/6/1 closed * /
@RequestMapping("/test")
@RestController
public class TestController {
@ApiTimerLog
@GetMapping("/a")
public R a(a) {
return R.ok("a"); }}Copy the code
Log output
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-LinkCopy the code