Monitoring
Der Shop verwendet OpenTelemetry für Tracing und Metriken, Loki für
Log-Aggregation und Grafana für Dashboards.
OpenTelemetry
Die monitoring-App (src/snake_shop/monitoring/) konfiguriert:
Instrumentierung
Beim App-Start werden automatisch instrumentiert:
| Komponente |
Instrumentiert durch |
| Django-Requests |
DjangoInstrumentor |
| PostgreSQL-Queries |
Psycopg2Instrumentor |
| Redis-Zugriffe |
RedisInstrumentor |
| HTTP-Clients |
RequestsInstrumentor |
| Celery-Tasks |
CeleryInstrumentor |
| Template-Rendering |
Django-Middleware |
Konfiguration
# monitoring/apps.py
from opentelemetry.instrumentation.django import DjangoInstrumentor
from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor
from opentelemetry.instrumentation.redis import RedisInstrumentor
DjangoInstrumentor().instrument()
Psycopg2Instrumentor().instrument()
RedisInstrumentor().instrument()
Exporter
- OTLP-Collector: Traces und Metriken an zentralen Collector
- Umgebungsvariablen:
OTEL_EXPORTER_OTLP_ENDPOINT – Collector-Adresse
OTEL_SERVICE_NAME – Service-Name („shop“)
OTEL_RESOURCE_ATTRIBUTES – Deployment-Umgebung
Logs
Strukturiertes Logging
# Verwendet django-structlog
import structlog
logger = structlog.get_logger(__name__)
logger.info("order_placed", order_id=42, user_id=7)
Log-Ausgabe
- Container schreibt strukturierte JSON-Logs nach stdout
- Docker/Containerd sammeln und leiten an Loki weiter
- Log-Level:
INFO (Produktion), DEBUG (Entwicklung)
Log-Streams
| Stream |
Inhalt |
| django |
Request/Response, Middleware |
| django.db |
SQL-Queries (nur DEBUG) |
| celery |
Task-Ausführung, Retries |
| gunicorn |
HTTP-Server |
| opentelemetry |
Export-Status |
Metriken
Request-Metriken
| Metrik |
Typ |
Beschreibung |
http.server.duration |
Histogram |
Request-Dauer |
http.server.request_count |
Counter |
Anzahl Requests |
http.server.error_count |
Counter |
Fehler (5xx) |
Application-Metriken
| Metrik |
Beschreibung |
orders.created |
Neue Bestellungen |
orders.value |
Bestellwert |
checkout.duration |
Checkout-Durchlaufzeit |
email.sent |
Versendete E-Mails |
celery.tasks.succeeded |
Erfolgreiche Tasks |
celery.tasks.failed |
Fehlgeschlagene Tasks |
Datenbank-Metriken
- Query-Dauer (p50, p95, p99)
- Query-Anzahl pro Request
- Connection-Pool-Auslastung
Health Checks
| Endpoint |
Zweck |
Erwartete Antwort |
/health/ |
Liveness |
200 OK |
/ready/ |
Readiness |
200 OK (DB/Cache erreichbar) |
/metrics/ |
Prometheus-Metriken |
Text/Plain |
Kubernetes-Probes
livenessProbe:
httpGet:
path: /health/
port: 8000
readinessProbe:
httpGet:
path: /ready/
port: 8000
Grafana-Dashboards
Vorkonfigurierte Dashboards:
| Dashboard |
Inhalt |
| Shop-Übersicht |
Requests, Fehler, Latenz |
| Bestellungen |
Anzahl, Wert, Status-Verteilung |
| Celery |
Task-Durchsatz, Fehler, Queue-Länge |
| Datenbank |
Queries, Connections, Slow-Queries |
Alerting
Eingerichtete Alerts:
| Alert |
Bedingung |
Schweregrad |
| Fehlerrate > 5 % |
5xx > 5 % in 5 Min. |
Warning |
| Fehlerrate > 10 % |
5xx > 10 % in 5 Min. |
Critical |
| Latenz p99 > 5s |
p99 > 5s in 5 Min. |
Warning |
| Health-Check down |
/health/ ≠ 200 |
Critical |
| DB-Connections > 80 % |
Pool-Auslastung |
Warning |
| Celery-Queue > 1000 |
Pending Tasks |
Warning |
Fehler-Tracking (Sentry)
Optionale Sentry-Integration für Exception-Tracking:
# Aktiviert über Umgebungsvariable
SENTRY_DSN = os.environ.get("SENTRY_DSN")
if SENTRY_DSN:
import sentry_sdk
sentry_sdk.init(dsn=SENTRY_DSN)