Distributed Tracing in Magento mit OpenTelemetry
AI generated
M2
di.xml
Magento 2 · Observability · OpenTelemetry · Tracing
Distributed Tracing in Magento
mit OpenTelemetry Anfragen über Systemgrenzen verfolgen

Sobald ein Magento Shop mit Microservices, externen APIs und asynchronen Queues arbeitet, verliert klassisches Logging jede Anfrage aus den Augen, sobald sie eine Systemgrenze überschreitet. Distributed Tracing mit OpenTelemetry verbindet jeden Teilschritt zu einer einzigen, durchgängigen Kette und macht sichtbar, wo genau Latenz entsteht.

19 Min. Lesezeit OpenTelemetry · Spans · Trace Context · Jaeger Magento 2.4.x · PHP 8.3

1. Warum Logging bei verteilten Systemen an seine Grenzen stößt

Ein einzelnes Log-File pro System reicht aus, solange eine Anwendung monolithisch bleibt. Sobald ein Magento Shop aber mit einem separaten Preis-Service, einem externen Versanddienst und einem asynchronen Order-Export-Consumer zusammenarbeitet, verliert sich eine einzelne Kundenanfrage über mehrere unabhängige Log-Dateien, jede mit eigenem Zeitstempel-Format und ohne gemeinsamen Bezugspunkt. Distributed Tracing löst genau dieses Problem, indem es jeder Anfrage eine eindeutige Trace-ID mitgibt, die über alle beteiligten Systeme hinweg erhalten bleibt.

Ohne Distributed Tracing bleibt die Fehlersuche bei einer langsamen Anfrage ein manuelles Zusammensetzen von Indizien: Ein Entwickler muss Zeitstempel in verschiedenen Logs von Hand korrelieren und hoffen, dass die Uhren der Server synchron laufen. Mit einem durchgängigen Trace hingegen zeigt eine einzige Ansicht die komplette Kette, von der ersten HTTP-Anfrage im Magento Frontend bis zur letzten Antwort eines externen Zahlungsdienstes, inklusive exakter Dauer jedes einzelnen Teilschritts.

OpenTelemetry hat sich als herstellerneutraler Standard für Distributed Tracing etabliert, weil es nicht an ein einzelnes Backend gebunden ist. Dieselbe Instrumentierung liefert Daten an Jaeger, Tempo oder kommerzielle Plattformen, ohne den Anwendungscode bei einem Anbieterwechsel neu schreiben zu müssen. Für Magento Shops mit wachsender Systemlandschaft ist das eine strategisch wichtige Entscheidung gegen Vendor-Lock-in.

2. Traces, Spans und Context: die Grundbegriffe

Ein Trace repräsentiert eine einzelne, vollständige Anfrage über alle beteiligten Systeme hinweg. Innerhalb eines Traces besteht jeder einzelne Arbeitsschritt aus einem Span, etwa eine Datenbankabfrage, ein HTTP-Aufruf an einen externen Dienst oder die Ausführung einer Preisregel. Jeder Span trägt Start- und Endzeitpunkt, sodass sich Dauer und Reihenfolge exakt rekonstruieren lassen. Spans können verschachtelt sein, ein übergeordneter Span für die gesamte Checkout-Anfrage enthält dann mehrere Kind-Spans für einzelne Teilschritte.

Der Trace Context ist die Information, die zwischen Systemen weitergereicht werden muss, damit ein neuer Span demselben Trace zugeordnet wird statt einen eigenen zu beginnen. Der W3C-Standard traceparent-Header transportiert diese Information über HTTP-Grenzen hinweg. Ohne korrekte Propagation dieses Headers entstehen isolierte Trace-Fragmente, die sich nicht mehr zu einer zusammenhängenden Kette zusammensetzen lassen, was den gesamten Wert von Distributed Tracing zunichtemacht.

3. OpenTelemetry PHP SDK in Magento integrieren

Das OpenTelemetry PHP SDK wird per Composer eingebunden und über eine zentrale Bootstrap-Klasse initialisiert, die einen Tracer-Provider registriert. Für Magento eignet sich ein Plugin auf den Front Controller, weil dort jede eingehende Anfrage garantiert einmal durchläuft, unabhängig davon, welche Route am Ende bedient wird. Dieser zentrale Einstiegspunkt öffnet den Root-Span für die gesamte Anfrage.

