背景:前幾天公司上線了一個項目(手機H5項目)說是用戶和老闆都覺得相應速度比較慢,然後下來要查找原因,所以就需要統計服務器端接口調用時長。
方案:
1.Logback+code
具體的操作步驟就是在每個方法的調用前後加上時間點,然後再把這些結果記錄到日誌中。
接口內調用的代碼:
@Override
public User getUserInfo(int userId) {
Long correspondingStartTime = System.currentTimeMillis();
logger.debug("debug_getUserInfo userId\t" + userId);
try {
User user = userInfoService.getUserInfo(userId);
if(user==null||userId<=0){
logger.debug("getUserInfo userId==null"+userId);
}else{
logger.debug("getUserInfo userId\t" + userId + ",response:" + user.toString());
}
Long correspondingEndTime = System.currentTimeMillis();
CorrespondingTime.correspondingTime("UserServiceImpl", "getUserInfo", correspondingStartTime, correspondingEndTime);
return user;
} catch (RuntimeException e) {
logger.error("getUserInfo userId:" + userId, e);
// 封裝對象。
User user = new User();
return user.setError(getBaseResponse(e));
}
}
相應時長統計類:
public class CorrespondingTime {
private static final Logger logger = LoggerFactory.getLogger("CorrespondingTimeLog");
public static void correspondingTime(String clazzName,String methodName,Long correspondingStartTime,Long correspondingEndTime){
logger.info(clazzName+";"+methodName+";"+(correspondingEndTime-correspondingStartTime));
}
}
Logback添加日誌文件:
<appender name="correspondingTime" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>../user-log/server-correspondingTime.log</File>
<encoder>
<pattern>%m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../user-log/server-correspondingTime.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
</appender>
/*日誌文件名稱*/
<logger name="CorrespondingTimeLog" additivity="false">
<appender-ref ref="correspondingTime" />
</logger>
2.Spring AOP
既然Spring aop能夠在方法內輸出日誌,那麼在方法內部肯定能夠實現對接口響應時長的統計。查找資料如下:
@Aspect
@Component
public class TimestatAspect {
private static final Logger LOG = LoggerFactory.getLogger(TimestatAspect.class);
@Around("execution(* com.baidu.soa.crm.user.dao.impl.*DaoImpl.*(..))")
public Object printTime(ProceedingJoinPoint pjp) throws Throwable {
long l1 = System.currentTimeMillis();
Object obj = pjp.proceed();
String param = "(";
Object[] params = pjp.getArgs();
if (params != null) {
boolean first = true;
for (Object o : params) {
String p = (o == null ? "null" : o.toString());
if (first) {
param = param + p;
first = false;
} else
param = param + ":" + p;
}
}
param = param + ")";
LOG.debug("類名爲:" + pjp.getTarget().getClass().getName() + "|方法名爲:" + pjp.getSignature().getName() + "|參數爲:" + param + "|執行時間爲:" + (System.currentTimeMillis() - l1));
return obj;
}
}
總結:
1、比較好想,也容易實現但是有點土鱉。如果需要統計的接口過多,那麼改動量就很大,不推薦。
2、調用Spring AOP自身屬性,比較簡單,能夠實現對多出接口的統計,贊!