To support production of metrics in OTLP format by our microservices, we are considering using the following libraries:
- org.springframework.boot:spring-boot-actuator-autoconfigure
- io.micrometer:micrometer-registry-otlp
We are currently using Spring Boot 3.2.4.
In some microservices, we noticed that the bean org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor (created by org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration) is created after the bean OtlpMeterRegistry (created by org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration).
As a result, post-processing done by MeterRegistryPostProcessor is not applied on this meter registry, namely:
- add meter filters (e.g. PropertyMeterFilter based on properties management.metrics.enabled.*)
- apply meter registry customizers
- apply meter binders (all beans implementing MeterBinder interface)
We only notice it on some internal projects that I can't share. I was not able to create a simple reproducer project to reproduce it.
Since MeterRegistryPostProcessor is currently package-private, we can't force its creation early at application startup.\ Could you consider making MeterRegistryPostProcessor public ?
Could you consider adding a MeterRegistryPostProcessor as argument of constructor of OtlpMetricsExportAutoConfiguration to ensure that it is always created before OtlpMeterRegistry ? Same would be required for other MetricsExportAutoConfiguration classes to ensure that it works for other meter registries.
If you agree with one of the propositions below, I can contribute to the resolution of the issue.
Comment From: wilkinsona
Could you consider adding a MeterRegistryPostProcessor as argument of constructor of OtlpMetricsExportAutoConfiguration
Unfortunately, I don't think we can justify doing that without fully understanding the problem as this sort of change is likely to mask an underlying issue. It sounds like something is creating the OtlpMeterRegistry too early, and before all bean post-processors have been created. If I am right, it's this that should be addressed to resolve the problem.
Ideally, you'd share a sample that reproduces the problem. If that's not possible, please share the log output of your application when it's starting up. The default info level may be sufficient to point us in the right direction. Debug logging would be even better as it should identify the names of the beans that are being created and that are triggering the early creation of the OtlpMeterRegistry bean.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Comment From: fstaudt
@wilkinsona ,
sorry for not replying before.
We identified the root cause of the issue in one of our internal libraries.
A MeterRegistry was expected in constructor of one of our classes annotated with @Configuration.\ The registy injected via constructor was used in multiple methods to create multiple beans:
@Configuration(proxyBeanMethods = false)
class MyConfiguration(private val meterRegistry: MeterRegistry) {
@Bean
fun bean1(): MyBean {
return MyBean(meterRegistry)
}
@Bean
fun bean2(): MyBean {
return MyBean(meterRegistry);
}
}
I assume that the injection in constructor was causing the early instantiation of the MeterRegistry (before post processor).\ Issue was fixed by moving MeterRegistry injection to each method:
@Configuration(proxyBeanMethods = false)
class MyConfiguration {
@Bean
fun bean1(meterRegistry: MeterRegistry): MyBean {
return MyBean(meterRegistry)
}
@Bean
fun bean2(meterRegistry: MeterRegistry): MyBean {
return MyBean(meterRegistry);
}
}