Spring Boot Production Monitoring and Distributed Tracing
Monitoring Spring Boot Applications in Production
Section titled “Monitoring Spring Boot Applications in Production”In production, monitoring is typically done using multiple tools that collect metrics, logs, health checks, and traces.
Typical Monitoring Stack
Section titled “Typical Monitoring Stack”flowchart TD
A[Spring Boot Application] --> B[Spring Boot Actuator]
B --> C[Micrometer]
C --> D[Prometheus]
D --> E[Grafana]
Key Components
Section titled “Key Components”| Component | Purpose |
|---|---|
| Spring Boot Actuator | Exposes health and metrics endpoints |
| Micrometer | Metrics collection library |
| Prometheus | Scrapes and stores metrics |
| Grafana | Dashboard visualization |
| ELK Stack | Centralized log aggregation and analysis |
| Distributed Tracing (Sleuth + Zipkin/Jaeger) | End-to-end request tracing |
Common Production Metrics
Section titled “Common Production Metrics”- CPU usage
- Memory usage
- JVM threads
- HTTP request count
- Error rate
- Database connection pool usage
- Response time
Common Actuator Endpoints
Section titled “Common Actuator Endpoints”/actuator/health/actuator/metrics/actuator/prometheus/actuator/env/actuator/threaddump/actuator/httptrace/actuator/beans/actuator/loggersExample:
http://localhost:8080/actuator/healthResponse:
{ "status": "UP"}How Spring Boot Actuator Collects Metrics
Section titled “How Spring Boot Actuator Collects Metrics”Spring Boot uses Micrometer as its metrics facade.
Architecture
Section titled “Architecture”flowchart TD
A[Application Code] --> B[Micrometer]
B --> C[MeterRegistry]
C --> D[Prometheus / Datadog / New Relic]
Core Concepts
Section titled “Core Concepts”| Component | Description |
|---|---|
| Micrometer | Metrics collection library |
| MeterRegistry | Stores and publishes metrics |
| Meter | Individual metric |
| Tags | Metadata used to classify metrics |
Metric Types
Section titled “Metric Types”| Type | Example |
|---|---|
| Counter | Number of requests |
| Gauge | Current memory usage |
| Timer | API response time |
| Distribution Summary | Payload size |
Example:
Counter requestCounter = meterRegistry.counter("api.requests");requestCounter.increment();Built-in metrics include JVM, memory, thread, HTTP request, and database connection pool metrics.
Metrics endpoint:
/actuator/metricsIntegrating Prometheus and Grafana
Section titled “Integrating Prometheus and Grafana”Step 1: Add Dependencies
Section titled “Step 1: Add Dependencies”<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId></dependency>Step 2: Configure Actuator
Section titled “Step 2: Configure Actuator”management: endpoints: web: exposure: include: "*" metrics: export: prometheus: enabled: trueStep 3: Configure Prometheus
Section titled “Step 3: Configure Prometheus”Prometheus scrapes:
http://localhost:8080/actuator/prometheusConfiguration:
scrape_configs: - job_name: springboot metrics_path: /actuator/prometheus static_configs: - targets: - localhost:8080Step 4: Grafana
Section titled “Step 4: Grafana”Configure Prometheus as a data source and build dashboards for:
- JVM memory
- HTTP latency
- Request rate
- Error percentage
Example query:
rate(http_server_requests_seconds_count[1m])Distributed Tracing
Section titled “Distributed Tracing”Distributed tracing follows a request across multiple microservices.
Example architecture:
flowchart LR
Client --> Gateway
Gateway --> Order
Order --> Payment
Payment --> Inventory
Example trace timing:
Trace ID: 12345
Order Service -> 50msPayment Service -> 200msInventory Service -> 40msKey Concepts
Section titled “Key Concepts”| Term | Meaning |
|---|---|
| Trace | Complete request journey |
| Span | Single operation within a trace |
| Trace ID | Unique identifier for the entire request |
| Span ID | Unique identifier for one operation |
Common tools:
- Zipkin
- Jaeger
- OpenTelemetry
Spring Cloud Sleuth
Section titled “Spring Cloud Sleuth”Note: Spring Cloud Sleuth is in maintenance mode as of Spring Boot 3 / Spring Cloud 2022+, superseded by Micrometer Tracing (paired with an exporter like OpenTelemetry or Zipkin’s Brave). The concepts below (TraceId/SpanId generation and propagation) still apply — only the library implementing them has changed. New Spring Boot 3.x projects should reach for Micrometer Tracing instead of adding Sleuth.
Spring Cloud Sleuth automatically generates and propagates tracing information.
flowchart TD
A[Client Request] --> B[Spring Cloud Sleuth]
B --> C[Generate TraceId & SpanId]
C --> D[Propagate to Downstream Services]
Example log:
[OrderService, traceId=12345, spanId=abcd]Processing orderSleuth propagates headers such as:
X-B3-TraceIdX-B3-SpanIdX-B3-ParentSpanIdDependency:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId></dependency>Optional:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>Tracing Requests Across Microservices
Section titled “Tracing Requests Across Microservices”Typical flow:
sequenceDiagram
participant C as Client
participant G as Gateway
participant O as Order Service
participant P as Payment Service
participant I as Inventory Service
C->>G: HTTP Request
G->>O: TraceId=12345
O->>P: TraceId=12345
P->>I: TraceId=12345
Each service creates its own span while sharing the same TraceId.
Example:
Gateway: TraceId=12345 SpanId=A1Order: TraceId=12345 SpanId=B1Payment: TraceId=12345 SpanId=C1Inventory: TraceId=12345 SpanId=D1Zipkin can visualize:
Trace 12345
Gateway -> 10msOrder Service -> 120msPayment Service -> 200msInventory Service -> 40msTraceId vs SpanId
Section titled “TraceId vs SpanId”Definitions
Section titled “Definitions”- TraceId identifies the complete end-to-end request.
- SpanId identifies a single operation within that request.
Example
Section titled “Example”| Service | TraceId | SpanId |
|---|---|---|
| Gateway | 12345 | A1 |
| Order Service | 12345 | B1 |
| Payment Service | 12345 | C1 |
| Inventory Service | 12345 | D1 |
Hierarchy
Section titled “Hierarchy”flowchart TD
T[TraceId: 12345]
T --> A[Gateway Span A1]
A --> B[Order Span B1]
B --> C[Payment Span C1]
C --> D[Inventory Span D1]
Log Example
Section titled “Log Example”[OrderService, TraceId=12345, SpanId=B1]Processing Order
[PaymentService, TraceId=12345, SpanId=C1]Processing PaymentComparison
Section titled “Comparison”| TraceId | SpanId |
|---|---|
| Identifies complete request flow | Identifies one operation |
| Same across all services | Different for every service |
| Used for end-to-end tracking | Used for operation-level analysis |
| One trace contains many spans | Each span belongs to one trace |
Interview Answer
Section titled “Interview Answer”TraceId represents the complete end-to-end request across microservices, while SpanId represents an individual operation within that request.
Key Takeaways
Section titled “Key Takeaways”- Spring Boot Actuator and Micrometer expose production-ready metrics.
- Prometheus scrapes metrics, while Grafana visualizes them.
- Distributed tracing tracks requests across microservices using TraceId and SpanId.
- Spring Cloud Sleuth automatically propagates tracing context between services.
- TraceId remains constant for an entire request; SpanId changes for each operation.