利用springboot+logback手写一个简单的链路追踪(代码片段)

Java碎碎念 Java碎碎念     2022-12-23     259

关键词:

最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简单的链路追踪,下面详细介绍下。

一、实现原理

Spring Boot默认使用LogBack日志系统,并且已经引入了相关的jar包,所以我们无需任何配置便可以使用LogBack打印日志。

MDC(Mapped Diagnostic Context,映射调试上下文)是log4j和logback提供的一种方便在多线程条件下记录日志的功能。

实现思路是在一个请求开始时,将请求相关的上下文信息(例如客户ID、客户的IP地址、sessionId、请求参数等)添加到MDC,然后配置好logback-spring.xml,则Logback组件将会在每条日志中打印出存放到MDC的信息,从而实现一个ID贯穿用户的所有操作。

二、代码实战

新建一个spring boot项目spring-boot-log,按照下面步骤操作。

  1. 新建日志拦截器

日志拦截器在请求开始获取用户的sessionId,当然也可以生成一个UUID,生成后存放到MDC中。
SessionInterceptor代码如下:

/**
 * 日志拦截器
 * @Author: Java碎碎念
 *
 */
public class SessionInterceptor extends HandlerInterceptorAdapter 
    /**
     * 会话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("-","");
        //本例测试使用sessionId,也可以使用UUID等
        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 
        // 删除
        MDC.remove(SESSION_KEY);
    

  1. 新建配置类

新建InterceptorConfig,注册刚才的日志拦截器。

InterceptorConfig代码如下:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer 

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

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/*");
    

  1. 修改logback-spring.xml

配置logback-spring.xml,获取日志拦截器添加的sessionId并打印到日志中,配置文件中获取方式如下:

%XsessionId

本例中打印sessionId到控制台和文件,完整配置如下:

<?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] [%XsessionId] %-5level %logger80 - %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.%dyyyy -MM-dd.log.zip</FileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern> %date [%thread] [%XsessionId]  %-5level %logger80 - %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. 添加controller

新建TestLogController,打印日志。

代码如下:

@RestController
public class TestLogController 

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

    /**
     * 测试登录
     */
    @RequestMapping(value = "/testLogin")
    public String testLogin() 
        log.info("用户登录成功!");
        return "ok";
    

    /**
     * 测试下单
     */
    @RequestMapping(value = "/testNewOrder")
    public String testNewOrder() 
        log.info("用户创建了订单!");
        log.info("请求完成,返回ok!");
        return "ok";
    

    /**
     * 测试购买
     */
    @RequestMapping(value = "/testPay")
    public String testPay() 
        log.info("用户付款!");
        return "ok";
    

三、测试

打开浏览器连续访问接口testLogin、testNewOrder和testPay,模拟用户登录、下单、付款操作,控制台和文件中打印的日志中已经包含了sessonId信息,打印的结果如下:

[http-nio-8888-exec-1] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - 用户登录成功!
[http-nio-8888-exec-2] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - 用户创建了订单!
[http-nio-8888-exec-2] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - 请求完成,返回ok!
[http-nio-8888-exec-3] [CB8E7DB250A31F2BE6C05B30633B9A95] INFO  com.example.springbootlog.controller.TestLogController - 用户付款!

到此SpringBoot+Logback手写一个简单的链路追踪功能已经全部实现,有问题欢迎留言沟通哦!

完整源码地址: https://github.com/suisui2019/springboot-study

推荐阅读

1.SpringBoot中如何优雅的读取yml配置文件?
2.SpringBoot中如何灵活的实现接口数据的加解密功能?
3.SpringBoot中神奇的@Enable*注解?
4.Java中Integer.parseInt和Integer.valueOf,你还傻傻分不清吗?
5.SpringCloud系列-整合Hystrix的两种方式


限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。
关注下方公众号即可免费领取:

Java碎碎念公众号

springboot配置logback日志

Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4JAPI使你可以... 查看详情

springboot初始教程之日志处理

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classic和... 查看详情

springboot初始教程之日志处理(代码片段)

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-class... 查看详情

springboot初始教程之日志处理(代码片段)

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-class... 查看详情

springboot应用系列5--springboot2整合logback

上一篇我们梳理了SpringBoot2整合log4j2的配置过程,其中讲到了SpringBoot2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对于那些日志量不算太高的项目来说,选择logback更简单方便。1.pom.xmlpom.xml不需要添加... 查看详情

