Using SpringBoot+Logback to write a simple link tracking

Keywords: Java Spring SpringBoot xml

Catalog

During the online troubleshooting recently, it was found that too many requests lead to the complexity of the log, and it is impossible to associate the user's logs in one or more requests. Therefore, we used SpringBoot+Logback to write a simple link tracking, which is described in detail below.

I. implementation principle

Spring Boot uses the LogBack log system by default, and has introduced related jar packages, so we can use LogBack to print logs without any configuration.

MDC (Mapped Diagnostic Context) is a function provided by log4j and logback, which is convenient for logging under multi-threaded conditions.

The implementation idea is to add the context information (such as customer ID, customer IP address, sessionId, request parameter, etc.) related to the request to MDC at the beginning of a request, and then configure logback-spring.xml, then Logback component will print out the information stored in MDC in each log, so as to realize all operations of an ID throughout the user.

II. Code practice

Create a new spring boot project spring boot log, and follow the steps below.

  1. New log interceptor

The log interceptor obtains the user's sessionId at the beginning of the request, and of course, it can also generate a UUID, which is stored in MDC after generation.
The SessionInterceptor code is as follows:

/**
 * Logging Interceptor 
 * @Author: Java Fragment
 *
 */
public class SessionInterceptor extends HandlerInterceptorAdapter {
    /**
     * Session ID
     */
    private final static String SESSION_KEY = "sessionId";


    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                           Object arg2, ModelAndView arg3) throws Exception {
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {

//        String token = UUID.randomUUID().toString().replaceAll("-","");
        //In this case, sessionId and UUID can be used.
        String token = request.getSession().getId();
        MDC.put(SESSION_KEY, token);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest arg0,
                                HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // delete
        MDC.remove(SESSION_KEY);
    }
}
  1. New configuration class

Create a new interceptor config to register the log interceptor.

The code of InterceptorConfig is as follows:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Bean
    public SessionInterceptor getSessionInterceptor() {
        return new SessionInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/*");
    }
}
  1. Modify logback-spring.xml

Configure logback-spring.xml to obtain the sessionId added by the log interceptor and print it to the log. The configuration file is obtained as follows:

%X{sessionId}

In this example, print the sessionId to the console and file. The complete configuration is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="log.base" value="./log/logback"/>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern> %date [%thread] [%X{sessionId}] %-5level %logger{80} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="logfile"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${log.base}.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}.%d{yyyy -MM-dd}.log.zip</FileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern> %date [%thread] [%X{sessionId}]  %-5level %logger{80} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <logger name="com.sample" level="TRACE"/>
    <root>
        <level value="INFO"/>
        <appender-ref ref="stdout"/>
        <appender-ref ref="logfile"/>
    </root>
</configuration>
  1. Add controller

Create a new TestLogController and print the logs.

The code is as follows:

@RestController
public class TestLogController {

    Logger log = LoggerFactory.getLogger(getClass());

    /**
     * Test login
     */
    @RequestMapping(value = "/testLogin")
    public String testLogin() {
        log.info("User login succeeded!");
        return "ok";
    }

    /**
     * Test order
     */
    @RequestMapping(value = "/testNewOrder")
    public String testNewOrder() {
        log.info("User created order!");
        log.info("Request complete, return ok!");
        return "ok";
    }

    /**
     * Test purchase
     */
    @RequestMapping(value = "/testPay")
    public String testPay() {
        log.info("User payment!");
        return "ok";
    }
}

Three, test

Open the continuous browser access interfaces testLogin, testNewOrder and testPay to simulate user login, order and payment operations. sessonId information has been included in the logs printed on the console and files. The printed results are as follows:

[http-nio-8888-exec-1] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - User login succeeded!
[http-nio-8888-exec-2] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - User created order!
[http-nio-8888-exec-2] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - Request complete, return ok!
[http-nio-8888-exec-3] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - User payment!

A simple link tracking function written by SpringBoot+Logback has been implemented. If you have any questions, please leave a message and communicate!

Full source address: https://github.com/suisuisui2019/springboot-study

Recommended reading

1. How to read yml configuration file gracefully in spring boot?
2. How to flexibly implement the encryption and decryption function of interface data in springboot?
3. The magic @ Enable * annotation in springboot?
4. In Java, Integer.parseInt and Integer.valueOf, are you still confused?
5. Spring cloud series - two ways to integrate Hystrix

Collect free Java related materials in limited time, covering Java, Redis, MongoDB, MySQL, Zookeeper, Spring Cloud, Dubbo/Kafka, Hadoop, Hbase, Flink and other high concurrent distributed, big data, machine learning and other technologies.
Pay attention to the public numbers below for free.

Posted by mark110384 on Thu, 31 Oct 2019 02:27:25 -0700