When I'm attempting to create a DistributionSummary instance with a minimum expected value or Service Level Objective (SLO) of 0.0, I encounter the exceptions below.
However, when I use distributionSummary.record(0.0), 0.0 is accepted without throwing an exception. What's the reason for this (seems to be) inconsistent behavior?
Here we're primarily utilizing this DistributionSummary for integer values, without fractional parts. Using, for example, 0.001 for minimumExpectedValue and SLO works but seems unconventional.
Sample code:
final PrometheusMeterRegistry registry =
new PrometheusMeterRegistry(PrometheusConfig.DEFAULT).throwExceptionOnRegistrationFailure();
final DistributionSummary distributionSummary = DistributionSummary.builder("my_metric")
.minimumExpectedValue(0.0)
.maximumExpectedValue(100.0)
.publishPercentileHistogram()
.serviceLevelObjectives(0.0, 1, 2, 5, 10, 20, 50, 100)
.baseUnit("listeners")
.register(registry);
distributionSummary.record(0.0);
System.out.println(registry.scrape());
.minimumExpectedValue(0.0) throws this:
io.micrometer.core.instrument.config.InvalidConfigurationException: Invalid distribution configuration: minimumExpectedValue (0.0) must be greater than 0.
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.rejectConfig(DistributionStatisticConfig.java:503)
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.validate(DistributionStatisticConfig.java:478)
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.build(DistributionStatisticConfig.java:460)
at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:418)
at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:413)
....
.serviceLevelObjectives(0, ...) throws this:
io.micrometer.core.instrument.config.InvalidConfigurationException: Invalid distribution configuration: serviceLevelObjectiveBoundaries must contain only the values greater than 0. Found 0.0
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.rejectConfig(DistributionStatisticConfig.java:503)
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.validate(DistributionStatisticConfig.java:495)
at io.micrometer.core.instrument.distribution.DistributionStatisticConfig$Builder.build(DistributionStatisticConfig.java:460)
at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:418)
at io.micrometer.core.instrument.DistributionSummary$Builder.register(DistributionSummary.java:413)
...
Used dependencies:
micrometer-core:1.12.3micrometer-registry-prometheus:1.11.3
From what I can see, the Micrometer's
DistributionSummaryis designed to measure the distribution of events, such as request sizes or method execution times. Both the minimum expected value and SLOs are used to configure how this distribution is analyzed and reported.The configuration phase enforces that both the minimum expected value and SLOs are greater than
0.0.I suspect it reflects the intention to measure and analyze positive distributions, where a
0.0might represent either an absence of measurement or an edge case not intended for typical statistical analysis.Recording a value of
0.0is allowed because it is considered a valid measurement, representing the lower bound of what can be recorded.That capability makes sure use cases requiring the tracking of zero values (e.g., no resource usage, immediate response times) are supported.
This distinction exists because:
As you have noted, setting the minimum expected value or SLOs to a small, positive value (like
0.001) is a workaround. While it might feel unconventional, it aligns with the framework's constraints and still allows you to capture the range of values you are interested in.If the above adjustment does not meet your needs (perhaps because treating
0.0as a special case is critical to your application's metrics analysis) then you might need to explore other options.either use other metrics collection and analysis systems (InfluxDB, Graphite, StatsD, Datadog, ...).
or implement custom metrics handling within your application. That could involve using basic Micrometer metrics types (like counters and gauges) in a custom way to track and analyze
0.0values explicitly. For example, you could use a separate counter to track occurrences of0.0and other metrics to capture the rest of the distribution.