Monitoring

Implement production monitoring for Spring Boot applications — Micrometer metrics, Prometheus integration, Grafana dashboards, and distributed tracing with Micrometer Tracing.

Last reviewed: January 2025

·Spring Boot 2.7Spring Boot 3.xMicrometer 1.12
✅
Quick Understanding: Micrometer is the metrics facade for Spring Boot (like SLF4J for logging). It collects JVM metrics, HTTP request metrics, database pool metrics, and your custom metrics. Add micrometer-registry-prometheus and /actuator/prometheus exposes all metrics in Prometheus format. Prometheus scrapes it, Grafana visualizes it.

🔍 What Is It?

Spring Boot monitoring stack:

Micrometer — metrics facade (vendor-neutral API)

Micrometer Tracing — distributed tracing (Spring Boot 3.x, replaces Sleuth)

Metrics categories:

  • →JVM metrics — heap, GC, threads, classes (auto-configured)
  • →HTTP metrics — request count, latency, error rate per endpoint
  • →DataSource metrics — HikariCP pool active/idle/waiting connections
  • →Custom metrics — business metrics (orders/minute, payment success rate)

Observability pillars:

  • →Metrics — aggregated numbers over time (Prometheus + Grafana)
  • →Logs — discrete events (ELK Stack, Splunk)
  • →Traces — request journey across services (Zipkin, Jaeger)

🎯 Why Do We Need It?

Without monitoring, you're flying blind in production:

  • →You don't know when response times degrade before users complain
  • →You can't identify which endpoint is slow
  • →You can't see database connection pool exhaustion before it causes errors
  • →You can't measure the impact of deployments on performance

🏗️ What Happens in Real Projects?

Production monitoring stack:

  • →Prometheus scrapes /actuator/prometheus every 15 seconds
  • →Grafana dashboards show: request rate, error rate, p99 latency, JVM heap, DB pool
  • →Alerts: error rate > 1%, p99 latency > 2s, heap > 80%
  • →Distributed tracing: every request gets a traceId, visible in Zipkin

⚙️ How It Works

Micrometer auto-configures when spring-boot-starter-actuator is present. Adding micrometer-registry-prometheus registers a Prometheus MeterRegistry. All metrics (JVM, HTTP, DB, custom) are registered in this registry and exposed at /actuator/prometheus in Prometheus text format.

💻 Example

Monitoring Setup — Custom metrics, Prometheus configuration, and distributed tracing.

java
@Service
@RequiredArgsConstructor
public class OrderMetricsService {

    private final MeterRegistry meterRegistry;

    // Counter: total orders created
    public void recordOrderCreated(String region, String paymentMethod) {
        meterRegistry.counter("orders.created",
            "region", region,
            "payment_method", paymentMethod
        ).increment();
    }

    // Timer: order processing duration
    public void recordOrderProcessingTime(Duration duration, OrderStatus finalStatus) {
        meterRegistry.timer("orders.processing.duration",
            "status", finalStatus.name()
        ).record(duration);
    }

    // Gauge: current pending orders count
    public void registerPendingOrdersGauge(OrderRepository orderRepository) {
        Gauge.builder("orders.pending.count",
                orderRepository,
                repo -> repo.countByStatus(OrderStatus.PENDING))
            .description("Number of orders in PENDING status")
            .register(meterRegistry);
    }

    // Distribution summary: order value distribution
    public void recordOrderValue(BigDecimal amount) {
        meterRegistry.summary("orders.value",
            "currency", "USD"
        ).record(amount.doubleValue());
    }
}

// Usage in service:
@Service
@Timed("order.service.place")  // Auto-times this method
public class OrderService {
    public Order placeOrder(CreateOrderRequest request) {
        long start = System.currentTimeMillis();
        try {
            Order order = processOrder(request);
            metricsService.recordOrderCreated(request.getRegion(), request.getPaymentMethod());
            return order;
        } finally {
            metricsService.recordOrderProcessingTime(
                Duration.ofMillis(System.currentTimeMillis() - start),
                OrderStatus.CONFIRMED);
        }
    }
}

🤔 Common Confusions

❓ Micrometer vs Micrometer Tracing — what is the difference?

Micrometer is for metrics (counters, gauges, timers). Micrometer Tracing (formerly Spring Cloud Sleuth) is for distributed tracing (trace IDs, spans, request journeys). Both are part of the Micrometer project. Spring Boot 3.x includes both. Add micrometer-tracing-bridge-brave for Zipkin compatibility.

❓ What is the difference between a counter, gauge, and timer?

Counter: monotonically increasing number (total requests, total errors). Gauge: current value that can go up or down (active connections, queue size, heap usage). Timer: measures duration and count of events (HTTP request latency, DB query time). Distribution summary: like timer but for non-time values (order amounts, file sizes).

🚨 Common Production Issues

Too many metric tags causing cardinality explosion — never use userId or orderId as a tag

Tracing sampling too high (100%) causing performance overhead in high-traffic production

/actuator/prometheus exposed publicly — restrict to monitoring network

✅ Best Practices

Tag all metrics with application name and environment

Use low-cardinality tags (status, region, method) — never userId or requestId

Set tracing sampling to 10-20% in production — not 100%

Create Grafana dashboards for RED metrics: Rate, Errors, Duration

Alert on error rate and p99 latency thresholds

🏛️ Architect's Note

Senior Architect's Perspective

The RED method is the standard for microservice monitoring: Rate (requests per second), Errors (error rate), Duration (latency percentiles). Create a Grafana dashboard with these three metrics for every service. Add USE metrics for infrastructure: Utilization, Saturation, Errors for CPU, memory, and DB connections. These 6 metrics tell you 90% of what you need to know about service health.

💬 Frequently Asked Questions

How do I create a Grafana dashboard for Spring Boot?

Import Grafana dashboard ID 4701 (JVM Micrometer) and 12900 (Spring Boot Statistics) from Grafana.com. These pre-built dashboards show JVM metrics, HTTP metrics, and database metrics out of the box. Customize with your business metrics on top.

🎯 Key Takeaways

1Micrometer is the metrics facade — add micrometer-registry-prometheus for Prometheus
2Auto-configured metrics: JVM, HTTP requests, HikariCP pool, cache
3Custom metrics: counter (totals), gauge (current values), timer (durations)
4Never use high-cardinality values (userId) as metric tags
5Micrometer Tracing adds distributed tracing — set sampling to 10% in production
6RED metrics: Rate, Errors, Duration — the essential service health indicators

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these Spring Boot references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages

SplashRide Spring Boot learning path

Browse the full Spring Boot topic collection and learning order on SplashRide.

Spring Boot Interview Prep

Practice Spring Boot interview questions and scenario-based answers.

Backend Engineer Career Path

A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.

Full Stack Java Developer Career Path

A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.

Actuator

Master Spring Boot Actuator — the production-ready features for health checks, metrics, info, and management endpoints that every enterprise Spring Boot application needs.

Logging

Master structured logging in Spring Boot — Logback configuration, SLF4J, MDC for request tracing, log levels, and production logging best practices.