spring專案中監控方法執行時間
阿新 • • 發佈:2018-12-25
當專案規模越來越大時,難免會遇到效能問題。尤其是多系統之間介面呼叫,所以新增時間監控很有必要。但是由於程式碼已經上線,所以要保證對程式碼的侵略性最小,所以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,其他的視你專案引用而定,缺什麼引入什麼