DEV Community

Nikita Blud
Nikita Blud

Posted on

Stop Writing Micrometer Boilerplate in Spring Boot

Annotation-driven Micrometer metrics for Spring Boot. Add @MetricGauge, @MetricCounter and dynamic SpEL tags with zero boilerplate. Open source Spring Boot starter
If you use Micrometer in Spring Boot you know this problem.

@Timed works great. But the moment you need a gauge you have to write this:

public OrderService(MeterRegistry registry) {
    Gauge.builder("orders.active", activeOrders, AtomicInteger::get)
         .register(registry);
}
Enter fullscreen mode Exit fullscreen mode

Inject MeterRegistry. Create a field. Write a builder. Repeat for every metric.

So I built Metrify. Let me know what do you think


What it does

Metrify is a Spring Boot starter that adds the annotations Micrometer is missing.

<dependency>
    <groupId>io.github.wtk-ns</groupId>
    <artifactId>metrify-spring-boot-starter</artifactId>
    <version>0.1.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

You don't need extra configuration of additional @Enable annotaion

@MetricGauge
java@MetricGauge(name = "orders.active")
public int getActiveOrderCount() {
    return orders.size();
}
Enter fullscreen mode Exit fullscreen mode

Works on fields too:

@MetricGauge(name = "connections.active")
private final AtomicInteger connections = new AtomicInteger(0);
Enter fullscreen mode Exit fullscreen mode

@MetricCounter

@MetricCounter(name = "orders.created")
public Order createOrder(OrderRequest request) { ... }
Enter fullscreen mode Exit fullscreen mode

Dynamic tags via SpEL

@MetricCounter(
    name = "orders.processed",
    dynamicTags = {
        @MetricTag(key = "region", expression = "#order.region")
    }
)
public void processOrder(Order order) { ... }
Enter fullscreen mode Exit fullscreen mode

@CachedGauge
For calls you do not want running on every Prometheus scrape:

@CachedGauge(name = "db.connections", ttl = 30, ttlUnit = TimeUnit.SECONDS)
public int getConnectionCount() {
    return dataSource.getActiveConnections();
}
Enter fullscreen mode Exit fullscreen mode

Startup tag validation
If you register the same metric name with different tag keys in two places. Micrometer silently fails. Metrify tells you at startup:

ERROR: Metric 'orders.processed' has inconsistent tag keys.
  OrderService   -> [region, tier]
  LegacyService  -> [region]
Enter fullscreen mode Exit fullscreen mode

One thing to know about @MetricGauge on methods
It caches the last returned value. Prometheus gets that cached value at scrape time.

If you need a true real time gauge. Use field annotation with AtomicInteger or AtomicLong instead. That is a live reference and always reflects the current value.


Metrify – annotation-driven Micrometer metrics for Spring Boot (@MetricGauge, @CachedGauge, dynamic tags)

Why Micrometer does not have this

The Micrometer team decided it should stay a low level facade. Not an annotation framework. That is a fair call. But it left a gap.
The old metrics-spring library had @Gauge and more. It has not been updated since 2016 and does not work with Spring Boot 3.
Metrify fills that gap for modern Spring Boot.

GitHub: https://github.com/wtk-ns/metrify-spring-boot-starter
Feedback and PRs are welcome.

Top comments (0)