// TRACING: OPENTELEMETRY + GRAFANA TEMPO

OpenTelemetry Tracing mit Grafana Tempo: von der Störung zur auslösenden Anfrage

Sie setzen OpenTelemetry ein oder führen es gerade ein: Metriken und Logs laufen, der Tracing-Teil fehlt oder liegt brach. Genau diese Umsetzung übernehmen wir: Instrumentierung, Collector-Pipeline, Grafana Tempo und die Nutzung in Grafana. Am Ende führt jede Störung in Grafana zu der Anfrage, die sie ausgelöst hat, über Services, Queues und Datenbanken hinweg.

Erster Schritt: ein kurzes, kostenloses Erstgespräch – direkt mit einem Senior Consultant, keine Vertriebskette. Unverbindlich – danach entscheiden Sie.

Tracing scheitert selten an Tempo und fast immer davor: am fehlenden Header in der Kafka-Nachricht, am Sampler, der die Fehler verwirft, am Limit, das still greift. Diese Stellen kennen wir aus dem Betrieb und räumen sie aus, bevor Ihr Team den ersten Trace sucht.

// LEISTUNGEN

Was wir beim Tracing-Teil übernehmen

Instrumentierung und Kontextweitergabe

Auto-Instrumentierung je Sprache (Java-Agent, .NET, Python, Node.js, Go), eBPF-basierte Instrumentierung, wo kein Code angefasst werden darf, manuelle Spans an Geschäftsgrenzen. Kontextweitergabe – die Übergabe von Trace-ID und Eltern-Span an den nächsten Aufruf – nach W3C Trace Context über HTTP und gRPC (traceparent-Header), über Kafka-Record-Header und über asynchrone Grenzen wie Thread-Pools und Batch-Jobs.

Collector-Pipeline für Traces

Agent- und Gateway-Stufe des OTel Collectors, Processors in der richtigen Reihenfolge: memory_limiter zuerst, batch zuletzt. Tail-Sampling – die Entscheidung fällt erst, wenn der ganze Trace vorliegt – läuft im Gateway. Davor schickt der loadbalancing-Exporter mit routing_key traceID alle Spans eines Traces an dasselbe Gateway; sonst entscheidet jede Instanz für sich, und Traces kommen halb an.

Grafana Tempo aufbauen und betreiben

Deployment-Modus nach Volumen (monolithisch, skalierbar monolithisch, Microservices), S3, GCS oder Azure Blob als Objektspeicher, Retention – wie lange Blocks aufbewahrt werden – über compactor.block_retention, Mandantenfähigkeit über den X-Scope-OrgID-Header mit eigenen Limits je Mandant. Tempo überwachen wir selbst: verworfene Spans nach Grund, Ingester-Speicher, Compaction-Rückstand, Query-Latenz. Self-hosted oder als Grafana Cloud Traces.

Nutzung in Grafana

Tempo-Datenquelle mit Trace-to-Logs (Loki) und Trace-to-Metrics (Mimir oder Prometheus), Service Graph und RED-Metriken (Rate, Errors, Duration) aus dem Metrics-Generator, der Tempo-Komponente, die Metriken aus Spans ableitet und per Remote Write ins Metrik-Backend schreibt. Exemplars – Metrikpunkte mit angehängter Trace-ID – führen vom Latenz-Ausreißer im Dashboard direkt zum Trace. Traces Drilldown für die Suche ohne Abfragesprache.

Enablement

TraceQL-Workshop an Ihren eigenen Daten – TraceQL ist die Abfragesprache von Tempo. Ergebnis: die Abfragen, die Ihr Bereitschaftsteam braucht, als gespeicherte Suchen in den Runbooks, und Konventionen für Span-Namen, damit Traces gelesen werden.

// ARCHITEKTUR

So sieht die Zielarchitektur aus.

