I'm trying to apply Prometheus metrics using the micrometer @Timed
annotations.
I found out that they only work on controller endpoints and not "simple" public and private methods.
Given this example:
@RestController
public class TestController {
@GetMapping("/test")
@Timed("test-endpoint") //does create prometheus metrics
public String test() {
privateMethod();
publicMethod();
return "test";
}
@Timed("test-private") //does NOT create prometheus metrics
private void privateMethod() {System.out.println("private stuff");}
@Timed("test-public") //does NOT create prometheus metrics
public void publicMethod() {System.out.println("public stuff");}
}
creates the following metrics:
...
# HELP test_endpoint_seconds
# TYPE test_endpoint_seconds summary
test_endpoint_seconds_count{,exception="none",method="test",} 1.0
test_endpoint_seconds_sum{,exception="none",method="test",} 0.0076286
# HELP test_endpoint_seconds_max
# TYPE test_endpoint_seconds_max gauge
test_endpoint_seconds_max{,exception="none",method="test",} 0.0076286
...
No metrics found for @Timed("test-private")
and @Timed("test-public")
, why is that?
Note: I've read on this github thread, that Spring Boot does not recognize @Timed
annotations on arbitrary methods and that you need to manually configure a TimedAspect
Bean in order for it to work. I've tried that but still it yields no results.
@Configuration
@EnableAspectJAutoProxy
public class MetricsConfig {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
To try this locally see necessary gist here
CodePudding user response:
@Timed works only on public methods called by another class.
Spring boot annotations like @timed / @transactional need the so called proxying that happens only between invocation of public methods.
A good explanation is this one https://stackoverflow.com/a/3429757/2468241