Implementing Monitoring and Observability

1. Integrating Micrometer for Metrics

Concept Description
MeterRegistry Central registry for meters
Built-in meters JVM, system, HTTP, datasource, cache
Backends Prometheus, Graphite, Datadog, New Relic, CloudWatch, Wavefront

2. Configuring Prometheus Endpoint

Example: Prometheus registry dependency

<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

Example: Prometheus endpoint with application tags

management:
  endpoints.web.exposure.include: prometheus,health
  metrics.tags:
    application: ${spring.application.name}
    env: ${ENV:dev}

3. Exporting Metrics to Grafana

Metrics Pipeline

App /actuator/prometheus → Prometheus (scrape) → Grafana (dashboards)

4. Using Spring Boot Admin for Monitoring

Component Role
Admin Server UI dashboard for actuator data
Admin Client Auto-registers with server
Service Discovery Eureka/Consul/K8s

5. Implementing Distributed Tracing (Micrometer Tracing)

Example: OpenTelemetry tracing dependencies

<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
  <groupId>io.opentelemetry</groupId>
  <artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>

Example: Configure trace sampling and OTLP collector

management:
  tracing:
    sampling.probability: 0.1
  otlp:
    tracing.endpoint: http://collector:4318/v1/traces

6. Integrating with Zipkin for Trace Visualization

Element Detail
Bridge micrometer-tracing-bridge-brave
Exporter zipkin-reporter-brave
Property management.zipkin.tracing.endpoint

7. Configuring APM Tools

APM Integration
Datadog Java agent + micrometer-registry-datadog
New Relic Java agent
Elastic APM Java agent or elastic-apm-spring-boot-starter
Dynatrace OneAgent (auto-instrumentation)

8. Monitoring JVM Metrics

Metric Description
jvm.memory.used Heap/non-heap usage
jvm.gc.pause GC pause durations
jvm.threads.live Active thread count
process.cpu.usage CPU%
system.load.average.1m OS load avg

9. Creating Custom Actuator Endpoints

Example: Custom actuator endpoint with read and write operations

@Component
@Endpoint(id = "cache-stats")
public class CacheStatsEndpoint {
  private final CacheManager cm;
  public CacheStatsEndpoint(CacheManager cm) { this.cm = cm; }
  @ReadOperation public Map<String,Object> all() { /* … */ }
  @ReadOperation public Map<String,Object> one(@Selector String name) { /* … */ }
  @WriteOperation public void clear(@Selector String name) { cm.getCache(name).clear(); }
}

10. Using Liveness and Readiness Probes

Endpoint K8s Use
/actuator/health/liveness livenessProbe — restart if DOWN
/actuator/health/readiness readinessProbe — remove from LB

Example: Enable liveness and readiness probes

management:
  endpoint.health.probes.enabled: true
  health.livenessstate.enabled: true
  health.readinessstate.enabled: true

11. Implementing Custom Metrics with Tags

Example: Counter metric with endpoint and status tags

Counter.builder("api.requests")
  .description("API request count")
  .tags("endpoint", "/orders", "status", "200", "method", "POST")
  .register(registry)
  .increment();
Warning: Avoid high-cardinality tags (user IDs, request IDs) — explodes metric storage.