Die Anwendungen liefern Spans über SDK, Auto-Instrumentierung oder eBPF an einen Collector-Agent je Knoten. Der Agent reichert Ressourcenattribute an und schickt die Spans trace-ID-bewusst an die Gateway-Stufe, die das Tail-Sampling durchführt und an den Tempo-Distributor exportiert. In Tempo schreiben Ingester Blocks in den Objektspeicher, der Compactor fasst Blocks zusammen und setzt die Retention durch, Querier und Query-Frontend beantworten TraceQL-Abfragen, der Metrics-Generator schreibt RED-Metriken und Service Graph per Remote Write nach Mimir oder Prometheus. Grafana bindet Tempo, Loki und Mimir als Datenquellen ein und verknüpft sie über die Trace-ID.

Planungshinweis: Tempo 3.0 ersetzt den Ingester durch Live-Store und Block-Builder hinter einer Kafka-kompatiblen Warteschlange. Läuft bei Ihnen 2.x, bauen wir auf 2.10 und planen den Upgrade-Pfad ein; bei Neuaufbau entscheidet Ihr Betriebsteam mit, ob die zusätzliche Warteschlange gewünscht ist.

01AnwendungenSDK je SpracheAuto-InstrumentierungeBPF ohne Code-Änderung02OTel CollectorAgent je KnotenGateway mit Tail-SamplingLoad-Balancing nach Trace-ID03Grafana TempoDistributor · Ingester · CompactorQuerier · Query-FrontendMetrics-Generator04GrafanaTrace-Suche mit TraceQLTrace-to-Logs · Trace-to-MetricsService Graph · ExemplarsOTLPOTLPTraceQLObjektspeicher: S3 · GCS · Azure BlobLoki · Mimir – verknüpft per Trace-IDRED-METRIKEN PER REMOTE WRITE
01AnwendungenSDK je SpracheAuto-InstrumentierungeBPF ohne Code-ÄnderungOTLP02OTel CollectorAgent je KnotenGateway mit Tail-SamplingLoad-Balancing nach Trace-IDOTLP03Grafana TempoDistributor · Ingester · CompactorQuerier · Query-FrontendMetrics-GeneratorObjektspeicher: S3 · GCS · Azure BlobTraceQL04GrafanaTrace-Suche mit TraceQLTrace-to-Logs · Trace-to-MetricsService Graph · ExemplarsLoki · Mimir – verknüpft per Trace-ID

Drei TraceQL-Abfragen, wie sie nach dem Enablement in Ihren Runbooks stehen:

{ resource.service.name = "checkout" && status = error }

Alle Traces, in denen der Service checkout einen Fehler-Span hat: die Frage nach dem ersten Alarm.

{ resource.service.name = "frontend" } >> { resource.service.name = "checkout" && duration > 800ms }

Langsame checkout-Spans, die irgendwo unterhalb eines frontend-Spans hängen. Der Operator >> fragt die Struktur des Traces ab, nicht nur einzelne Spans: Aufrufe aus dem Batch-Job bleiben außen vor.

{ span.db.system.name != nil } | count() > 25

Traces mit mehr als 25 Datenbank-Spans, der klassische N+1-Fall. Ältere SDKs schreiben das Attribut noch als span.db.system; welche Variante bei Ihnen gilt, legt die Bestandsaufnahme fest.

// AUS DEM BETRIEB

Typische Fehler, die wir beim Tracing-Rollout beheben

Der Trace endet an Kafka, am Thread-Pool oder an der Legacy-Komponente

UrsacheDie Kontextweitergabe fehlt: kein traceparent-Header im Kafka-Record, kein Kontext im Worker-Thread, ein Header, den die alte Komponente nicht kennt.Was wir tunJede Grenze einzeln prüfen, die passende Instrumentierung aktivieren (Kafka-Clients, Executor-Wrapping) und an Legacy-Stellen den Kontext manuell per inject und extract weiterreichen.

Ein Service, vier Namen

Ursacheservice.name kommt aus der Umgebungsvariable, aus dem Deployment oder gar nicht („unknown_service“).Was wir tunRessourcenattribute zentral setzen: OTEL_RESOURCE_ATTRIBUTES im Deployment, k8sattributes- und resource-Processor im Agent. Der Service Graph zeigt danach einen Knoten je Service.

