Issue
I'm trying to programmatically read the Meters as follows:
Get registry:
MeterRegistry registry = Metrics.globalRegistry.getRegistries().iterator().next();
Read measurement:
double systemCpuUsage = registry.get("system.cpu.usage").gauge().measure().iterator().next().getValue();
The problem is that sometimes I get NaN
.
I read about this in the docs: Why is my Gauge reporting NaN or disappearing?
but I'm not sure what I shall do. Also, I'm reading the "built-in" gauge of Spring Boot actuator (which is exposed by management.metrics.enable.process.cpu.usage=true
) so I cannot change it's construction.
Solution
In this case, since you are using a "built in" metric, you can override io.micrometer.core.instrument.binder.MeterBinder#bindTo
, redefine system.cpu.usage
with a a custom MeterBinder implementation, and defining system.cpu.usage as (along with others which you use)
Gauge.builder("system.cpu.usage", operatingSystemBean, x -> invoke(systemCpuUsage))
.strongReference(true)//Add strong reference
.tags(tags)
.description("The recent cpu usage for the whole system")
.register(registry);
Refer io.micrometer.core.instrument.binder.system.ProcessorMetrics
for example which defines it as of now.
The bean on ProcessorMetrics is defined in org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration
, you need to define your bean too somewhere. (or mark @Component)
If you don't want to rely on some predefined metric by micrometer, like to capture some custom list size, this is what you can do.
private static Map<String, Long> strongRefGauge = new ConcurrentHashMap<>();
For adding values do the following
registry.gauge("CustomListSizeGuage", getMyCustomGuageTagsFor("myListName"), strongRefGauge, g -> g.get("myListName")).put("myListName", list.size());
Answered By - Sumeet Mondal
Answer Checked By - Candace Johnson (JavaFixing Volunteer)