Wenn Monitoring in der Praxis scheitert, liegt es selten am fehlenden Tool. Häufiger sind Metriken unklar benannt, zu hochdimensional (zu viele Label-Kombinationen) oder an der falschen Stelle im Code erfasst. Das Ergebnis ist ein Zahlenfriedhof: Dashboards wirken beeindruckend, beantworten aber die entscheidenden Fragen nicht.
Mit OpenTelemetry lassen sich Metriken standardisiert erfassen und an verschiedene Backends ausliefern. Der eigentliche Hebel liegt jedoch im Modell: Welche Signale werden gemessen, welche Labels sind erlaubt, und wie wird aus Rohwerten eine betriebliche Aussage? In produktiven Systemen zahlt sich eine klare Metrik-Strategie sofort aus: schnellere Ursachenanalyse, weniger Alarmmüdigkeit und nachvollziehbare Performance-Budgets.
Welche Fragen Monitoring beantworten muss
Vor jeder Instrumentierung lohnt ein Blick auf typische Betriebsfragen. Metriken sind dann gut, wenn sie eine Entscheidung erleichtern oder ein Problem eingrenzen. In Web-Backends und Datenpipelines tauchen immer wieder ähnliche Muster auf:
- Ist der Dienst gerade verfügbar, oder steigt die Fehlerrate?
- Ist die Latenz hoch, und betrifft das alle Endpunkte oder nur einzelne?
- Ist das Problem lastgetrieben (Traffic), ressourcengetrieben (CPU/RAM) oder abhängig von Downstream-Systemen?
- Wo entsteht Backpressure (z.B. Queue wächst, Worker kommen nicht nach)?
Diese Fragen lassen sich mit wenigen, gut gewählten Kennzahlen abdecken. Ein häufiger Fehler ist, zuerst „alles“ zu messen. Besser ist ein Kernset aus Service-Metriken plus gezielten Domänenmetriken (z.B. pro Job-Typ, pro Datenquelle), die direkt an Geschäfts- oder Prozessschritte gekoppelt sind.
SLIs statt Dashboard-Sammelsurium
Ein praktikabler Einstieg ist, pro Service 2–4 Service Level Indicators (SLIs) festzulegen: Fehlerrate, Latenz (p95/p99) und Durchsatz. Diese Kennzahlen lassen sich in der Regel direkt aus HTTP-/RPC-Servern, Datenbankzugriffen oder Queue-Verarbeitung ableiten. Wichtig ist: SLIs müssen stabil bleiben, auch wenn sich Implementierungsdetails ändern.
Metriktypen richtig einsetzen: Counter, Gauge, Histogram
Metrics sind nicht einfach „Zahlen“, sondern haben Semantik. Der Metriktyp entscheidet, ob Aggregationen korrekt sind und ob Alarme sinnvoll funktionieren.
Counter: nur nach oben
Counter eignen sich für Ereignisse: Anzahl Requests, Anzahl Fehler, Anzahl verarbeiteter Jobs. Sie werden typischerweise als Rate betrachtet (z.B. Fehler pro Minute). Counter sind robust gegen Scrape-Intervalle und liefern in Zeitreihen-Backends stabile Ableitungen.
Gauge: aktueller Zustand, aber mit Vorsicht
Gauges sind Momentaufnahmen: Queue-Länge, offene Verbindungen, aktueller Speicherverbrauch. Sie sind hilfreich, können aber in verteilten Systemen leicht missinterpretiert werden, wenn man mehrere Instanzen zusammenfasst. „Summe der offenen Verbindungen über alle Pods“ ist manchmal sinnvoll, manchmal nicht. Deshalb Gauges so definieren, dass klar ist, ob „pro Instanz“ oder „gesamt“ gemeint ist.
Histogram: Latenzen und Größenverteilungen
Für Latenzen, Payload-Größen oder Job-Dauern sind Histogramme meist die richtige Wahl. Damit lassen sich Perzentile ableiten und Tail-Latenz sichtbar machen. In der Praxis ist es entscheidend, die Bucket-Grenzen bewusst zu wählen: zu grob verliert Aussagekraft, zu fein erhöht Kosten und Rauschen. Viele Teams starten mit einer Standard-Bucket-Strategie und passen sie nur für besonders kritische Pfade an.
Kardinalität: das häufigste Produktionsproblem
„Kardinalität“ beschreibt, wie viele unterschiedliche Zeitreihen durch Label-Kombinationen entstehen. Hohe Kardinalität treibt Speicher- und Rechenkosten hoch, verschlechtert Query-Performance und kann Backends destabilisieren. Label wie user_id, session_id oder request_id sind fast immer eine schlechte Idee in Metriken.
Label-Regeln, die im Betrieb wirklich helfen
- Nur Labels nutzen, die eine begrenzte, kontrollierte Wertemenge haben (z.B. method=GET/POST, status_class=2xx/5xx).
- Für Pfade nicht den rohen URL-Pfad labeln, sondern eine Route-Template-Form (z.B. /users/{id}).
- Für Fehlergründe lieber grobe Kategorien (timeout, validation, downstream) statt freier Fehlermeldungen.
- Wenn ein Label plötzlich explodiert, ist das ein Incident: Metrik sofort entschärfen, notfalls Label entfernen.
Domänenmetriken: gezielt statt überall
Domänenmetriken sind wertvoll, wenn sie eine betriebliche Hypothese prüfen. Beispiel: Ein Import-Service verarbeitet Dateien aus verschiedenen Quellen. Ein Label source=partner_a/partner_b kann sinnvoll sein, wenn die Quellen überschaubar sind und sich Verhalten unterscheidet. Ein Label filename dagegen erzeugt praktisch unendliche Kardinalität und bringt kaum operativen Nutzen.
Namenskonventionen und Einheiten: Query-freundlich bleiben
Unklare Namen führen zu falschen Dashboards. Eine Konvention reduziert Abstimmungskosten und macht Metriken langfristig wartbar.
Pragmatische Konvention für Teams
- Substantivische Namen, die das Gemessene beschreiben: http_server_requests, job_duration.
- Einheiten konsequent führen (z.B. seconds, bytes). Nicht mischen.
- Labels als Adjektive: method, route, status_class, outcome.
- Keine Abkürzungen, die nur im Team verstanden werden.
Wichtig ist nicht die „perfekte“ Norm, sondern Stabilität. Wer Namensschemata wöchentlich ändert, verliert den historischen Vergleich und erzeugt Migrationsaufwand in Alerts und Dashboards.
Instrumentierung im Code: typische Muster für Web und Worker
Der technische Einstieg gelingt oft über vorhandene Auto-Instrumentierung (z.B. für HTTP-Frameworks). Danach lohnt sich eine dünne Schicht für eigene Messpunkte. Zentral ist, dass Messung und Business-Logik nicht unkontrolliert vermischt werden.
HTTP-Services: Routen, Statusklassen, Ergebnis
Für einen HTTP-Service reichen meist diese Dimensionen: route, method, status_class und outcome (success/error). Wer zusätzlich „exception_type“ labelt, sollte die Menge der möglichen Werte begrenzen (z.B. eigene Fehlerklassen, keine vollständigen Exception-Namen aus Libraries).
Ein verbreiteter Stolperstein sind dynamische Routen. Gute Framework-Integrationen liefern ein Route-Template; falls nicht, sollte eine eigene Normalisierung eingebaut werden, bevor der Wert als Label in Metriken landet.
Worker und Queues: Durchsatz und Lag sichtbar machen
Bei Worker-Systemen sind drei Kennzahlen besonders hilfreich: jobs_processed_total (Counter), job_duration_seconds (Histogram) und queue_depth (Gauge). Daraus lassen sich schnell Engpässe erkennen: Steigt queue_depth, aber jobs_processed_total bleibt stabil, ist die Eingangsrate höher als die Verarbeitungskapazität. Steigt job_duration_seconds, liegt die Ursache häufig in Downstream-Aufrufen oder Datenbank-Locks.
Export und Pipeline: Collector als Entkopplung
In vielen Setups ist der OpenTelemetry Collector der zentrale Baustein: Anwendungen senden Signale an den Collector, der sie verarbeitet und an das gewünschte Backend exportiert. Das entkoppelt Applikationen von Backend-spezifischen Formaten und erlaubt Anpassungen ohne Redeploy (z.B. Sampling bei Traces, Attribute-Filtering bei Metriken).
Warum eine Pipeline Schmutzarbeit übernehmen sollte
- Entfernen oder Umbenennen riskanter Labels, bevor sie das Backend erreichen.
- Zusammenführen von Ressourcenattributen (z.B. service.name, deployment.environment).
- Routing in unterschiedliche Backends (z.B. kurzlebige Dev-Umgebung vs. Produktiv).
Gerade Kardinalitätsprobleme lassen sich im Collector oft schneller entschärfen als in jeder Anwendung einzeln. Trotzdem sollte die Quelle korrigiert werden: „Filter im Collector“ ist eine Notbremse, kein Ersatz für saubere Instrumentierung.
Alerts, die nicht nerven: wenige, aber robuste Regeln
Alarmmüdigkeit entsteht meist durch zu sensitive Grenzwerte oder durch fehlenden Kontext. Gute Alerts knüpfen an stabile Signale an, die direkt eine Nutzerwirkung abbilden.
Bewährte Alarm-Kategorien
- Fehlerrate über Schwellwert für mehrere Minuten (statt einzelne Peaks).
- p95/p99-Latenz über Budget in einem Zeitraum (nicht nur Mittelwert).
- Queue wächst dauerhaft (Backlog), kombiniert mit sinkendem Durchsatz.
- Ressourcenknappheit, wenn sie tatsächlich zu Sättigung führt (CPU throttling, OOM-Kills).
Zusätzlicher Kontext reduziert Zeit bis zur Diagnose: Wenn ein Alert feuert, sollte das verlinkte Dashboard sofort die relevanten Splits zeigen (route, status_class, outcome). Für die Ursachenanalyse sind ergänzend Logs und Traces sinnvoll. Wer Webhooks verarbeitet, kann z.B. Retries und Queue-Verhalten mit passenden Signalen kombinieren; dazu passt der Beitrag Webhooks zuverlässig verarbeiten.
Vorgehen für die Einführung in bestehenden Systemen
In laufenden Produkten ist Monitoring selten „Greenfield“. Entscheidend ist ein Ablauf, der Risiko minimiert und schnell Nutzen zeigt.
- Pro Service ein Kernset definieren: Requests, Fehler, Latenz als Histogram, optional Sättigungsmetriken.
- Labels begrenzen und schriftlich festhalten: welche sind erlaubt, welche sind verboten.
- Collector-Pipeline als Sicherheitsnetz konfigurieren: problematische Attribute droppen oder normalisieren.
- Ein Dashboard pro Service bauen, das Incident-Fragen beantwortet (Fehler, Latenz, Traffic, Sättigung).
- Erst danach Domänenmetriken ergänzen (z.B. pro Job-Typ, pro Partnerquelle), wenn sie eine Diagnose verbessern.
- Alarme aus SLIs ableiten und regelmäßig reviewen: welche feuern ohne Handlungsbedarf?
Zusammenspiel mit API-Design und Backend-Architektur
Metriken hängen stark davon ab, wie APIs und interne Schichten geschnitten sind. Ein Service-Layer (fachliche Logik in einer klaren Schicht) erleichtert es, Metriken an stabilen Punkten einzuhängen, statt in Controller- oder Handler-Code zu verstreuen. Passend dazu: Service-Layer im Backend.
Auch API-Eigenschaften beeinflussen die Interpretation von Metriken. Bei idempotenten Endpunkten (mehrfache gleiche Requests ohne Doppelwirkung) sind Wiederholungen weniger riskant, und Fehler-/Retry-Metriken lassen sich anders bewerten als bei nicht-idempotenten Operationen. Dazu ergänzt der Beitrag idempotente APIs den Blick auf robuste Request-Flows.
Typische Anti-Patterns aus realen Projekten
„Alles labeln“ statt operativer Hypothesen
Ein häufiger Reflex ist, jede denkbare Dimension als Label zu erfassen. Besser ist eine klare Frage: „Welche Aufteilung hilft im Incident?“ Labels sollten diese Frage beantworten, nicht Neugier befriedigen.
Fehler nur zählen, aber nicht klassifizieren
Eine einzelne Fehlerrate ist wichtig, aber für die Diagnose oft zu grob. Mit wenigen Kategorien (timeout, validation, downstream, unknown) entsteht ein deutlich besserer Einstieg. Diese Kategorien sollten im Code konsistent vergeben werden, statt aus freien Texten abgeleitet zu werden.
Histogramme ohne klare Buckets
Zu breite Buckets machen Tail-Latenz unsichtbar, zu schmale Buckets verteuern Queries. Gute Buckets orientieren sich an erwarteten Latenzen und an relevanten Budgets. Wer beispielsweise ein 300-ms-Latenzziel hat, braucht rund um diesen Bereich eine ausreichende Auflösung.
Kurzer Vergleich: Custom-Metriken vs. Auto-Instrumentierung
| Aspekt | Auto-Instrumentierung | Eigene Messpunkte |
|---|---|---|
| Einführungsgeschwindigkeit | Hoch, schnelle Basisabdeckung | Mittelhoch, abhängig von Code-Struktur |
| Semantik/Domain-Fit | Begrenzt auf Framework-Events | Sehr gut, direkt an Prozessschritten |
| Kardinalitätsrisiko | Framework-abhängig, teils ok | Hoch, wenn Label-Regeln fehlen |
| Wartung | Updates der Libraries nötig | Stabil, wenn Konventionen eingehalten |
In der Praxis funktioniert eine Kombination: Auto-Instrumentierung liefert die Grundversorgung, eigene Metriken ergänzen kritische Prozesspunkte. Für Sicherheit und Stabilität helfen klare Deploy- und Änderungsprozesse, etwa über Feature Flags beim schrittweisen Ausrollen von Instrumentierung; dazu passt Feature Flags im Produktivbetrieb.
Wer Metriken als Produktbestandteil versteht, profitiert langfristig: weniger Rätselraten im Betrieb, klare Performance-Signale und belastbare Kapazitätsentscheidungen. Entscheidend sind wenige, korrekt modellierte Messungen, begrenzte Label-Kardinalität und eine Pipeline, die Fehler abfedert.