Span-Metriken sprengen das Serien-Limit

UrsacheHohe Kardinalität, also zu viele Label-Kombinationen, weil Nutzer-IDs oder Request-Pfade als Dimension in die Span-Metriken laufen.Was wir tunDie Dimensionen des span_metrics-Processors auf wenige stabile Attribute begrenzen und Span-Namen schon im Collector normalisieren (/orders/{id} statt /orders/4711).

Genau die Traces fehlen, die man sucht

UrsacheHead-Sampling im SDK entscheidet beim ersten Span, bevor jemand weiß, ob die Anfrage fehlschlägt.Was wir tunDas SDK auf „alles senden“ stellen und die Entscheidung ins Tail-Sampling im Gateway verlegen, wo Fehler und Dauer bekannt sind.

Tempo verwirft Spans, ohne dass jemand es merkt

UrsacheLimits greifen still: max_bytes_per_trace, max_traces_per_user, rate_limit_bytes. Sichtbar wird das nur in der Metrik tempo_discarded_spans_total.Was wir tunDie Limits nach gemessenem Volumen setzen und auf diese Metrik einen Alarm legen, bevor der erste Nutzer einen Trace vermisst.

Trace-to-Logs läuft ins Leere

UrsacheDie Logs enthalten keine trace_id, oder das Feld heißt anders als in der Tempo-Datenquelle konfiguriert.Was wir tuntrace_id und span_id über die Logging-Bridge des SDK ins Log-Format bringen, die Ableitungsregeln der Datenquelle prüfen und den Sprung Trace → Logs → Trace an echten Anfragen testen.

// VORGEHEN

So läuft die Umsetzung

Wir binden uns in vorhandene Collector, Grafana-Instanzen und Objektspeicher ein und tauschen keinen laufenden Stack aus. Was bei Ihnen funktioniert, bleibt; wir ergänzen den Tracing-Teil.

1. Bestandsaufnahme

Vorhandene Collector und Pipelines, Sprachen und Frameworks, Kubernetes oder VMs, Objektspeicher, Grafana, Loki und Mimir. Gemeinsam legen wir die kritischen Nutzerpfade fest, die zuerst nachvollziehbar sein müssen.Danach haben Siedas Architekturbild mit Ihren Namen darin, die Service-Liste je Pfad und die Abnahmekriterien im Angebot.

2. Tempo und Pipeline als Code

Tempo-Deployment mit Objektspeicher, Retention und Limits, Collector-Gateway mit Tail-Sampling, Tempo-Datenquelle in Grafana mit Trace-to-Logs und Trace-to-Metrics, dazu das Monitoring von Tempo selbst.Danach haben Sieeinen versionierten Stack in Ihrem Repository, der sich aus dem Git-Stand wieder aufbauen lässt, und ein Betriebsdashboard für Tempo.

3. Pilot auf einem kritischen Pfad

Instrumentierung der Services auf dem ersten Pfad, Kontextweitergabe über jede Grenze geprüft, Naming-Konventionen an echten Spans festgelegt.Danach haben Sieeinen ununterbrochenen End-to-End-Trace vom Eingang bis zur Datenbank, den Ihr Team in Grafana aufrufen kann, und die Vorlage für alle weiteren Pfade.

4. Rollout und Übergabe

Ausrollen auf die übrigen Services, Metrics-Generator aktiv, Dashboards und Alarme auf Span-Metriken, TraceQL-Workshop, Runbooks, Übergabe an Ihren Betrieb.Danach haben SieTrace-Abdeckung der definierten Services, Alarme, die auf den Trace zeigen, und ein Team, das ohne uns weiterarbeitet.

Erfolgsgarantie für Tracing

