This project runs a minimal full observability stack with:
- OpenTelemetry Collector (traces + span metrics)
- Prometheus (metrics storage)
- Jaeger UI (distributed tracing + service monitoring)
- Grafana (visualization layer)
- Receives OTLP traces on
4317 - Converts traces → metrics using
spanmetrics - Exposes Prometheus metrics on
8889 - Forwards traces to Jaeger
-
Scrapes metrics from:
otel-collector:8889
-
Stores time-series metrics
-
Backend for Grafana dashboards
-
Backend for Jaeger SPM (Service Performance Monitoring)
-
Trace exploration UI: http://localhost:16686
-
Shows:
- request traces
- latency breakdown
- service dependencies
-
Monitor tab uses Prometheus metrics for SPM
- Visualization layer for metrics
- Connects to Prometheus datasource
- Provides dashboards for:
- service latency
- error rate
- throughput (RPS)
- span metrics (RED metrics)
Use Grafana dashboard:
Dashboard ID: 19419
Import steps:
- Open Grafana: http://localhost:3000
- Login
- Go to Dashboards → Import
- Enter ID: 19419
- Select Prometheus datasource
- Click Import
graph LR
App[Application / Express API]
OTel[OpenTelemetry Collector]
Jaeger[Jaeger UI]
Prom[Prometheus]
Grafana[Grafana]
App -->|OTLP Traces| OTel
OTel -->|Traces| Jaeger
OTel -->|Span Metrics| Prom
Prom --> Grafana
| Service | Port | Description |
|---|---|---|
| otel-collector | 4317 | OTLP trace ingestion |
| otel-collector | 8889 | Prometheus metrics |
| prometheus | 9090 | Metrics UI/API |
| jaeger | 16686 | Trace UI |
| grafana | 3000 | Dashboard UI |
podman compose up -d --remove-orphans
podman compose ps
- Jaeger: http://localhost:16686
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000
up{job="otel-collector"}
sum(rate(traces_span_metrics_duration_milliseconds_count[5m])) by (service_name)
histogram_quantile(0.95, sum(rate(traces_span_metrics_duration_milliseconds_bucket[5m])) by (le, service_name) )
- Service: otel-demo
- View traces in Search tab
- Monitor tab shows SPM metrics
- spanmetrics may take 30–90 seconds to appear
- Grafana requires Prometheus datasource configured
- SELinux systems may require :Z volume flag
You can extend this stack with:
- Loki (logs)
- Promtail (log shipping)
- Pino traceId correlation
- Alertmanager (alerts)
- Kubernetes deployment version