1. 程式人生 > >spring專案中監控方法執行時間

spring專案中監控方法執行時間

當專案規模越來越大時,難免會遇到效能問題。尤其是多系統之間介面呼叫,所以新增時間監控很有必要。但是由於程式碼已經上線,所以要保證對程式碼的侵略性最小,所以Spring AOP可以解決這個問題。

首先定義監控方法

package com.project.common.util;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.StopWatch;
import
org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Created by manong on 2016/9/2. * Desc:用來記錄每個介面方法的執行時間 */ public class MethodTimeAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { Logger logger = LoggerFactory.getLogger(invocation.getThis().getClass()); // 用 commons-lang 提供的 StopWatch 計時
StopWatch clock = null; if (logger.isDebugEnabled()) { clock = new StopWatch(); clock.start(); // 計時開始 } Object result = invocation.proceed(); if (!logger.isDebugEnabled()) return result; clock.stop(); // 計時結束 // 方法引數型別,轉換成簡單型別
Class[] params = invocation.getMethod().getParameterTypes(); String[] simpleParams = new String[params.length]; for (int i = 0; i < params.length; i++) { simpleParams[i] = params[i].getSimpleName(); } Object[] args = invocation.getArguments(); logger.debug("Takes:" + clock.getTime() + " ms [" + invocation.getThis().getClass().getName() + "." + invocation.getMethod().getName() + "(" + StringUtils.join(simpleParams, ",") + ")(" + StringUtils.join(args, ",") + ")] "); return result; } }

注意:在上面的類中,我們定義了日誌的輸出級別 !logger.isDebugEnabled(),這樣我們就可以根據級別篩選 輸出到單獨的檔案與系統其他日誌分開。

然後我們需要在Spring配置檔案中定義切入點

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
       default-lazy-init="true">
    <aop:aspectj-autoproxy />
    <bean id="methodTimeAdvice" class="com.project.common.util.MethodTimeAdvice"/>
    <aop:config>
        <!-- Spring 2.0 可以用 AspectJ 的語法定義 Pointcut,這裡攔截 service 包中的所有方法 -->
        <aop:advisor id="methodTimeLog" advice-ref="methodTimeAdvice"
                     pointcut="
                     (execution(* com.project.service.impl.*Service.*(..)))
                     or (execution(* com.project.controller.*Controller.*(..)))
                     "/>
    </aop:config>
</beans>

注意:pointcut的語法有時間再補上

然後,在logback.xml 或者 log4j.xml中我們需要配置日誌輸出

<appender name="timeAdvice" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${user.home}/logs/timeAdvice.log" />
        <param name="Encoding" value="UTF-8" />
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS}-[%p] %m      |[%c:%L][%t]%n" />
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMin" value="DEBUG" />
            <param name="LevelMax" value="DEBUG" />
        </filter>
    </appender>
<logger name="com.project.service.impl">
        <level value="DEBUG"></level>
        <appender-ref ref="timeAdvice" />
    </logger>
    <logger name="com.project.controller">
        <level value="DEBUG"></level>
        <appender-ref ref="timeAdvice" />
    </logger>
OK,通過上面的配置就可以將時間監控日誌輸出到單獨的日誌檔案中了,便於除錯。

最後的最後,千萬別忘了引入相應的jar包:aopalliance-1.0.jar,其他的視你專案引用而定,缺什麼引入什麼