Overview
The microservices-app includes a full observability stack for monitoring, tracing, and logging:- OpenTelemetry (OTEL): Unified telemetry collection
- Prometheus: Metrics storage and querying
- Grafana: Visualization and dashboards
- Loki: Log aggregation
- Tempo: Distributed tracing
- Hubble UI: Network flow visualization (Cilium)
Architecture
OpenTelemetry Integration
All services send telemetry to the OTEL collector via theOTEL_EXPORTER_OTLP_ENDPOINT environment variable.
Configuration
Docker Compose (docker-compose.yml):
http://otel-collector:4317 if you deploy the observability stack.
Kubernetes (deploy/k8s/greeter.nix):
observability namespace and receives:
- Traces on port 4317 (gRPC)
- Metrics on port 4318 (HTTP)
Service Instrumentation
Go services use the official OTEL Go SDK with automatic instrumentation:@opentelemetry/sdk-node:
Accessing Observability UIs
| Service | URL | Credentials |
|---|---|---|
| Grafana | http://localhost:30300 | admin / admin |
| Prometheus | http://localhost:30090 | None |
| Hubble UI | http://localhost:31235 | None |
full-bootstrap.
Grafana
Grafana provides unified visualization for metrics, logs, and traces.Data Sources
Pre-configured in the microservices-infra bootstrap:- Prometheus:
http://prometheus.observability:9090 - Loki:
http://loki.observability:3100 - Tempo:
http://tempo.observability:3100
Dashboards
Import pre-built dashboards for:- Kubernetes cluster metrics
- Service-level metrics (request rate, latency, error rate)
- Traefik routing metrics
- Go runtime metrics
Querying Logs
Loki LogQL examples:Querying Traces
Use the Explore tab to query Tempo:- Search by trace ID
- Search by service name
- Search by duration
- Correlate with logs (click trace → view logs)
Prometheus
Prometheus scrapes metrics from:- Kubernetes nodes
- Traefik
- OTEL collector
- Service exporters
Querying Metrics
Example PromQL queries:Service Discovery
Prometheus discovers targets via Kubernetes service discovery:Loki
Loki aggregates logs from all pods via Promtail.Log Collection
Promtail runs as a DaemonSet and scrapes logs from:- Container stdout/stderr
- Kubernetes events
- Traefik access logs
Labels
Logs are indexed by:namespacepodcontainerapp(fromapp.kubernetes.io/namelabel)
Retention
Default retention: 7 days (configured in microservices-infra).Tempo
Tempo stores distributed traces from OTEL.Trace Correlation
Logs → Traces: If your log entries include atrace_id field, Grafana can automatically link to the trace:
Trace Sampling
Default: 100% sampling (all traces). Adjust in OTEL collector config for production:Hubble UI
Hubble visualizes network flows between services using Cilium.Features
- Service Map: Visual graph of service dependencies
- Flow Logs: Detailed network flow data (source, destination, protocol, status)
- DNS Queries: Track DNS lookups
- Policy Enforcement: Visualize NetworkPolicy effects
Accessing Hubble
Browser: http://localhost:31235 CLI:Use Cases
- Identify service dependencies
- Debug connectivity issues
- Verify NetworkPolicy enforcement
- Analyze traffic patterns
Traefik Observability
Traefik sends traces to Tempo via OTEL:- Request traces from edge to backend
- Middleware timing (CORS, auth, rate limiting)
- Error tracking
Service Metrics
Go Services
Usepromhttp to expose metrics:
Node.js Services
Useprom-client:
Custom Instrumentation
Adding Spans
Go:Structured Logging
Use structured logs for better Loki parsing: Go (zerolog):Disabling Observability
For lightweight local development: Docker Compose: Already disabled (emptyOTEL_EXPORTER_OTLP_ENDPOINT)
Kubernetes: Use bootstrap instead of full-bootstrap
Troubleshooting
No Traces Appearing
-
Check OTEL collector logs:
-
Verify endpoint configuration:
-
Test connectivity:
High Memory Usage
Reduce retention periods in microservices-infra:- Prometheus: Default 15d → 7d
- Loki: Default 7d → 3d
- Tempo: Default 7d → 1d
Missing Metrics
Verify Prometheus scrape targets:Next Steps
- Deploy with full observability: Kubernetes Deployment
- Configure Traefik tracing: Traefik Configuration
- Explore Grafana dashboards: http://localhost:30300