perf4j配置

274 阅读1分钟

SpringXML配置

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.tqmall.yunpai.interceptor.TraceInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

LogBack配置

<!--perf4j配置-->
    <appender name="statistics" class="ch.qos.logback.core.rolling.RollingFileAppender">

        <Encoding>UTF-8</Encoding>
        <file>${log.path}/perf4j.log</file>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名 -->
            <FileNamePattern>${log.path}/perf4j.%d{yyyy-MM-dd}.log</FileNamePattern>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%msg%n</pattern>
        </layout>
    </appender>

    <appender name="coalescingStatistics" class="org.perf4j.logback.AsyncCoalescingStatisticsAppender">
        <!--一个小时打印一次-->
        <timeSlice>3600000</timeSlice>
        <appender-ref ref="statistics"/>
    </appender>

    <logger name="org.perf4j.TimingLogger" level="info" additivity="false">
        <appender-ref ref="coalescingStatistics"/>
    </logger>
    <!--perf4j配置结束-->

Java代码

package com.tqmall.yunpai.interceptor;

import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Description:
 * User: wushangqing1
 * Date: 2019-06-14 9:36
 */
@Slf4j
public class TraceInterceptor extends HandlerInterceptorAdapter {

    private final Logger switchLogger = LoggerFactory.getLogger("org.perf4j.TimingLogger");

    private static ThreadLocal<StopWatch> local = new ThreadLocal<>();

    /**
     * The constant TRACE_ID.
     */
    private static final String TRACE_ID ="traceId";

    /**
     * Pre handle boolean.
     *
     * @param request  the request
     * @param response the response
     * @param handler  the handler
     * @return the boolean
     * @throws Exception the exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        StopWatch stopWatch = new Slf4JStopWatch();
        local.set(stopWatch);

        // 创建回话id
        String traceId = IdUtil.fastSimpleUUID();
        // 设置会话id
        MDC.put(TRACE_ID, traceId);
        response.setHeader(TRACE_ID, traceId);
        return true;
    }

    /**
     * After completion.
     *
     * @param request  the request
     * @param response the response
     * @param handler  the handler
     * @param ex       the ex
     * @throws Exception the exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        StopWatch watch = local.get();
        if (watch != null) {
            watch.stop(generateOperatonIdendifier(request, watch.getElapsedTime()));
            local.remove();
        }
        // 删除会话id
        MDC.remove(TRACE_ID);
    }

    private String generateOperatonIdendifier(HttpServletRequest request, long exeTime) {
        StringBuilder sb = new StringBuilder(64);
        sb.append(request.getMethod()).append("|");
        // URI
        if (switchLogger.isTraceEnabled()) { // 如果是trace级别,统计到具体的URI
            sb.append(request.getRequestURL());
            sb.append('|');
            sb.append(request.getHeader("User-Agent"));
        } else { // 按URI pattern匹配,方便汇总
            sb.append(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE));
        }
        // 记录慢得url,
        if (exeTime > 300) {
            sb.append("|");
            sb.append(MDC.get(TRACE_ID));
            sb.append("|SLOW");
        }
        return sb.toString();
    }

}