Today, I've stumbled over this issue:
https://github.com/micrometer-metrics/micrometer/issues/780
It seems that this happens not only when annotating controller methods with @Timed but also when annotating Spring Data repositories (and possibly other beans).
Is there some way for Spring Boot to prevent this?
Comment From: wilkinsona
Unfortunately, I don't think there's anything that Boot can do here as it doesn't have the necessary information to detect a double registration. To do so, it would have to:
- Detect
@Timedon a method - Detect that the
TimedAspectis in play - Know that the annotated method is also instrumented by the underlying framework
1 is possible. 2 is harder as it relies both on a TimedAspect bean and the necessary AOP machinery being in place. 3 is the real stumbling block as it isn't possible without coupling Boot more tightly than we would like to behavior in Spring MVC, Spring Data, etc.
If you've opted into using @Timed (or @Counted), you may also want to consider defining TimedAspect yourself with a predicate that performs your desired filtering, as described in this comment from @jonatan-ivanov.
Comment From: helpermethod
Hi @wilkinsona,
thanks for the detailed answer, that makes sense.
I've used the predicate workaround to solve this issue, but it took me quite a while to find out what the actual problem was. Maybe the metrics chapter @Timed usage should link to the workaround / give some hints. Wdyt?
Comment From: wilkinsona
Yes, I think we could add something to https://docs.spring.io/spring-boot/3.3/reference/actuator/metrics.html#actuator.metrics.supported.timed-annotation. Thanks for the suggestion.
Comment From: jonatan-ivanov
FWIW, I think by adding @Timed/@Observed/etc. to something that is already instrumented out of the box, (without disabling that instrumentation) you are explicitly asking for double instrumentation (built-in + annotation).
Also, since annotating a controller method with @Timed/@Observed/etc. is technically not exactly the same (Spring Framework instruments these on the ServletFilter level), this "double instrumentation" could be a ~valid use-case if you want to distinguish between just the method call and the method call + Spring overhead.
Because of these, I think Boot should not do anything but making it easy to turn auto-instrumentation on/off (this is already happening).
@wilkinsona For the doc change, could you please also consider @Counted, @Observed, and @NewSpan next to @Timed?