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>
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>
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 |
| 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
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.