如何为Logback日志添加唯一追踪ID

 更新时间:2024年12月16日 09:56:43   作者:Mistra丶  
本文介绍了如何为Logback日志添加唯一追踪ID,以便在测试和调试时更容易定位报错信息,通过创建过滤器和修改配置文件,可以在每个请求的日志中添加唯一的ID,并将其返回给前端,这样,当用户反馈报错时,开发人员可以根据ID快速定位和解决问题

为Logback日志添加唯一追踪ID

平常在测试的时候,不容易定位报错信息,这个时候给日志加上唯一的追踪ID,查找日志的时候就非常方便了。

像这样:

每个请求打印的日志都会有不同的ID,哪个请求出错,根据ID来定位日志就行了。

这个ID还会返回给前端,前端发现报错让后台找原因的话只需要给个ID,后台开发人员就能根据

环境:

  • SpringBoot - 2.1.5.RELEASE
  • JDK8

一、创建过滤器

  • LogMDCFilter.java
public class LogMDCFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String requestIdKey = "requestId";
        String requestId = UUID.randomUUID().toString();
        MDC.put(requestIdKey, requestId);

        String levelName = "logLevel";
        String value = servletRequest.getParameter(levelName);
        if (StringUtils.isNotBlank(value)) {
        	//org.slf4j.MDC
            MDC.put(levelName, value.toUpperCase());
        }

        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            MDC.remove(requestIdKey);
            MDC.remove(levelName);
        }
    }

    @Override
    public void destroy() {

    }
}
  • DebugLogTurboFilter.java
public class DebugLogTurboFilter extends TurboFilter {

    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
        int levelInt = level.toInt();
        String levelName = MDC.get("logLevel");
        if (StringUtils.isBlank(levelName) || "DEBUG,INFO,TRACE,WARN".indexOf(levelName) == -1) {
            return FilterReply.NEUTRAL;
        }
        if ((Level.TRACE.levelStr.equals(levelName) && levelInt >= Level.TRACE_INT)
                || (Level.DEBUG.levelStr.equals(levelName) && levelInt >= Level.DEBUG_INT)
                || (Level.INFO.levelStr.equals(levelName) && levelInt >= Level.INFO_INT)
                || (Level.WARN.levelStr.equals(levelName) && levelInt >= Level.WARN_INT)) {
            return FilterReply.ACCEPT;
        }
        return FilterReply.DENY;
    }
}

二、注册过滤器

  • FilterConfiguration.java
@Configuration
public class FilterConfiguration {

    @Bean
    public FilterRegistrationBean logFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //注入过滤器
        registration.setFilter(new LogMDCFilter());
        //拦截规则
        registration.addUrlPatterns("/*");
        //过滤器名称
        registration.setName("logMDCFilter");
        //过滤器顺序
        registration.setOrder(0);
        return registration;
    }
}

三、Logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line - %msg %X{requestId}%n
            </pattern>
        </encoder>
    </appender>
	//上面的 DebugLogTurboFilter
    <turboFilter class="com.example.common.config.DebugLogTurboFilter">
    </turboFilter>

    <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/home/logs/merchant/common-merchant.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>/home/logs/merchant/history/merchant.%d{yyyy-MM-dd HH}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>3MB</maxFileSize>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line - %msg %X{requestId}%n
            </pattern>
        </encoder>
    </appender>

    <!-- project default level -->
    <logger name="com.version" level="DEBUG"/>
    <logger name="org.springframework.web.servlet.handler" level="INFO"/>
    <logger name="com.example.user.mapper" level="DEBUG"/>
    <!--log4jdbc -->
    <logger name="org.springframework.jdbc.core.JdbcTemplate" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="rollingFile"/>
    </root>
</configuration>

注意配置中的{requestId}占位符,这个就会替换为生成的唯一日志ID。

四、返回值封装

  • ResponseModel.java
public class ResponseModel implements Serializable {

    private static final long serialVersionUID = -8972819161141262263L;

    @ApiModelProperty(value = "是否处理成功", name = "success", example = "true")
    private Boolean success;
    @ApiModelProperty(value = "返回码", name = "code", example = "200")
    private Integer code;
    @ApiModelProperty(value = "处理消息", name = "msg", example = "处理成功")
    private String msg;
    @ApiModelProperty(value = "返回数据", name = "data", example = "{}")
    private Object data;
    private String requestId = MDC.get("requestId");
    }

代码写完了,前端每次请求,如果有返回值的话,都会收到唯一日志ID,如图:

可以根据requestId,通过此命令在日志文件中查找对应的日志

cat common-user.log | grep -C 10 f11819ea-6169-4c13-8032-979a88977575

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Kotlin语言编程Regex正则表达式实例详解

    Kotlin语言编程Regex正则表达式实例详解

    这篇文章主要为大家介绍了Kotlin语言编程Regex正则表达式实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Java程序数据库连接满问题的排查指南

    Java程序数据库连接满问题的排查指南

    这篇文章主要介绍了Java应用数据库连接满问题的识别、诊断、原因排查及解决方案,提出通过监控、代码优化、配置调整和预防措施,结合Arthas等工具,有效应对和预防该问题,需要的朋友可以参考下
    2025-07-07
  • spring data简化jpa开发_动力节点Java学院整理

    spring data简化jpa开发_动力节点Java学院整理

    这篇文章主要介绍了spring data简化jpa开发,本文主要讲述 Spring Data JPA,希望能够深入学习 Spring 和 JPA,有兴趣的可以了解下
    2017-09-09
  • Maven打包之解决没有依赖jar包问题及分析

    Maven打包之解决没有依赖jar包问题及分析

    用户使用Maven打包FTPServer程序时,因未配置依赖打包导致jar体积过小且运行报错,解决方法是添加maven-assembly插件生成包含依赖的jar包,确保程序正常运行
    2025-09-09
  • 简单实现Java版学生管理系统

    简单实现Java版学生管理系统

    这篇文章主要为大家详细介绍了简单实现Java版学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • Spring Cloud多个微服务之间调用代码实例

    Spring Cloud多个微服务之间调用代码实例

    这篇文章主要介绍了Spring Cloud多个微服务之间调用代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Spring Security添加验证码的两种方式小结

    Spring Security添加验证码的两种方式小结

    使用spring security的时候,框架会帮我们做账户密码的验证,但是如我们需要添加一个验证码,就需要对配置文件进行修改,这篇文章主要给大家介绍了关于Spring Security添加验证码的两种方式,需要的朋友可以参考下
    2021-10-10
  • AI算法实现五子棋(java)

    AI算法实现五子棋(java)

    这篇文章主要为大家详细介绍了AI算法实现五子棋,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • SpringBoot返回Json对象报错(返回对象为空{})

    SpringBoot返回Json对象报错(返回对象为空{})

    本文主要介绍介绍了SpringBoot返回Json对象报错(返回对象为空{}),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 如何实现Spring Event(异步事件)

    如何实现Spring Event(异步事件)

    这篇文章主要介绍了如何实现Spring Event(异步事件)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02

最新评论