Hi,
I'm using micrometer 1.5.0 with spring boot 2.2.6, but without web/actuator.
I took a usage example from your documentation and adapted it to run inside Spring.
Config:
@Configuration
public class MetricsConfig {
@Bean
public PrometheusMeterRegistry getMeterRegistry() {
final var registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
registry.config().commonTags("application", "app_name");
new ClassLoaderMetrics().bindTo(registry);
new JvmMemoryMetrics().bindTo(registry);
new JvmGcMetrics().bindTo(registry);
new ProcessorMetrics().bindTo(registry);
new JvmThreadMetrics().bindTo(registry);
new UptimeMetrics().bindTo(registry);
return registry;
}
}
Service:
@Service
public class Micrometer {
private final PrometheusMeterRegistry registry;
public Micrometer(final PrometheusMeterRegistry registry) {
this.registry = registry;
}
@PostConstruct
public void start() {
try {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/prometheus", httpExchange -> {
String response = registry.scrape();
httpExchange.sendResponseHeaders(200, response.getBytes().length);
try (OutputStream os = httpExchange.getResponseBody()) {
os.write(response.getBytes());
}
});
new Thread(server::start).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Some time after starting the application, during the creation of the PrometheusTimer, an error occurs:
06.05. 14:09:31 [task-scheduler-1] E o.s.i.h.LoggingHandler.handleMessageInternal:187 - java.lang.NoSuchMethodError: 'io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.sla(double[])'
at io.micrometer.prometheus.PrometheusTimer.<init>(PrometheusTimer.java:45)
at io.micrometer.prometheus.PrometheusMeterRegistry.newTimer(PrometheusMeterRegistry.java:192)
at io.micrometer.core.instrument.MeterRegistry.lambda$timer$2(MeterRegistry.java:271)
at io.micrometer.core.instrument.MeterRegistry.getOrCreateMeter(MeterRegistry.java:575)
at io.micrometer.core.instrument.MeterRegistry.registerMeterIfNecessary(MeterRegistry.java:529)
at io.micrometer.core.instrument.MeterRegistry.timer(MeterRegistry.java:269)
at io.micrometer.core.instrument.Timer$Builder.register(Timer.java:473)
I tried different versions, this error appeared in version 1.4.0.
In this version, in the PrometheusTimer constructor, you added an argument to the .sla() method call using an array of double, while the method expects an array of long, in version 1.3.8 the method is called without arguments.
Thanks in advance
@Comrada It seems to me that you may have a version misalignment in your runtime classpath, different versions of micrometer-registry-prometheus and micrometer-core. Can you output ./gradlew dependencyInsight micrometer or the equivalent for Maven?
@jkschneider yes you're right, the versions are different:
> Task :dependencyInsight
io.micrometer:micrometer-core:1.3.6 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.version = 11
]
io.micrometer:micrometer-core:1.5.0 -> 1.3.6
\--- io.micrometer:micrometer-registry-prometheus:1.5.0
\--- compileClasspath
io.micrometer:micrometer-registry-prometheus:1.5.0 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.version = 11
]
io.micrometer:micrometer-registry-prometheus:1.5.0
\--- compileClasspath
But this old dependency of the "micrometer-core" is pulled automatically by the "micrometer-registry-prometheus" module, I do not explicitly include the "micrometer-core" anywhere.
I took an example from your documentation.
compile 'io.micrometer:micrometer-registry-prometheus:latest.release'
After I plug the micrometer-core module with the same version, everything works, even the bug that I created in the next thread.
So, what's the problem after all? Maybe you should add this to the documentation or update the dependency in the micrometer-registry-prometheus module?
@Comrada The old version isn't actually depended on by micrometer-registry-prometheus, it's the annoying behavior of the io.spring.dependency-management plugin which is forcing down the version of micrometer-core to the version _it_ expects unless there is a first-level dependency on it with a different version.
The Spring team continues to try to make Gradle behave like Maven, and this the consequence...
@Comrada You can use micrometer.version property to control the version. See the relevant section in the Spring Boot Gradle Plugin Reference Guide for details.
Most helpful comment
@Comrada You can use
micrometer.versionproperty to control the version. See the relevant section in the Spring Boot Gradle Plugin Reference Guide for details.