这可能是一个简单的解决方案,但我无法完成。 我需要在 SpringBoot Rest API 中记录我的请求的整体执行时间。 请求总是进入到
MainController
总是并且可以从两个地方退出-
Restcontroller
相同的方法或ExceptionHandlerController
处理方法我创建了一个自定义注释并将其注入主要
Controller
和ExceptionController
方法,并获取各个方法的运行时间。
所以这就是问题所在。我需要添加这些单独的时间来计算我不想要的总时间。
有没有其他方法可以轻松记录这些信息。
方面类:
@Aspect
@Component
public class PointsAspect {
private final static Logger logger = LoggerFactory.getLogger(PointsAspect.class);
@Around("@annotation(annotation)")
public Object logMethod(final ProceedingJoinPoint proceedingJoinPoint, final LogAround annotation)
throws Throwable {
final long start = System.currentTimeMillis();
Object obj;
try {
logger.debug("Starting...! Method Name - " +proceedingJoinPoint.getSignature().getName());
obj = proceedingJoinPoint.proceed();
} finally {
logger.debug("Exiting...! Method Name - " +proceedingJoinPoint.getSignature().getName() +"Execution Time in Milliseconds:> "+ String.valueOf(System.currentTimeMillis()-start));
}
return obj;
}
}
标记界面:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAround {
}
这就是我注射它的方式:
**ExceptionHandlerController.java**
@LogAround
@ExceptionHandler(HttpMessageNotReadableException.class)
public GenericFailureResponse missingRequestBodyException(HttpServletResponse response,
HttpServletRequest request, Exception ex) throws IOException {
GenericFailureResponse failureResponse = new GenericFailureResponse();
//TODO: exception logic
return failureResponse;
}
**MainController.java**
@LogAround
public String getTotalPoints(@RequestParam(required=true) long memberNo,
HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
//TODO : some logic
return "something";
}
你可以使用一个简单的过滤器。
@Component
public class LogTimeFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
long startTime = System.currentTimeMillis();
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request take " + duration + " ms");
}
}
我已经使用注释和建议解决了它。
首先需要添加这些依赖
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop然后我创建一个注释如下
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Creator : Tanvir Chowdhury
* Date : 2023-02-23
*/
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface TimeTraker {
}
然后我在advice类中写时间测量逻辑
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
/**
* Creator : Tanvir Chowdhury
* Date : 2023-02-23
*/
@Aspect
@Component
public class RequestResponseTimeTracker {
private static Logger logger = LoggerFactory.getLogger(RequestResponseTimeTracker.class);
@Around("@annotation(com.reliantvalue.lake.security.TimeTraker)")
public Object measureTime(ProceedingJoinPoint point) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object object = point.proceed();
stopWatch.stop();
logger.debug("Execution Time taken by : " + point.getSignature().getName() + "() method is - "
+ stopWatch.getTotalTimeMillis() + " ms");
return object;
}
}
就是这样。现在像这样在休息控制器上使用注释 TimeTracker
@SneakyThrows
@PostMapping
@JsonView(View.Full.class)
@TimeTraker
public Loan createLoan(@CurrentUser User user,
@RequestParam(value = "type", required = false) String type,
@RequestParam(value = "wf", required = false) String wfId,
@RequestBody LoanCreateRequestDTO loanCreateRequest) {
}
输出会是这样的
2023-02-23 17:32:36,958 INFO [http-nio-5000-exec-6] c.r.l.s.RequestResponseTimeTracker: Execution Time taken by : deleteLoan() method is - 3776 ms