title: Most efficient way to track execution time of methods in REST API? (Java Spring Boot app, Swagger)
body: <p>I have a Java Spring Boot API (Swagger) that I is having thousands of calls on it daily. I wanted to log the execution times of these methods for analysis. I used Spring AOP (Aspect Orientated Programming) to make a simple interface and concrete class that allows me to annotate my methods with @TrackExecutionTime to see the runtime. I have listed the code for that below. My problem is, that in the logs, I am tracking the method call times, but I have thousands of requests, so I need a way of &quot;tagging&quot; each api call and logging it, so I can follow the flow of each api call. I was thinking of generating a random # or maybe someone here had a better suggestion. So the logging currently looks like this:
  <code>&quot;com.mypackage.myclassname.mymethodname. Time taken for Execution is : 100ms&quot;</code></p>
  <p>Also, My first RestController uses Swagger, so I tried to annotate the method with my @TrackTimeExecution, but we are using the <strong>swagger-codegen-maven</strong> plugin, so it reads the swagger definition yaml file and generates the &quot;CustomerApi&quot; and other classes/interfaces when it compiles. When I tried annotating at the class level per below, the Spring Boot app compiles, but when I run the app locally on port 8080 and try to hit the endpoint I annotated with Postman, nothing happens at all. It's like annotating breaks the swagger codegen or something, so I had to settle with sticking the annotation on the customersService.getCustomers() method. Is this acceptable? I figured I would need to clock the execution from when the Controller first gets hit, but as I said,  I coudln't do it this way unless I'm making some dumb mistake, so I had to put it on the <em>next</em> method the controller calls. Does this make my timing of the api call inaccurate since I would need to time in when the app first gets the request by the controller? Would love any input here...</p>
  <p>Dumbed dumb implementation of one of my endpoints, basically the same:</p>
  <pre><code>@RestController
  @TrackExecutionTime // this fails to compile
  public class CustomerApiController implements CustomerApi {
      @Autowired
      public CustomerApiController(ObjectMapper objectMapper, HttpServletRequest request) {
          this.objectMapper = objectMapper;
          this.request = request;
  }
  
  public ResponseEntity&lt;List&lt;Customer&gt;&gt; searchCustomer() {
      return new ResponseEntity&lt;List&lt;Customer&gt;&gt;(this.customerService.getCustomers(), HttpStatus.OK);
  </code></pre>
  <p>Class that logs the execution time of any method annotated with &quot;@TrackExecutionTime&quot;</p>
  <pre><code>@Aspect
  @Component
  @Slf4j
  @ConditionalOnExpression(&quot;${aspect.enabled:true}&quot;)
  public class ExecutionTimeAdvice {
  
      @Around(&quot;@annotation(com.mailshine.springboot.aop.aspectj.advise.TrackExecutionTime)&quot;)
      public Object executionTime(ProceedingJoinPoint point) throws Throwable {
          long startTime = System.currentTimeMillis();
          Object object = point.proceed();
          long endtime = System.currentTimeMillis();
          log.info(&quot;Class Name: &quot;+ point.getSignature().getDeclaringTypeName() +&quot;. Method Name: &quot;+ point.getSignature().getName() + &quot;. Time taken for Execution is : &quot; + (endtime-startTime) +&quot;ms&quot;);
          return object;
      }
  }
  </code></pre>
  <pre><code>@Target(ElementType.METHOD)
  @Retention(RetentionPolicy.RUNTIME)
  public @interface TrackExecutionTime {
  }
  </code></pre>