MDC 可用于绑定日志上下文信息
Slf4j: org.slf4j.MDC
slf4j作为日志门面, 定义了相当多的规范
例: 生成一个唯一id, 来区分输出的日志归属于哪次http请求
效果
代码语言:txt复制20:43:30.204 [xid=1529443036298219520] [XNIO-1 task-1 ] INFO com.content.system.service.common.web.aop.ControllerLogAop : GET:/test/testLib, args: []
20:43:30.207 [xid=1529443036298219520] [XNIO-1 task-1 ] INFO com.content.system.service.controller.TestController : info: true
20:43:30.207 [xid=1529443036298219520] [XNIO-1 task-1 ] ERROR com.content.system.service.controller.TestController : error: true
20:43:30.936 [xid=1529443036298219520] [XNIO-1 task-1 ] DEBUG com.content.system.service.dao.TestDAO.selectById : ==> Preparing: SELECT id,name,creator_id,create_date,modifier_id,modify_date,deleted FROM test WHERE id=? AND deleted=0
20:43:30.951 [xid=1529443036298219520] [XNIO-1 task-1 ] DEBUG com.content.system.service.dao.TestDAO.selectById : ==> Parameters: 1(Integer)
20:43:30.971 [xid=1529443036298219520] [XNIO-1 task-1 ] DEBUG com.content.system.service.dao.TestDAO.selectById : <== Total: 1
20:43:31.011 [xid=1529443036298219520] [XNIO-1 task-1 ] INFO com.content.system.service.common.web.aop.ControllerLogAop : result: ApiResult(msg=ok, code=0, data=TestPO(super=BasePO(id=1, creatorId=0, createDate=2022-05-24T18:02:49, modifierId=0, modifyDate=2022-05-25T10:53:29, deleted=false), name=tess))
配置
logback.xml
代码语言:txt复制<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<property name="log.debug.path"
value="/data/logs/cs-app-debug.log"/>
<property name="log.error.path"
value="/data/logs/cs-app-error.log"/>
<!-- 控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- %X 输出自定义的信息 -->
<pattern>%d{HH:mm:ss.SSS} [%-23X] [%-15thread] %-5level %-60logger{60} : %msg%n</pattern>
</encoder>
</appender>
<!-- debug日志输出 -->
<appender name="debugFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.debug.path}</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.debug.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>�te [%-23X] [%thread] %-5level %logger{36} : %msg%n</pattern>
</encoder>
</appender>
<!-- error日志输出 -->
<appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.error.path}</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>error</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.error.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>�te [%-23X] [%thread] %-5level %logger{36} : %msg%n</pattern>
</encoder>
</appender>
<logger name="org.apache" level="info"/>
<logger name="org.apache.commons" level="info"/>
<logger name="org.springframework" level="info"/>
<logger name="com.content.system.service.dao" level="debug"/>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="debugFile"/>
<appender-ref ref="errorFile"/>
</root>
</configuration>
定义过滤器
代码语言:txt复制public class RequestLogXidFilter implements Filter {
/**
* 日志上下文信息 key
*/
private static final String MDC_XID = "xid";
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
try {
MDC.put(MDC_XID, Long.toString(IdUtil.getSnowflakeNextId()));
filterChain.doFilter(servletRequest, servletResponse);
} finally {
MDC.remove(MDC_XID);
}
}
}
/**
* 绑定日志全局id
*/
@Bean
public FilterRegistrationBean<RequestLogXidFilter> requestLogFilter() {
FilterRegistrationBean<RequestLogXidFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new RequestLogXidFilter());
filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
filterRegistrationBean.setEnabled(true);
//filter使用 /* 匹配所有路径
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}