使用MDC进行日志打印

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/han1196639488/article/details/83544929

在项目中,我们会使用拦截器,aop或者过滤器来进行请求信息的提取,打印工作,当我们获取到需要的信息之后,就需要打印出来记录到日志中,这个时候我们会把日志记录到mdc中,然后给传递参数给log的自定义配置中使用,如下:

public class LogInterceptor extends HandlerInterceptorAdapter {

    private static final String USER_ID = "USER_ID";
    private static final String USER_NAME = "USER_NAME";

    public static final String REQUEST_REQUEST_URL = "REQ_REQUESTURL";
    public static final String REQUEST_USER_AGENT_MDC_KEY = "REQ_USERAGENT";
    public static final String REQUEST_X_FORWARDED_FOR = "REQ_XFORWARDEDFOR";


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        insertIntoMDC(request);
        return super.preHandle(request, response, handler);

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        clearMDC();
        super.postHandle(request, response, handler, modelAndView);
    }

    private void insertIntoMDC(HttpServletRequest request) {

        PrincipalRo ro = null;
        try {
            ro = ThreadObjManager.getLoginUser();
        } finally {
            if (ro != null) {
                if (ro.getId() != null) {
                    MDC.put(USER_ID, ro.getId().toString());
                }
                if (ro.getUsername() != null && !"".equals(ro.getUsername())) {
                    MDC.put(USER_NAME, ro.getUsername());
                }
            }
            StringBuffer requestURL = request.getRequestURL();
            if (requestURL != null) {
                String allUrl = requestURL.toString();
                if (request.getQueryString() != null) {
                    allUrl = allUrl + "?" + request.getQueryString();
                }
                MDC.put(REQUEST_REQUEST_URL, allUrl);
            }
            MDC.put(REQUEST_USER_AGENT_MDC_KEY, request
                    .getHeader("User-Agent"));
            MDC.put(REQUEST_X_FORWARDED_FOR, request
                    .getHeader("X-Forwarded-For"));
        }
    }


    private void clearMDC() {
        if (MDC.get(USER_ID) != null) {
            MDC.remove(USER_ID);
        }
        if (MDC.get(USER_NAME) != null) {
            MDC.remove(USER_NAME);
        }
        if (MDC.get(REQUEST_REQUEST_URL) != null) {
            MDC.remove(REQUEST_REQUEST_URL);
        }
        MDC.remove(REQUEST_USER_AGENT_MDC_KEY);
        MDC.remove(REQUEST_X_FORWARDED_FOR);
    }
}

我们在代码中为mdc插入用户的信息,用户使用的ip地址user-agent等信息,然后我们在自定义日志的时候就可以使用。mdc是线程独有的,使用的是threadloaclmap,保证了各个线程的在MDC键值对的独立性.
我们在我们的logback.xml文件中就可以配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <property name="APP_NAME" value="cssmanager" />
    <property name="LOG_HOME" value="/data/html/logs/${APP_NAME}" />
    <property name="MAX_HISTORY" value="30" />

在这个地方进行配置:

<property name="ENCODER_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %X{REQ_REQUESTURL}-%X{REQ_USERAGENT}-%X{REQ_XFORWARDEDFOR}-%X{USER_ID}-%X{USER_NAME}-%X{INSIGHT_REQUEST_ID} [%thread] ${APP_NAME}-%-5level %logger{36} - %msg%n" />
    <!-- 第三方框架-->
    <!-- spring-->
    <appender name="spring" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/spring.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/spring-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- mybatis-->
    <appender name="mybatis" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/mybatis.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/mybatis-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- zk-->
    <appender name="zookeeper" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/zookeeper.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/zookeeper-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- dubbo-->
    <appender name="dubbo" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/dubbo.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/dubbo-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- qccrframework-->
    <appender name="qccrframework" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/qccr-framework.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/qccr-framework-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- authmanager-->
    <appender name="authmanager" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/qccr-authmanager.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/qccr-authmanager-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- cssmanager自己-->
    <!--error-->
    <appender name="cssmanager-error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-error.log</file>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-error-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- biz-->
    <appender name="cssmanager-biz" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-biz.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-biz-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- integ-->
    <appender name="cssmanager-integ" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-integ.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-integ-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- sql-->
    <appender name="sql" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-sql.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-sql-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- biz-->
    <appender name="cssmanager-aop" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-aop.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-biz-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>
    <!-- 所有日志-->
    <appender name="all" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/${APP_NAME}-all.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP_NAME}-all.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${MAX_HISTORY}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${ENCODER_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 第三方框架-->
    <!-- Spring日志 -->
    <logger name="org.springframework" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="spring" />
    </logger>
    <!-- mybatis日志 -->
    <logger name="com.mybatis" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="mybatis" />
    </logger>
    <!-- zookeeper日志 -->
    <logger name="org.apache.zookeeper" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="zookeeper" />
    </logger>
    <!-- dubbo -->
    <logger name="com.alibaba.dubbo" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="dubbo" />
    </logger>
    <!-- qccrframework -->
    <logger name="com.qccr.framework" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="qccrframework" />
    </logger>
    <!-- authoritymanager -->
    <logger name="com.qccr.authoritymanager" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="authmanager" />
    </logger>

    <!-- cssmanager自己 -->
    <logger name="com.qccr.cssmanager.service">
        <level value="INFO"/>
        <appender-ref ref="cssmanager-biz" />
    </logger>
    <logger name="com.qccr.cssmanager.web.aop">
        <level value="INFO"/>
        <appender-ref ref="cssmanager-aop" />
    </logger>
    <logger name="com.qccr.cssmanager.integration">
        <level value="INFO"/>
        <appender-ref ref="cssmanager-integ" />
    </logger>
    <!-- sql -->
    <logger name="dao">
        <level value="DEBUG"/>
        <appender-ref ref="sql" />
    </logger>

    <root>
        <level value="INFO" />
        <appender-ref ref="all" />
        <appender-ref ref="cssmanager-error" />
    </root>
</configuration>

这样我们就可以在日志中打印出用户的信息,
另外,我们还可以加入traceId来进行分布式链路的追踪等。我们可以使用copyOnInheritThreadLocal方法进行获取父线程存入的值,然后在获取子线程的信息。

猜你喜欢

转载自blog.csdn.net/han1196639488/article/details/83544929