Wichtig bei der Integration ist, den Exporter asynchron und mit kurzer Timeout-Konfiguration zu betreiben, damit ein langsamer oder nicht erreichbarer Collector niemals die eigentliche Kundenanfrage verzögert. Ein OTLP-Exporter über UDP oder ein lokaler Sidecar-Collector, der Spans zwischenspeichert und weiterleitet, entkoppelt die Instrumentierung vom eigentlichen Request-Zyklus zuverlässig.


<?php
declare(strict_types=1);

namespace Mironsoft\Observability\Plugin;

use Magento\Framework\App\FrontControllerInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\API\Trace\TracerInterface;

/**
 * Opens the root span for every incoming request at the front controller
 * boundary, ensuring every route is captured under a distributed trace.
 */
class TracingFrontControllerPlugin
{
    /**
     * @param TracerInterface $tracer OpenTelemetry tracer instance.
     */
    public function __construct(private readonly TracerInterface $tracer)
    {
    }

    /**
     * Wraps request dispatch in a root span named after the request path.
     *
     * @param FrontControllerInterface $subject Original front controller.
     * @param callable                 $proceed Original dispatch method.
     * @param RequestInterface         $request Incoming HTTP request.
     * @return ResponseInterface
     */
    public function aroundDispatch(
        FrontControllerInterface $subject,
        callable $proceed,
        RequestInterface $request
    ): ResponseInterface {
        $span = $this->tracer->spanBuilder('magento.request')
            ->setSpanKind(SpanKind::KIND_SERVER)
            ->setAttribute('http.target', $request->getPathInfo())
            ->startSpan();

        $scope = $span->activate();

        try {
            return $proceed($request);
        } finally {
            $scope->detach();
            $span->end();
        }
    }
}

4. Eigene Spans für Checkout und Preisberechnung erzeugen

Der Root-Span allein zeigt nur die Gesamtdauer einer Anfrage, ohne Aufschluss darüber, welcher Teilschritt dafür verantwortlich ist. Für aussagekräftiges Distributed Tracing müssen kritische Codepfade eigene Kind-Spans erzeugen, etwa die Preisberechnung im Checkout oder der Aufruf des Versanddienstes. Diese Spans erben automatisch den Trace Context des aktiven Root-Spans, solange sie innerhalb derselben Ausführung erzeugt werden.

Ein bewährtes Muster ist, Attribute an jeden Span anzuhängen, die für die spätere Analyse relevant sind, etwa die Anzahl der Warenkorbpositionen oder die verwendete Versandmethode. Diese Attribute machen es später möglich, in der Trace-Oberfläche gezielt nach Mustern zu filtern, etwa alle langsamen Checkout-Traces mit mehr als zehn Positionen, ohne jeden Trace einzeln öffnen zu müssen.


<?php
declare(strict_types=1);

namespace Mironsoft\Observability\Service;

use OpenTelemetry\API\Trace\TracerInterface;

/**
 * Wraps shipping rate calculation in a child span with useful attributes
 * for later filtering in the trace backend.
 */
class ShippingRateSpan
{
    /**
     * @param TracerInterface $tracer OpenTelemetry tracer instance.
     */
    public function __construct(private readonly TracerInterface $tracer)
    {
    }

    /**
     * Executes the given callback inside a named, attributed span.
     *
     * @param callable $callback  Actual shipping rate calculation.
     * @param int      $itemCount Number of cart items, attached as a span attribute.
     * @return mixed The callback's return value.
     */
    public function wrap(callable $callback, int $itemCount): mixed
    {
        $span = $this->tracer->spanBuilder('shipping.calculate_rate')
            ->setAttribute('cart.item_count', $itemCount)
            ->startSpan();

        $scope = $span->activate();

        try {
            return $callback();
        } finally {
            $scope->detach();
            $span->end();
        }
    }
}

5. Trace Context über HTTP und Message Queue propagieren

Bei synchronen HTTP-Aufrufen an externe Dienste genügt es, den traceparent-Header an die ausgehende Anfrage anzuhängen, was die meisten OpenTelemetry-Instrumentierungen für gängige HTTP-Clients automatisch übernehmen. Schwieriger wird es bei asynchronen Nachrichten über RabbitMQ, weil dort kein HTTP-Header existiert, über den der Context automatisch mitreisen könnte.

