Files
TimeTracker/docker/docker-compose.analytics.yml
T
Dries Peeters 4007ee2ca8 feat(observability): add OpenTelemetry traces, OTLP metrics, and log correlation
Introduce a centralized OTel layer (app/telemetry/otel_setup.py) that reuses
the existing OTLP endpoint and token, exports traces and metrics over OTLP/HTTP,
and instruments Flask plus SQLAlchemy. Manual OTLP log export remains for base
and product analytics; log records now include trace_id, span_id, and
event_category where tracing is active.

Business spans and product metrics cover invoices, timers, reports, auth,
webhook delivery, and scheduled jobs. RED-style HTTP metrics are recorded in
after_request alongside existing Prometheus counters. ENABLE_TRACING and
ENABLE_METRICS default on when credentials exist; graceful no-op when they do not.

Privacy is preserved: user_id appears on traces only when detailed analytics is
opted in; metrics never carry user_id; _remove_pii behavior for analytics is
unchanged. Responses inject traceparent when tracing is enabled for future
browser correlation.

Tests: test_otel_integration.py and per-test reset_for_testing() in conftest
so each app factory can reinitialize OTel.
2026-03-28 17:32:18 +01:00

124 lines
3.8 KiB
YAML

version: '3.8'
# Analytics-enabled Docker Compose configuration
# This extends the base docker-compose.yml with analytics services and configuration
services:
timetracker:
environment:
# Sentry Error Monitoring
- SENTRY_DSN=${SENTRY_DSN:-}
- SENTRY_TRACES_RATE=${SENTRY_TRACES_RATE:-0.0}
# OTEL OTLP export
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-}
- OTEL_EXPORTER_OTLP_TOKEN=${OTEL_EXPORTER_OTLP_TOKEN:-}
- ENABLE_TRACING=${ENABLE_TRACING:-true}
- ENABLE_METRICS=${ENABLE_METRICS:-true}
- OTEL_METRICS_EXPORT_INTERVAL_MS=${OTEL_METRICS_EXPORT_INTERVAL_MS:-60000}
# Telemetry (opt-in detailed analytics; base telemetry is always-on)
- ENABLE_TELEMETRY=${ENABLE_TELEMETRY:-false}
- TELE_SALT=${TELE_SALT:-change-me}
- APP_VERSION=${APP_VERSION:-1.0.0}
volumes:
# Mount logs directory for persistent JSON logs
- ./logs:/app/logs
# Mount data directory for telemetry marker files
- ./data:/app/data
# Expose metrics endpoint (optional, for Prometheus scraping)
# ports:
# - "8000:8000" # Already exposed in base compose
# Optional: Self-hosted Prometheus for metrics collection
prometheus:
image: prom/prometheus:latest
container_name: timetracker-prometheus
profiles:
- monitoring
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
ports:
- "9090:9090"
restart: unless-stopped
# Optional: Grafana for metrics visualization
grafana:
image: grafana/grafana:latest
container_name: timetracker-grafana
profiles:
- monitoring
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
ports:
- "3000:3000"
depends_on:
- prometheus
restart: unless-stopped
# Optional: Grafana Loki for log aggregation
loki:
image: grafana/loki:latest
container_name: timetracker-loki
profiles:
- logging
volumes:
- ./loki/loki-config.yml:/etc/loki/local-config.yaml
- loki_data:/loki
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
restart: unless-stopped
# Optional: Promtail for log shipping to Loki
promtail:
image: grafana/promtail:latest
container_name: timetracker-promtail
profiles:
- logging
volumes:
- ./logs:/var/log/timetracker:ro
- ./promtail/promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki
restart: unless-stopped
volumes:
prometheus_data:
driver: local
grafana_data:
driver: local
loki_data:
driver: local
# Usage:
#
# 1. Base setup with analytics enabled (Sentry, Grafana OTLP):
# docker-compose -f docker-compose.yml -f docker/docker-compose.analytics.yml up -d
#
# 2. With self-hosted monitoring (Prometheus + Grafana):
# docker-compose -f docker-compose.yml -f docker/docker-compose.analytics.yml --profile monitoring up -d
#
# 3. With log aggregation (Loki + Promtail):
# docker-compose -f docker-compose.yml -f docker/docker-compose.analytics.yml --profile logging up -d
#
# 4. With everything (monitoring + logging):
# docker-compose -f docker-compose.yml -f docker/docker-compose.analytics.yml --profile monitoring --profile logging up -d
#
# Configuration:
# - Copy env.example to .env and configure analytics variables
# - See docs/analytics.md for detailed configuration instructions