如何使用Spring Boot和Micrometer创建定制量规?

时间:2019-07-29 20:17:04

标签: spring-boot prometheus micrometer

我写了一个Spring Boot应用程序,我想用Micrometer向Prometheus公开自定义指标。这是一个代码段,在这里我要增加一个计数器(有效)并尝试设置几个仪表(无效):

@Scheduled(cron = "*/2 * * * * *") // run every 2 seconds
private void logTemperature() throws UnknownHostException {

    // get measurement
    SensorReader sensorReader = new SensorReader();
    SensorReading sensorReading = sensorReader.getSensorReading();

    Metrics.counter("measurements").increment();
    Metrics.gauge("fahrenheit", sensorReading.getFahrenheit());
    Metrics.gauge("humidity", sensorReading.getHumidity());

    // do stuff with measurement
    // ...

}

完整的源代码在这里:https://github.com/alexwoolford/htu21d_logger/tree/master/htu21d-logger-spring

fahrenheit对象中的sensorReading字段是float。量规存在于输出中,但是值是NaN(即不是数字):

# HELP measurements_total  
# TYPE measurements_total counter
measurements_total 82.0
...
# HELP humidity  
# TYPE humidity gauge
humidity NaN
...
# HELP fahrenheit  
# TYPE fahrenheit gauge
fahrenheit NaN
...

我见过类似的帖子,例如Micrometer/Prometheus How do I keep a gauge value from becoming NaN?Micrometer - Prometheus Gauge displays NaN,但是我无法从这些答案中找出具体需要做的事情。

我还尝试创建一个变量,并使用lambda更新该变量,例如

Metrics.gauge("humidity", humidity, humidity -> sensorReading.getHumidity());

...并且指示符完全消失(甚至没有NaN)。

此问题与其他问题略有不同,因为我没有使用缓存,而是尝试使用全局注册表,这大概是最简单的选择。

1 个答案:

答案 0 :(得分:3)

您正在使用的对象正在被垃圾回收,因为注意会保留这些值的引用。仪表默认使用弱引用。

如果将其设置为使用强引用,则应避免使用NaN。不幸的是,全球注册表帮助者没有公开量规构建器,因此您需要稍微不同地创建量规。

Gauge.builder("humidity", humidity, humidity -> sensorReading.getHumidity()).strongReference(true).register(Metrics.globalRegistry);

作为一个旁注,除非传感器读数本来就很慢,否则我建议不要使用@Scheduled方法。如果SensorReader是线程安全的,则可以删除@Scheduled并直接使用SensorReader

SensorReader sensorReader = new SensorReader();

Gauge.builder("humidity", sensorReader, sensorReader -> 
  sensorReader.getSensorReading().getHumidity())
  .strongReference(true)
  .register(Metrics.globalRegistry);
Gauge.builder("fahrenheit", sensorReader, sensorReader -> 
  sensorReader.getSensorReading().getFahrenheit())
  .strongReference(true)
  .register(Metrics.globalRegistry);

这样,您只需要查看传感器读数即可了解普罗米修斯抓取指标的速度。