Die Lösung ist, den Trace Context explizit als Teil des Nachrichten-Payloads oder als benutzerdefiniertes Message-Header-Feld zu serialisieren, bevor die Nachricht in die Queue geschrieben wird. Der Consumer liest dieses Feld beim Empfang aus und setzt damit den Trace Context fort, statt einen neuen, isolierten Trace zu beginnen. Ohne diesen expliziten Schritt reißt jede asynchrone Verarbeitung die Trace-Kette unweigerlich ab, was gerade bei Bestellexporten und Lagerabgleich ein häufiges Problem ist.

6. Collector und Backend: Jaeger und Tempo im Vergleich

Der OpenTelemetry Collector nimmt Spans von der Anwendung entgegen, verarbeitet sie optional weiter, etwa durch Batching oder Filterung, und leitet sie an ein Speicher-Backend weiter. Jaeger ist die etablierteste Open-Source-Lösung für Distributed Tracing, mit einer ausgereiften Web-Oberfläche zur Visualisierung von Trace-Ketten als Wasserfalldiagramm. Grafana Tempo verfolgt einen anderen Ansatz und speichert Traces kostengünstiger, indem es auf einen vollständigen Suchindex verzichtet und stattdessen auf Trace-ID-basierten Zugriff setzt.

Für Magento Betreiber, die bereits Grafana für Metriken und Logs nutzen, bietet Tempo den Vorteil einer einheitlichen Oberfläche über alle drei Observability-Säulen hinweg. Wer dagegen primär auf detaillierte, durchsuchbare Trace-Analyse Wert legt, profitiert von Jaegers ausgereifterer Suchfunktion über Span-Attribute und Tags.

7. Sampling-Strategien für hohen Traffic

Jede einzelne Anfrage vollständig zu tracen, erzeugt bei einem stark frequentierten Magento Shop erhebliche Datenmengen und Netzwerklast zum Collector. Head-based Sampling entscheidet bereits beim Start einer Anfrage, ob sie getraced wird, meist über eine feste Prozentzahl. Tail-based Sampling dagegen sammelt zunächst alle Spans eines Traces und entscheidet erst am Ende, basierend auf Kriterien wie Fehlerstatus oder Gesamtdauer, ob der komplette Trace behalten wird.

Für Distributed Tracing in Magento ist Tail-based Sampling besonders wertvoll, weil es garantiert, dass jeder fehlgeschlagene oder ungewöhnlich langsame Trace erhalten bleibt, während normale, schnelle Anfragen nur stichprobenartig gespeichert werden. Diese Kombination reduziert Speicherbedarf drastisch, ohne die für die Fehlersuche wichtigsten Traces zu verlieren.

8. Fehleranalyse anhand einer echten Trace-Kette

In der Praxis zeigt sich der Wert von Distributed Tracing am deutlichsten bei intermittierenden Performance-Problemen, die sich in klassischen Metriken nur als leichte Erhöhung des Durchschnittswerts zeigen. Eine Trace-Kette für eine einzelne langsame Checkout-Anfrage kann offenlegen, dass der Root-Span zwei Sekunden dauert, davon aber 1,7 Sekunden auf einen einzelnen Span für die Steuerberechnung entfallen, der wiederum auf einen externen Steuerdienst wartet.

Ohne diese Granularität hätte ein Entwickler vermutlich zuerst die Magento-eigene Preisberechnung verdächtigt und wertvolle Zeit mit der falschen Hypothese verbracht. Distributed Tracing verkürzt diese Art der Fehlersuche von Stunden auf Minuten, weil die Antwort direkt in der Struktur des Traces sichtbar ist, statt aus verstreuten Indizien rekonstruiert werden zu müssen.

9. Distributed Tracing im Vergleich zu Logs und Metriken

Distributed Tracing ersetzt weder Logs noch Metriken, sondern ergänzt beide um eine Dimension, die keines der beiden Werkzeuge allein liefern kann: die kausale Reihenfolge und Dauer einzelner Schritte über Systemgrenzen hinweg.

Werkzeug Beantwortet Grenze Ideal für
Logs Was ist an einem bestimmten Punkt passiert Kein Zusammenhang über Systemgrenzen Detailinformationen zu einem Ereignis
Metriken Wie viel, wie oft, über welchen Zeitraum Kein Einblick in einzelne Anfragen Trendanalyse und Alerting
Distributed Tracing Wo genau die Zeit einer Anfrage verbracht wurde Erfordert Instrumentierung in jedem System Latenz- und Fehleranalyse über Systemgrenzen

