How to create a Gauge metric with tags using Java prometheus sdk?
Asked Answered
E

3

6

I have a springboot Kotlin web service that uses Actuator (spring-boot-starter-actuator) and micrometer (micrometer-registry-prometheus) to expose metrics to a prometheus scraper.

To monitor the size of operations in a queue I use a custom Gauge

val gauge = Gauge.build()
        .name("operation_queue_size")
        .help("Size of queue")
        .register(collectorRegistry)

# later
gauge.inc()
# or
gauge.dec()

I would like to improve this metric adding a tag that represents the type of the operation in the queue, but didn't find any appropriate method on the Builder class.

The goal would be to expose a metric like:

operation_queue_size{op_type="deletions"} 999
operation_queue_size{op_type="insertions"} 999

Thanks.

Excide answered 26/3, 2020 at 13:15 Comment(0)
C
6

There are two ways of creating gauges:

Micrometer Core

With Micrometer you can create Gauge from the object method you want to check for example from baeldung:

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;

List<String> list = new ArrayList<>(4);

Gauge gauge = Gauge
  .builder("cache.size", list, List::size)
  .tags("example", "list size")
  .register(registry);

It takes a string "cache.size" for the name of the Gauge, an object list and a lambda (() -> Double) here it's list::size. And the Gauge will be updated thanks to that.

Then the gauge gets updated each time automatically (here is an example with the assert, of what the value would be):

assertEquals(0.0, gauge.value());
list.add("1");
assertEquals(1.0, gauge.value());

Prometheus Client

With the prometheus sdk it's:

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;

Gauge gauge = Gauge.build()
        .build("cache.size", "size of the cache")
        .labelNames("type")
        .register(collectorRegistry);

But then you will need to manually change the gauge value doing:

# Increase
gauge.labels("list size").inc();
# Decrease
gauge.labels("list size").dec();
# Set value
gauge.labels("list size").set(list.size());

Now you have the choice.

Cellaret answered 10/12, 2020 at 17:46 Comment(0)
E
5

I found the solution:

val gauge = Gauge.build()
        .name("ic_queue_size")
        .help("Size of queue")
        .labelNames("op_type")
        .register(collectorRegistry)

# later
gauge.labels("deletions").inc()
# or
gauge.labels("deletions").dec()

The reason why was hard to find is that this library uses the term labels while the prometheus documentation refers to them as tags

Excide answered 26/3, 2020 at 13:27 Comment(0)
D
0

example for the micrometer statsd:

import io.micrometer.core.instrument.*;
import io.micrometer.statsd.StatsdMeterRegistry;

//...

Map<String, Long> metrics = new HashMap<>();
metrics.put("brand1", 4l);
metrics.put("brand2", 4l);


for (Map.Entry<String, Long> entry : metrics.entrySet()) {
    String key = entry.getKey();
    Tags tag = Tags.of("brand", key);
    Gauge.builder("app.metrics", metrics, map -> map.get(key))
            .tags(tag)
            .register(statsdMeterRegistry);
}
Defile answered 8/9, 2023 at 16:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.