Why do reading Micrometer measurement returns NaN sometimes?

我们两清 提交于 2019-12-12 20:06:48

问题


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.


回答1:


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());



回答2:


This is due to Micrometer using 'weak references' in gauges. Since the gauge doesn't hold a strong reference to the object, when the object is garbage collected, the value becomes NaN.

If you did control the gauge creation you would want to store a reference yourself, or call strongReference(true) on the gauge.

If you are encountering with the built in Spring Boot gauges, I believe you are running into a bug. Which is very strange since the ProcessorMetrics meter binder that creates that gauge holds its own reference (though it is nullable).

Are you running on a different JVM or Runtime environment when you see the NaN?



来源:https://stackoverflow.com/questions/56889240/why-do-reading-micrometer-measurement-returns-nan-sometimes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!