Die drei Säulen ergänzen sich am besten, wenn Trace-IDs auch in strukturierte Logs geschrieben werden. So lässt sich von einem auffälligen Metrik-Alarm direkt zu den zugehörigen Traces springen und von dort zu den detaillierten Log-Einträgen jedes einzelnen Spans, ohne manuelles Zeitstempel-Korrelieren.

Mironsoft

Magento Observability und Architektur für verteilte Systeme

Latenz über Systemgrenzen hinweg sichtbar machen?

Wir integrieren OpenTelemetry in euren Magento Shop, verbinden Traces über Microservices und Message Queues hinweg und richten Jaeger oder Tempo für echte Latenz-Analysen ein.

SDK-Integration

OpenTelemetry PHP SDK sauber in Magentos Front Controller eingebunden

Context Propagation

Trace Context über HTTP und Message Queues zuverlässig weitergegeben

Backend-Auswahl

Jaeger oder Tempo passend zur bestehenden Observability-Landschaft

10. Zusammenfassung

Distributed Tracing mit OpenTelemetry schließt die Lücke, die klassisches Logging und Metriken in verteilten Magento Architekturen offen lassen. Traces bestehen aus verschachtelten Spans, die über einen propagierten Trace Context miteinander verbunden bleiben, selbst wenn eine Anfrage von Magento über einen externen Preis-Service bis zu einem asynchronen Message-Queue-Consumer wandert. Die korrekte Propagation des traceparent-Headers über HTTP und die explizite Weitergabe des Contexts über Message Queues sind dabei die kritischsten technischen Schritte.

Tail-based Sampling stellt sicher, dass gerade die aussagekräftigsten Traces, nämlich fehlgeschlagene oder ungewöhnlich langsame, zuverlässig erhalten bleiben, während der Speicherbedarf für die Masse normaler Anfragen kontrolliert bleibt. Wer Distributed Tracing einmal sauber in seinen Magento Shop integriert hat, verkürzt die Fehlersuche bei Latenzproblemen über Systemgrenzen hinweg von Stunden auf Minuten.

Distributed Tracing in Magento — Das Wichtigste auf einen Blick

Traces und Spans

Ein Trace besteht aus verschachtelten Spans, jeder mit eigener Start- und Endzeit, verbunden über den Trace Context.

Context Propagation

traceparent-Header für HTTP, explizite Serialisierung des Contexts für asynchrone Message-Queue-Nachrichten.

Sampling

Tail-based Sampling behält fehlgeschlagene und langsame Traces zuverlässig, reduziert aber die Gesamtdatenmenge deutlich.

Backend-Wahl

Jaeger für ausgereifte Suche, Tempo für einheitliche Oberfläche mit bestehendem Grafana-Stack.

11. FAQ: Distributed Tracing in Magento mit OpenTelemetry

1Unterschied zwischen Trace und Span?
Ein Trace ist die vollständige Anfrage, ein Span ein einzelner Arbeitsschritt darin mit eigener Zeitmessung.
2Warum ist Context Propagation entscheidend?
Ohne sie entstehen isolierte Trace-Fragmente, die sich nie zu einer zusammenhängenden Kette zusammensetzen.
3Wie integriert man OpenTelemetry in Magento?
Über das PHP SDK per Composer, mit einem Plugin auf den Front Controller für den Root-Span.
4Context über Message Queue propagieren?
Explizit als Teil des Payloads oder Header-Felds serialisieren, vom Consumer wieder auslesen.
5Head-based vs. Tail-based Sampling?
Head entscheidet beim Start über feste Quote, Tail sammelt erst alle Spans und entscheidet am Ende.
6Warum Tail-based für Magento oft besser?
Garantiert, dass fehlgeschlagene und langsame Traces erhalten bleiben, reduziert aber Gesamtdatenmenge.
7Jaeger vs. Grafana Tempo?
Jaeger bietet ausgereifte Suche, Tempo integriert sich günstiger in einen bestehenden Grafana-Stack.
8Ersetzt Tracing klassisches Logging?
Nein, beide ergänzen sich am besten mit Trace-IDs in strukturierten Logs.
9Ursache einer langsamen Checkout-Anfrage finden?
Die Trace-Kette zeigt exakt den dominanten Span, vermeidet falsche Hypothesen von Anfang an.
10Welche Attribute an Spans anhängen?
Geschäftsrelevante Werte wie Positionsanzahl oder Versandmethode für spätere gezielte Filterung.