OpenTelemetry, a RED dashboard, one trace across Kafka and an SLO that pages on time
The flash sale is live and support is flooded. Is it every fan or a few? Which of seven services? The database, the pool, Kafka, the e-mail provider?
otel-lgtm
Development backend in one image; production swaps it for separate systems — the services still speak OTLP.
sh scripts/get-otel-agent.sh # downloads infra/otel/opentelemetry-javaagent.jar (v2.32.0) ```yaml x-otel: &otel JAVA_TOOL_OPTIONS: -javaagent:/otel/opentelemetry-javaagent.jar OTEL_JAVAAGENT_ENABLED: ${OTEL_ON:-true} OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-lgtm:4318
Each Java service mounts ./infra/otel:/otel:ro and adds <<: *otel plus its own OTEL_SERVICE_NAME. No image changes.
./infra/otel:/otel:ro
<<: *otel
OTEL_SERVICE_NAME
@Scheduled
http_server_request_duration_seconds_bucket{service_name, http_route, http_response_status_code}
trace_id
span_id
http_route
/catalog/events/{id}
An order produces two unrelated traces: POST /orders, and later the relay → Kafka → notification.
POST /orders
notification
traceparent
V2__outbox_traceparent.sql
kafka.send
infra/grafana/dashboards/boxoffice-red.json
sum by (service_name) (rate(…_count[$__rate_interval])) # Rate rate(…_count{http_response_status_code=~"5.."}) / rate(…_count) # Errors (ratio) histogram_quantile(0.95, sum by (service_name, le) (rate(…_bucket[…]))) # Duration db_client_connections_pending_requests # Saturation
Never average percentiles. Sum the bucket rates, then take the quantile.
catalog
/actuator
infra/grafana/alerting/slo-catalog.yaml
$A > 14.4 && $B > 14.4
Steady traffic, one healthy hour, then docker compose stop db. When does the fast-burn rule page?
docker compose stop db
for: 1m
OTEL_ON
parentbased_traceidratio
user_id
db
k6 constant-arrival-rate on GET /catalog/events/{id} through the edge; docker stats during the run.
constant-arrival-rate
GET /catalog/events/{id}
docker stats
observability-stack
chaos
You cannot fix what you do not measure — and you cannot measure what you did not instrument.
Outline: (1) the questions k6 cannot answer; (2) otel-lgtm and the Java agent; (3) the outbox breaks the trace; (4) RED and USE as code; (5) SLO, error budget, burn rate; (6) fire the alert; (7) measure.