在springboot项目中添加logback的mdc

在SpringBoot项目中添加logback的MDC  先看下MDC是什么MappedDiagnosticContext,用于打LOG时跟踪一个“会话“、一个”事务“。举例,有一个webcontroller,在同一时间可能收到来自多个客户端的请求,如果一个请求发生了... 查看详情

springboot配置每天一个日志文件logback-spring.xml

...pring.xml内容部署启动(2)application.yml放在resources下工程目录springboot配置每天一个日志文件logback-spring.xmlspringboot工程配置文件可以放在多个地方,可以直接放在resources目录下,也可以放在根目录下的config目录&#x 查看详情

springboot使用默认的logback配置logback-spring.xml每天一个日志文件(代码片段)

...ring.xml内容部署启动(2)application.yml放在resources下使用logbackspringboot配置每天一个日志文件logback-spring.xmlspringboot工程配置文件可以放在多个地方,可以直接放在resources目录下,也可以放在根目录下的con 查看详情

springboot启动过程解析logback

使用SpringBoot默认的日志框架Logback。所有这些POM依赖的好处在于为开发Spring应用提供了一个良好的基础。SpringBoot所选择的第三方库是经过考虑的,是比较适合产品开发的选择。但是SpringBoot也提供了不同的选项,比如日志框架可... 查看详情

springboot项目中使用logback进行日志管理

Logback简介logback是由log4j创始人设计的又一个开源日志组件,优化了log4j存在的性能问题。logback包含了三个模块:logback-core、logback-classic、logback-access。logback-core 是其它模块的基础设施,其它模块基于它构建,显然,logback-core... 查看详情

手写一个springboot简易版框架

...代码,看演示效果文章目录一、项目框架二、创建simple-springboot父模块1.修改pom.xml三、创建springboot-module子模块1.修改pom.xml2.创建META-INF/services/com.example.springboot.AutoConfiguration3.创建AutoConfiguration4.创建WebServerA 查看详情

手写一个springboot简易版框架

...代码,看演示效果文章目录一、项目框架二、创建simple-springboot父模块1.修改pom.xml三、创建springboot-module子模块1.修改pom.xml2.创建META-INF/services/com.example.springboot.AutoConfiguration3.创建AutoConfiguration4.创建WebServerA 查看详情

第十章springboot+logback

logback是boot默认的日志首选,个人觉得是最好的日志实现(比log4j好)下边,在之前的代码基础上增加一个功能,该功能要实现mybatis的andor联查功能,并通过logback日志在控制台去查看输出的sql情况。即实现如下sql的功能:SELECT*FRO... 查看详情

springboot项目使用logback把日志输出到控制台或输出到文件

...初始化,可从控制台输出信息中查看加载的配置文件。在Springboot项目中可以自定义logback配置文件名及文件位置要想让Springboot项目识别到该logback配置文件,只需要在Springboot配置文件中定义好配置文件的加载路径即可如下所示:... 查看详情

springboot整合logback集成elk实现日志的汇总分析统计和检索功能(代码片段)

  在SpringBoot当中,默认使用logback进行log操作。logback支持将日志数据通过提供IP地址、端口号,以Socket的方式远程发送。在SpringBoot中,通常使用logback-spring.xml来进行logback配置。首先、创建一个elk的springboot项目,然后先对logback... 查看详情

springboot使用之三:springboot使用logback日志

springboot默认使用的日志就是logback,所以使用logback不需要添加日志相关依赖了,执行添加logback.xml配置文件,springboot这个聪明的框架便能识处理你的配置。做法:将logback.xml放在resources下(classpath)下即可。配置参考如下:<?xm... 查看详情

使用idea搭建一个springboot+mybatis+logback的maven项目(代码片段)

(注意项目名不能有大写。。。。。。),把项目类型改成War类型。(web项目)使用mybatis-generator插件生成实体类和接口在resources目录中新建一个generatorConfig.xml的文件generatorConfig.xml文件信息1<?xmlversion="1.0"encoding="UTF-8"?>2<!D... 查看详情

springboot使用默认的logback配置logback-spring.xml每天一个日志文件(代码片段)

...ring.xml内容部署启动(2)application.yml放在resources下使用logbackspringboot配置每天一个日志文件logback-spring.xmlspringboot工程配置文件可以放在多个地方,可以直接放在resources目录下,也可以放在根目录下的config目录,部署运行... 查看详情