Custom Micrometer Gauge Metrics

Introduction
Micrometer is a metrics facade for JVM-based applications, allowing you to instrument your code and collect application metrics in a vendor-neutral way. It provides various meter types, including gauges, counters, timers, and distribution summaries.
Custom Micrometer Gauge Metrics
A Gauge is a metric type that retrieves the current value of a variable or a function's return value. Unlike counters, which only increase, gauges can go up or down, reflecting a dynamic state.
To create a custom gauge metric in Micrometer:
Obtain a
MeterRegistry:You need an instance of
MeterRegistry, which is responsible for registering and managing your meters. In frameworks like Spring Boot, Micrometer automatically configures and provides this registry, often injectable into your components.Register the Gauge:
Use the
Gauge.builder()method to create and register your custom gauge. This builder requires a name for the metric and a function or a reference to an object from which the value will be retrieved.Provide the Value:
The gauge will call the specified function (e.g.,
MyService::getMyValuein the example) each time the monitoring system scrapes the metric, ensuring the reported value is always current. You can also directly register aSupplieror aCollectionto track their size.Add Tags (Optional):
You can add key-value pairs as "tags" to your gauge using the
.tag()method. Tags enable dimensional analysis of your metrics, allowing you to filter and group data based on specific attributes (e.g.,tag("environment", "production")).
Considerations for Custom Gauges:
Weak References:
By default, Micrometer's
Gaugeholds a weak reference to the object it's monitoring. This means the object can be garbage collected if no other strong references exist, potentially leading to the gauge disappearing. If you need the gauge to persist, ensure a strong reference to the object or configure the gauge to hold a strong reference if supported by your specific Micrometer registry implementation.High Cardinality Tags:
Be mindful of creating gauges with a large number of unique tag values (high cardinality), as this can negatively impact the performance of your monitoring system.
Dynamic Values:
Gauges are ideal for monitoring values that fluctuate over time, such as queue sizes, thread counts, or the number of active connections.
Examples
Custom Gauge for Dependencies Check
@Bean
public MeterBinder GaugeMetricsDependencyCheck(MonitorDependencyService monitorDependencyService) {
return (registry) -> Gauge.builder(
"bookingsService_checkDependencies",
() -> DependencyStatus.OK.equals(
monitorDependencyService.checkDependencies().getStatus()
) ? 1.0 : 0.0
)
.strongReference(true)
.register(registry);
}
Bean name:
GaugeMetricsDependencyCheckPurpose: Creates a Micrometer Gauge metric named
bookingsService_checkDependencies.Behavior:
Calls
monitorDependencyService.checkDependencies().getStatus()every time the gauge is scraped.If the returned status is
DependencyStatus.OK→ gauge value =1.0\ Else → gauge value =0.0.
strongReference(true)ensures the gauge isn't garbage collected by holding a strong reference.
Use case: This lets Prometheus (or any Micrometer-compatible monitoring system) see if dependencies are healthy (1) or unhealthy (0).
Custom Gauge for Scheduled Jobs Check
@Bean
public MeterBinder GaugeMetricsScheduledJobsCheck(MonitorScheduledJobService monitorScheduledJobService) {
return (registry) -> Gauge.builder(
"bookingsService_checkScheduledJobs",
() -> ScheduledJobStatus.OK.equals(
monitorScheduledJobService.checkScheduledJobs().getStatus()
) ? 1.0 : 0.0
)
.strongReference(true)
.register(registry);
}
Bean name:
GaugeMetricsScheduledJobsCheckPurpose: Creates a Micrometer Gauge metric named
bookingsService_checkScheduledJobs.Behavior:
Calls
monitorScheduledJobService.checkScheduledJobs().getStatus()when the gauge is scraped.Outputs
1.0if OK, else0.0.
Use case: Lets you monitor whether scheduled jobs in your application are running correctly.
Scrapping the Prometheous Endpoint
In order to check if your metrics are working, the simplest check you can make is to just hit the actuator endpoint prometheous uses to scrape the metrics from your system.
curl -X GET http://localhost:8080/actuator/prometheus
If all is working as expected, you should see some custom metrics showing up in the results.
... other metrics
...
# HELP bookingsService_checkDependencies
# TYPE bookingsService_checkDependencies gauge
bookingsService_checkDependencies 1.0
# HELP bookingsService_checkScheduledJobs
# TYPE bookingsService_checkScheduledJobs gauge
bookingsService_checkScheduledJobs 1.0
Conclusion
From here, you can easily create a Prometheus alert rule and Grafana panel ready to plug in these metrics so you can immediately start alerting on these gauges and be a step closer to being production ready.




