基于logback添加唯一追踪ID

本文详细介绍了一种在Java Web项目中使用Logback进行日志记录的方法,包括自定义跟踪ID、配置不同类型的日志输出及日志级别,并展示了如何在web.xml中设置过滤器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、添加过滤器LogbackFilter

package com.myself.ssmTest.web.filter;

import org.slf4j.MDC;

import javax.servlet.*;
import java.io.IOException;
import java.util.UUID;

/**
 * 增加输出日志traceRootId
 */
public class LogbackFilter implements Filter {

	private static final String UNIQUE_ID = "traceRootId";

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

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
						 FilterChain chain) throws IOException, ServletException {
		boolean bInsertMDC = insertMDC();
		try {
			chain.doFilter(request, response);
		} finally {
			if(bInsertMDC) {
				MDC.remove(UNIQUE_ID);
			}
		}
	}

	private boolean insertMDC() {
		UUID uuid = UUID.randomUUID();
		String uniqueId = UNIQUE_ID +"-"+ uuid.toString().replace("-", "");
		MDC.put(UNIQUE_ID, uniqueId);
		return true;
	}

	@Override
	public void destroy() {

	}

}

2、在src\main\webapp\WEB-INF\web.xml文件的加上过滤器的配置

  <filter>
    <filter-name>logbackFilter</filter-name>
    <filter-class>com.yz.rainbowbridgewebcenter.filter.LogbackFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>logbackFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3、在logback.xml文件中的每一个<appender>标签下的<encoder><pattern>中都加上traceRootId,

我的配置文件是这么添加的(红色字体):<pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>,全部 如配置下图(仅供参考):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--文件资源的引用-->
    <property resource="app.properties"/>
    <!-- 默认输出文件 -->
    <appender name="DEFAULT-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/default/common-default.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- 默认错误文件 -->
    <appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/error/common-error.log.%d{yyyyMMdd}</fileNamePattern>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>
    <!-- 性能日志文件 -->
    <appender name="PERF-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/perf/common-perf.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- 默认dao日志文件 -->
    <appender name="DAO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/dao/common-dao.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- service日志文件 -->
    <appender name="SERVICE-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/service/common-service.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- 业务日志文件 -->
    <appender name="BUSINESS-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/business/common-business.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- WEB日志文件 -->
    <appender name="WEB-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/web/common-web.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- 报警日志 -->
    <appender name="ALARM-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/alarm/common-alarm.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d [%t] %-5p %c{2} [%X{traceRootId}] - [%m]%n</pattern>
        </encoder>
    </appender>
    <!--默认追踪日志-一般model或工具类日志用此  -->
    <appender name="TRACE-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.home}/trace/tracing.log.%d{yyyy-MM-dd-HH}.gz</fileNamePattern>
            <maxHistory>72</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d - [%m]%n</pattern>
        </encoder>
    </appender>
    <!-- ===================================================================== -->
    <!-- Loggers                                                               -->
    <!-- ===================================================================== -->
    <logger name="com.myself.ssmTest.controller" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="WEB-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
        <logger name="com.myself.ssmTest.service" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="SERVICE-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
     <logger name="com.myself.ssmTest.dao" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="DAO-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
     <logger name="com.myself.ssmTest.model" additivity="false">
        <level value="INFO"/>
        <appender-ref ref="TRACE-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
     <logger name="businessLogger" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="BUSINESS-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
    <logger name="com.tuan.core.common.aop.pref.PerformanceMonitorInterceptor" additivity="false">
    	<level value="INFO"/>
    	<appender-ref ref="PERF-APPENDER"/>
    </logger>
   
    <logger name="java.sql" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="DAO-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
    
    <logger name="alarmLogger" additivity="false">
        <level value="${log.root.level}"/>
        <appender-ref ref="ALARM-APPENDER"/>
        <appender-ref ref="ERROR-APPENDER"/>
    </logger>
    <!-- 屏蔽logger-start -->
    <logger name="org.springframework" level="${log.root.level}"/>
    <logger name="org.apache" level="WARN"/>
    <logger name="org.mybatis.spring" level="${log.root.level}"/>
    <!-- 屏蔽jdk日志 -->
    <logger name="java" level="WARN"/>
    <logger name="com.mchange" additivity="false">
        <level value="WARN"/>
        <appender-ref ref="DAO-APPENDER"/>
    </logger>
    <!-- 屏蔽logger-end-->
    <root level="${log.root.level}">
        <appender-ref ref="DEFAULT-APPENDER"></appender-ref>
        <appender-ref ref="ERROR-APPENDER"></appender-ref>
    </root>
</configuration> 

相关文章:
logback的搭建与使用-maven项目:https://blog.youkuaiyun.com/qq_25646191/article/details/81004513


MDC(Mapped Diagnostic Contexts)是一种用于日志上下文信息管理的机制,广泛应用于链路追踪中以增强日志的可读性和调试能力。通过MDC,可以在日志中记录请求的唯一标识(如traceId)以及操作者、请求来源等信息,从而实现对请求链路的追踪。 在链路追踪实践中,MDC通常与日志框架(如Logback、Log4j)结合使用。以下是一个基于Spring Boot的示例,展示如何通过MDC记录traceId并将其集成到日志中。 ### MDC在链路追踪中的使用方法 #### 1. **配置日志框架** 在`logback-spring.xml`文件中配置日志格式,将MDC中的traceId等信息添加到日志输出中。例如: ```xml <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg [traceId:%X{traceId}] [operator:%X{operator}] [request:%X{request}]%n</pattern> </encoder> </appender> <root level="info"> <appender-ref ref="STDOUT" /> </root> </configuration> ``` 此配置将traceId、operator和request作为MDC变量,并在日志输出中展示[^2]。 #### 2. **拦截器中设置MDC** 在微服务架构中,可以通过拦截器(Interceptor)或过滤器(Filter)在请求开始时设置MDC的值,并在请求结束时清除MDC。例如,在Spring Boot中实现一个拦截器: ```java import org.slf4j.MDC; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.UUID; @Component public class TraceInterceptor implements HandlerInterceptor { private static final String TRACE_ID = "traceId"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String traceId = UUID.randomUUID().toString(); MDC.put(TRACE_ID, traceId); MDC.put("operator", request.getHeader("X-Operator")); MDC.put("request", request.getRequestURI()); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { MDC.clear(); } } ``` 此拦截器在请求开始时生成唯一的traceId,并将其与其他上下文信息一起存入MDC,在请求结束时清除MDC[^2]。 #### 3. **日志输出示例** 当配置完成后,日志输出会包含traceId等信息,例如: ``` 2023-10-01 12:34:56.789 [http-nio-8080-exec-1] INFO com.example.demo.Controller - Handling request [traceId:550e8400-e29b-41d4-a716-446655440000] [operator:admin] [request:/api/test] ``` 这种日志格式便于通过日志分析工具(如ELK Stack)进行链路追踪。 ### 4. **与其他链路追踪框架结合** MDC可以与其他链路追踪框架(如SkyWalking、Zipkin)结合使用,以增强日志的可追溯性。例如,在SkyWalking中,traceId会自动注入到MDC中,无需手动设置。通过这种方式,日志和链路追踪数据可以相互关联,从而实现更高效的调试和问题定位。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值