Repository navigation
1.18 Migration Guide
AtlasMeterRegistry now publishes FunctionTimer statistics (statistic=count and statistic=totalTime) as per-second rates (atlas.dstype=rate) rather than gauges, aligning them with standard Timer and FunctionCounter behavior in Atlas.
Previously, AtlasMeterRegistry registered FunctionTimer through the generic newMeter path, which published the measurements as gauges (atlas.dstype=gauge). The reported values were deltas over the step interval (1 minute by default) rather than per-second rates:
-
statistic=countwas reported as total events per step interval (e.g., requests per minute). -
statistic=totalTimewas reported as total seconds per step interval (e.g., seconds of work per minute). - The values were ~60x higher (with a 1-minute step) than a native Spectator
Timeror a standard MicrometerTimer. - Because they were typed as gauges, Atlas averaged them rather than normalizing them when consolidating across time into larger step intervals.
Starting with Micrometer 1.18.0:
-
statistic=countis polled viaPolledMeter.monitorMonotonicCounterand published as an event rate per second. -
statistic=totalTimeis polled viaPolledMeter.monitorMonotonicCounterDoubleand published as total seconds per second. - Idle
FunctionTimerinstances whose referenced objects have been garbage collected will now expire aftermeterTTLrather than continuing to report0indefinitely.
This affects every meter binder backed by a FunctionTimer, including Tomcat request metrics (tomcat.global.request, tomcat.servlet.request), Jetty request timers, and cache, executor, and Hibernate timers.
-
Dashboards and Alerts: If you have Atlas queries or alert rules that divided
FunctionTimervalues by 60 (or your configured step interval in seconds) to compute a rate, remove that division. -
Scale Adjustment: With the default 1-minute step, published
countandtotalTimevalues will be ~60x lower than in previous releases. -
Latency Expressions: Expressions calculating average latency (
statistic=totalTime / statistic=count) are unaffected because the rate scaling factors cancel out.
In Micrometer 1.18.0, PrometheusMeterRegistry (for Prometheus Java Client 1.x, micrometer-registry-prometheus) validates metric family descriptors at meter registration time rather than during scrape collection.
Previously, if different meters mapped to the same Prometheus metric family name (for example, registering a Timer("test") which generates test_seconds_max along with a separate Gauge("test_seconds_max")), both meters were accepted at registration time, but subsequent calls to scrape() would fail with a DuplicateLabelsException.
In 1.18.0, the Prometheus client detects the duplicate metric family name during registration and fails to register meters that would conflict after the first:
- By default, the duplicate meter registration fails gracefully: a warning is logged and the duplicate meter is discarded. Subsequent scrapes succeed and export only the originally registered meter's metrics.
- If you configured
registry.throwExceptionOnRegistrationFailure()or anonMeterRegistrationFailedcallback onregistry.config(), the failure occurs immediately upon calling.register(...)instead of when Prometheus scrapes the endpoint.
In Prometheus, all time series sharing the same metric name must produce the same metric family type. In Micrometer's Prometheus registry, a Timer or DistributionSummary produces a SUMMARY by default, or a HISTOGRAM if percentile histograms or SLO buckets are configured.
In 1.17, registering meters with the same name where only some configured histogram buckets succeeded at registration time but failed with an unhandled ClassCastException when scraping the Prometheus endpoint.
In 1.18.0:
- Metric family types are validated eagerly when meters are registered.
- If a
TimerorDistributionSummaryis registered whose histogram configuration conflicts with an already-registered meter of the same name:-
Default behavior: A warning log explains that meters with the same name must produce the same family type (e.g.
SUMMARYvsHISTOGRAM). The conflicting meter is ignored, preventing the scrape endpoint from failing. -
When
throwExceptionOnRegistrationFailure()is enabled: AnIllegalArgumentExceptionis thrown immediately upon calling.register(...).
-
Default behavior: A warning log explains that meters with the same name must produce the same family type (e.g.
Review your Timer and DistributionSummary configurations to ensure meters sharing the same name configure histograms consistently across all tag sets:
- Ensure that any
MeterFilterconfiguring histogram buckets (such aspublishPercentileHistogram(),serviceLevelObjectives(), or min/max expected values) matches all meters for a given metric name rather than a subset based on specific tag values. - Ensure application code and
@Timed(histogram = ...)annotations consistently enable or disable histograms across different registration sites for the same metric name.