Vor dem Start stehen messbare Abnahmekriterien im Angebot, mit Messverfahren und Abnahmetermin. Ob sie erreicht sind, prüfen Sie. Verfehlen wir sie, geht das spürbar zu unseren Lasten; die Konditionen stehen transparent in Ihrem Vertrag. Für ein Tracing-Projekt sehen die Kriterien zum Beispiel so aus:

// FAQ

Häufige Fragen zu Tracing mit Tempo

Ja, genau das. Wir bauen Tempo und die Trace-Pipeline neben Ihre bestehenden Metriken und Logs und verknüpfen die drei Signale über die Trace-ID.

Ihre Collector, Grafana-Instanz und Ihr Objektspeicher bleiben; wir ergänzen die Traces-Pipeline und die Tempo-Datenquelle.

Weil Tempo nur Objektspeicher braucht und sich ohne eigene Datenbank horizontal skalieren lässt.

Jaeger ist ein gutes Werkzeug und OpenTelemetry-kompatibel; wenn es bei Ihnen läuft und trägt, bleibt es. Für Grafana-Umgebungen liefert Tempo TraceQL, Metrics-Generator und Exemplars ohne zusätzliche Komponenten.

Nein. Tempo schreibt Blocks im Parquet-Format direkt in S3, GCS oder Azure Blob und legt den Index in denselben Blocks ab.

Es gibt keinen Elasticsearch- oder Cassandra-Cluster, den Sie zusätzlich betreiben müssen.

Tail-Sampling, sobald Sie Fehler und langsame Anfragen vollständig sehen wollen.

Head-Sampling entscheidet im SDK beim ersten Span und kennt den Ausgang der Anfrage nicht; Tail-Sampling entscheidet im Collector-Gateway, wenn der Trace komplett ist. Der Preis ist Speicher im Gateway für die Wartezeit, deshalb dimensionieren wir decision_wait und num_traces nach gemessenem Volumen.

Das hängt von Span-Volumen, Sampling-Anteil und Retention ab, nicht von einer Faustformel.

Wir messen im Pilot die Bytes je Trace nach Sampling, rechnen auf Ihre Anfragen hoch und legen block_retention und Speicherbudget als Abnahmekriterium fest. Objektspeicher ist die günstigste Speicherklasse im Stack; teuer wird nur, was ungeplant wächst.

Beides setzen wir um; die Pipeline davor ist identisch.

Self-hosted lohnt sich, wenn Betriebsteam und Objektspeicher vorhanden sind und Daten im eigenen Rechenzentrum bleiben müssen. Grafana Cloud Traces nimmt Ihnen Betrieb und Upgrades ab und rechnet nach eingeliefertem Volumen ab, was das Tail-Sampling zur Kostenstellschraube macht. Lizenzen verkaufen wir in keinem der beiden Fälle.

Ja. Wir arbeiten mit 50 bis 100 Prozent Auslastung je nach Projektbedarf, remote-first und bei Bedarf vor Ort.

Bei Teilauslastung planen wir feste Tage, damit Ihr Team weiß, wann Rückfragen beantwortet werden.

Bei sauberer Konfiguration gering und messbar: Die Auto-Instrumentierung erzeugt Spans im Prozess, der Export läuft asynchron in Batches zum Collector.

Wie viel CPU und Latenz das bei Ihnen kostet, hängt von Sprache, Instrumentierungstiefe und Span-Volumen ab. Wir messen den Overhead im Pilot mit und ohne Agent, statt Pauschalwerte zu nennen.

Lassen Sie uns über Ihren Tracing-Teil sprechen

Ob Tempo neu aufbauen, eine liegengebliebene Trace-Pipeline in Betrieb nehmen oder Traces endlich mit Logs und Metriken verknüpfen: Im Erstgespräch klären wir Ihren Stand und den ersten kritischen Pfad. Mit Erfolgsgarantie auf die vereinbarten Ziele.

Erster Schritt: ein kurzes, kostenloses Erstgespräch – direkt mit einem Senior Consultant, keine Vertriebskette. Unverbindlich – danach entscheiden Sie.