为什么有时读取千分尺测量结果会返回NaN?

时间:2019-07-04 13:39:48

标签: java spring-boot micrometer spring-micrometer

我正在尝试以编程方式读取仪表,如下所示:

获取注册表:

MeterRegistry registry = Metrics.globalRegistry.getRegistries().iterator().next();

读取测量值:

    double systemCpuUsage = registry.get("system.cpu.usage").gauge().measure().iterator().next().getValue();

问题是有时我会得到NaN

我在文档中读到了以下内容:Why is my Gauge reporting NaN or disappearing?

但是我不确定该怎么做。另外,我正在阅读Spring Boot执行器的“内置”量规(由management.metrics.enable.process.cpu.usage=true公开),因此无法更改其构造。

2 个答案:

答案 0 :(得分:3)

这是由于千分尺在量规中使用了“弱参考”。由于量规对对象没有严格的引用,因此当对象被垃圾回收时,该值将变为NaN

如果您确实控制了量规的创建,则需要自己存储参考,或在量规上调用strongReference(true)

如果您遇到内置的Spring Boot压力表,我相信您会遇到错误。这很奇怪,因为创建该量具的ProcessorMetrics活页夹拥有自己的参考(尽管它可以为空)。

看到NaN时,您是否正在其他JVM或运行时环境上运行?

答案 1 :(得分:2)

在这种情况下,由于您使用的是“内置”指标,因此可以覆盖io.micrometer.core.instrument.binder.MeterBinder#bindTo,使用自定义MeterBinder实现重新定义system.cpu.usage,并将system.cpu.usage定义为(以及您使用的其他人

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);
例如,

请参考io.micrometer.core.instrument.binder.system.ProcessorMetrics,以对其进行定义。

ProcessorMetrics上的bean是在org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration中定义的,您也需要在某个地方定义bean。 (或标记@Component)

如果您不想依靠某个千分尺预定义的度量标准,例如要捕获一些自定义列表大小,那么您可以这样做。

private static Map<String, Long> strongRefGauge = new ConcurrentHashMap<>();

要添加值,请执行以下操作

registry.gauge("CustomListSizeGuage", getMyCustomGuageTagsFor("myListName"), strongRefGauge, g -> g.get("myListName")).put("myListName", list.size());