Home/Learn/Spring Boot/Metrics with Micrometer

Metrics with Micrometer

Advanced
Actuator & Ops

Micrometer provides a vendor-neutral metrics facade; counters, gauges, and timers feed Prometheus, Datadog, or CloudWatch with dimensional time-series data.

Overview

Micrometer is the metrics instrumentation library bundled with Spring Boot Actuator. It provides a vendor-neutral facade — you instrument your code once using `Counter`, `Timer`, `Gauge`, and `DistributionSummary`, then configure any backend registry (Prometheus, Datadog, CloudWatch, InfluxDB) without changing instrumentation code. `spring-boot-actuator` auto-instruments JVM metrics, HTTP request latency, HikariCP pool stats, Kafka consumer lag, and more. You add custom business metrics (order count, payment latency) by injecting `MeterRegistry`. Metrics are exposed at `/actuator/prometheus` (with `micrometer-registry-prometheus`) and scraped by Prometheus every 15–30 seconds.

Counter, Timer, and Gauge

`Counter` tracks a monotonically increasing count (orders placed, errors). `Timer` measures call duration and count simultaneously (payment API latency). `Gauge` tracks a current value that can go up or down (queue depth, active sessions). Always add **tags** (dimensions) to slice metrics by meaningful attributes — `status`, `region`, `service`. Tags are key-value pairs that become Prometheus labels.

Spring Boot — Counter, Timer, and Gauge with tags
@Service
@RequiredArgsConstructor
class OrderService {
    private final MeterRegistry registry;

    // Counter — increments on each call
    public Order place(CreateOrderRequest req) {
        Order order = orderRepo.save(new Order(req));
        registry.counter("orders.placed",
            "status",   "success",
            "region",   req.getRegion()
        ).increment();
        return order;
    }

    // Timer — records duration + count
    public PaymentResult charge(Order order) {
        return Timer.builder("payment.latency")
            .tag("provider", "stripe")
            .register(registry)
            .record(() -> stripeClient.charge(order));
    }
}

// Gauge — tracks a current value (register once, reads lambda on each scrape)
@Bean
MeterBinder queueDepthGauge(OrderQueue queue) {
    return registry -> Gauge.builder("orders.queue.depth", queue, OrderQueue::size)
            .description("Current orders waiting to be processed")
            .register(registry);
}

Prometheus Scraping and Actuator Endpoint

Add `micrometer-registry-prometheus` to expose `/actuator/prometheus`. Configure Prometheus to scrape this endpoint. The Prometheus naming convention converts Micrometer names: `orders.placed` → `orders_placed_total` (counter), `payment.latency` → `payment_latency_seconds_*` (histogram). Spring Boot auto-instruments dozens of metrics out of the box.

Spring Boot — Prometheus endpoint + auto-instrumented metrics
<!-- pom.xml -->
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

# application.properties
management.endpoints.web.exposure.include=prometheus,health,info
management.metrics.tags.application=order-service   # global tag on all metrics
management.metrics.tags.environment=production

# Auto-instrumented metrics (no code required):
# http.server.requests           — HTTP request latency + status
# hikaricp.connections.*         — connection pool stats
# jvm.memory.used                — heap/non-heap usage
# jvm.gc.pause                   — GC pause durations
# process.cpu.usage              — CPU utilisation
# kafka.consumer.fetch.latency.avg — Kafka consumer fetch time

# Prometheus scrape config
scrape_configs:
  - job_name: order-service
    metrics_path: /actuator/prometheus
    static_configs:
      - targets: ['order-service:8080']

Custom Annotations and @Timed

`@Timed` on a controller or service method auto-records a `Timer` metric without boilerplate. For more control, `@Counted` increments a counter on each invocation. Use `MeterBinder` for infrastructure metrics (external queue depth, cache size) so they are registered at the right lifecycle phase rather than on first request.

Spring Boot — @Timed annotation and Grafana PromQL
// @Timed — auto-instruments method execution time
@RestController
class OrderController {

    @PostMapping("/orders")
    @Timed(value = "orders.create", extraTags = {"endpoint", "create-order"},
           description = "Time to create an order")
    ResponseEntity<Order> create(@RequestBody CreateOrderRequest req) {
        return ResponseEntity.status(201).body(orderService.place(req));
    }
}

// Grafana dashboard PromQL queries:
// Request rate (per second, 5m window)
rate(orders_placed_total[5m])

// P99 HTTP latency (Spring Boot auto-instruments http.server.requests)
histogram_quantile(0.99,
  rate(http_server_requests_seconds_bucket{uri="/orders",method="POST"}[5m]))

// Error rate
rate(http_server_requests_seconds_count{status=~"5.*"}[5m])
  / rate(http_server_requests_seconds_count[5m])

// Alert: error rate > 1%
- alert: HighErrorRate
  expr: |
    rate(http_server_requests_seconds_count{status=~"5.*"}[5m])
    / rate(http_server_requests_seconds_count[5m]) > 0.01
  for: 2m

Key Points to Remember

  • 1Micrometer is a vendor-neutral facade — same code instruments Prometheus, Datadog, CloudWatch
  • 2Counter: monotonically increasing (events); Timer: duration + count; Gauge: current snapshot value
  • 3Always add tags (dimensions) to slice metrics by status, region, service, method
  • 4/actuator/prometheus exposes metrics for Prometheus scraping (requires micrometer-registry-prometheus)
  • 5Spring Boot auto-instruments HTTP, JVM, HikariCP, Kafka — dozens of metrics with zero code
  • 6management.metrics.tags.application=name adds a global tag to every metric from this service

Interview Questions

Sign in to ask Aria
1

What is the difference between a Counter, Timer, and Gauge in Micrometer?

EasyThoughtWorks
2

Why should you always add tags to Micrometer metrics?

MediumNetflix
3

How does Micrometer allow you to switch from Prometheus to Datadog without changing instrumentation code?

MediumPivotal
4

Write a PromQL expression to calculate the P99 latency of POST /orders over the last 5 minutes.

HardAmazon
5

What metrics does Spring Boot auto-instrument without any custom code?

EasyAccenture

Ask Aria about Metrics with Micrometer

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…