Controller及service层利用AOP通过日志记录加入方法的参数,执行时间,及返回结果
This commit is contained in:
parent
fdf4b85164
commit
e685c1a245
|
@ -61,8 +61,6 @@ public class GameController {
|
|||
@ApiParam(name = "tpiID", required = true, value = "实训实例的ID") @RequestParam String tpiID,
|
||||
@ApiParam(name = "tpiRepoName", required = true, value = "tpiRepoName") @RequestParam String tpiRepoName)
|
||||
throws Exception {
|
||||
logger.info("开启实训:tpmGitURL: {}, tpiID: {}, tpiRepoName: {}", tpmGitURL, tpiID, tpiRepoName);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
|
||||
// 设定工作路径为${workspace}/myshixun_${tpiID}
|
||||
|
@ -102,12 +100,6 @@ public class GameController {
|
|||
@ApiParam(name = "content_modified", required = true, value = "文件是否修改的标志") @RequestParam Integer content_modified,
|
||||
@ApiParam(name = "sec_key", required = false, value = "每一次评测的唯一标识") String sec_key)
|
||||
throws Exception {
|
||||
logger.info(
|
||||
"评测:tpiID: {}, tpiGitURL: {}, buildID: {}, isPublished: {}, instanceChallenge: {}, "
|
||||
+ "testCases: {}, tpmScript: {}, timeLimit: {}, resubmit: {}, "
|
||||
+ "times: {}, needPortMapping: {}, podType: {}, file: {}, containers: {}, content_modified: {}, sec_key: {}",
|
||||
tpiID, tpiGitURL, buildID, isPublished, instanceChallenge, testCases, tpmScript, timeLimit, resubmit,
|
||||
times, needPortMapping, podType, file, containers, content_modified, sec_key);
|
||||
|
||||
// 记录开始时间
|
||||
String evaluateStartTime = LocalDateTime.now().toString();
|
||||
|
@ -258,8 +250,6 @@ public class GameController {
|
|||
@ApiParam(name = "tpmGitURL", required = true, value = "学员对应当前实训的tpm版本库地址,base64编码") @RequestParam String tpmGitURL,
|
||||
@ApiParam(name = "identifier", required = true, value = "push权限") @RequestParam String identifier)
|
||||
throws Exception {
|
||||
logger.info("tpm版本库已更新,同步tpi版本库,tpiID: {}, tpiGitURL: {}, tpmGitURL: {}, identifier: {}", tpiID, tpiGitURL,
|
||||
tpmGitURL, identifier);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
package com.educoder.bridge.game.interceptor;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* 对Controller,以INFO级别记录每个方法的参数及耗时,返回结果
|
||||
* 对Service,判断debug是否开启,如果开启,以debug级别记录每个方法参数及耗时。以上两点AOP Logging实现就可以
|
||||
*
|
||||
* @author weishao
|
||||
* @date 2019-06-03
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class LogInterceptor {
|
||||
|
||||
// controller层切点
|
||||
@Pointcut("execution (* com.educoder.bridge.*.controller.*.*(..))")
|
||||
private void controllerPointCut() {}
|
||||
|
||||
// service层切点
|
||||
@Pointcut("execution (* com.educoder.bridge.*.service.*.*(..))")
|
||||
private void servicePointCut() {}
|
||||
|
||||
/**
|
||||
* 统计Controller的参数,响应时长,和返回结果
|
||||
* @param joinPoint
|
||||
* @return
|
||||
*/
|
||||
@Around("controllerPointCut()")
|
||||
public Object controllerAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
Instant startTime = Instant.now();
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
|
||||
|
||||
// 获取并以info级别记录参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
String[] parameterNames = signature.getParameterNames();
|
||||
StringBuffer params = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
params.append(parameterNames[i]).append(":").append(args[i]).append(",");
|
||||
}
|
||||
if (params.length() > 0) {
|
||||
params.deleteCharAt(params.length() - 1);
|
||||
}
|
||||
|
||||
logger.info("interface: {}, params: [{}]", signature.getName(), params.toString());
|
||||
|
||||
// 执行方法
|
||||
Object obj = joinPoint.proceed(args);
|
||||
|
||||
// 记录耗时及结果
|
||||
Duration d = Duration.between(startTime, Instant.now());
|
||||
logger.info("interface: {}, time consuming: {}ms, response: [{}]", signature.getName(), d.toMillis(), obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计Service的参数,响应时长,和返回结果
|
||||
* @param joinPoint
|
||||
* @return
|
||||
*/
|
||||
@Around("servicePointCut()")
|
||||
public Object serviceAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
Instant startTime = Instant.now();
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
|
||||
|
||||
// 获取并以debug级别记录参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
String[] parameterNames = signature.getParameterNames();
|
||||
StringBuffer params = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
params.append(parameterNames[i]).append(":").append(args[i]).append(",");
|
||||
}
|
||||
if (params.length() > 0) {
|
||||
params.deleteCharAt(params.length() - 1);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("method: {}, params: [{}]", signature.getName(), params.toString());
|
||||
}
|
||||
|
||||
// 执行方法
|
||||
Object obj = joinPoint.proceed(args);
|
||||
|
||||
// 记录耗时及结果
|
||||
Duration d = Duration.between(startTime, Instant.now());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("method: {}, time consuming: {}ms, result: [{}]", signature.getName(), d.toMillis(), obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,8 +11,10 @@
|
|||
http://www.springframework.org/schema/websocket
|
||||
http://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
<context:component-scan base-package="com.educoder.bridge.*.*"/>
|
||||
<aop:aspectj-autoproxy proxy-target-class="true"/>
|
||||
<context:component-scan base-package="com.educoder.bridge.*.*">
|
||||
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
|
||||
</context:component-scan>
|
||||
|
||||
<!-- freemaker配置 -->
|
||||
<bean id="freemarkerConfig"
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
<configuration scan="true" scanPeriod="1 minutes">
|
||||
<property name="log_path" value="${catalina.home}/logs/"/>
|
||||
|
||||
<!-- 日志按天生成 -->
|
||||
<appender name="bridge" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<encoder>
|
||||
<pattern>%d{MM-dd HH:mm:ss} [%X{sec_key}] [%thread] %-5level -- %msg%n</pattern>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log_path}bridge.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!-- 输入到logstash -->
|
||||
<appender name="bridge" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<destination>10.9.81.28:9998</destination>
|
||||
<!--<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />-->
|
||||
<encoder>
|
||||
<pattern>%d{MM-dd HH:mm:ss} [%X{sec_key}] [%thread] %-5level -- %msg%n</pattern>
|
||||
</encoder>
|
||||
|
@ -21,6 +32,7 @@
|
|||
<root>
|
||||
<level value="DEBUG"/>
|
||||
<appender-ref ref="bridge"/>
|
||||
<appender-ref ref="stash" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -2,13 +2,14 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
|
||||
<!--指明 controller 所在包,并扫描其中的注解-->
|
||||
<context:component-scan base-package="com.educoder.bridge.*.controller"/>
|
||||
|
||||
<aop:aspectj-autoproxy proxy-target-class="true" />
|
||||
|
||||
<!-- 静态资源(js、image等)的访问 -->
|
||||
<mvc:default-servlet-handler/>
|
||||
|
||||
|
|
Loading…
Reference in New Issue