Slf4j+Logback MDC使用

kyaa111 1年前 ⋅ 450 阅读

MDC 可用于绑定日志上下文信息

Slf4j: org.slf4j.MDC

slf4j作为日志门面, 定义了相当多的规范

例: 生成一个唯一id, 来区分输出的日志归属于哪次http请求

效果

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

<?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>%date [%-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>%date [%-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>

定义过滤器

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;
}