Schnellstart
Der Export ist standardmäßig deaktiviert. Setzen SieOTEL_ENABLED=true
und richten Sie den Exporter auf Ihren Collector aus:
opentelemetry enabled zusammen mit den
gewählten Exportern. Exporter arbeiten asynchron: Das Gateway startet auch dann,
wenn der Collector nicht erreichbar ist, und versucht es im Hintergrund erneut.
Ohne
OTEL_EXPORTER_OTLP_ENDPOINT sendet das SDK an
http://localhost:4318 (http/protobuf) oder localhost:4317 (grpc).Konfiguration
OTEL_ENABLED ist der einzige GoModel-spezifische Schalter. Alles andere folgt
den standardisierten
OpenTelemetry-Umgebungsvariablen,
sodass GoModel genau wie jeder andere instrumentierte Dienst konfiguriert wird.
Die gängigen Einstellungen sind auch unter opentelemetry: in
config.yaml verfügbar; eine in der Umgebung
gesetzte Variable hat Vorrang vor dem YAML-Wert.
Ein typisches Setup für den Produktivbetrieb:
Was exportiert wird
HTTP-Server-Spans und -Metriken
Jeder Request erhält einenSERVER-Span, der nach seiner Route benannt ist
(zum Beispiel POST /v1/chat/completions), mit den Standardattributen
http.request.method, http.route, http.response.status_code und
url.scheme, dazu das Histogramm http.server.request.duration sowie die
Histogramme für die Größe von Request- und Response-Body.
Der Trace-Kontext des Aufrufers wird berücksichtigt, sodass ein Gateway-Span
als Kind des Spans der aufrufenden Anwendung erscheint, sobald der Client
traceparent sendet (oder die Header, die OTEL_PROPAGATORS auswählt).
/health, /health/ready, der Prometheus-Endpunkt (METRICS_ENDPOINT) und
/debug/pprof sind ausgenommen: Sie werden regelmäßig abgefragt und würden
sonst das Trace-Volumen dominieren.
Spans der Provider-Aufrufe und GenAI-Metriken
Jeder logische Aufruf an einen Modell-Provider wird instrumentiert mit:
Die Response- und Nutzungsattribute werden bei Chat Completions, bei der
Responses API und bei übersetzten
/v1/messages-Aufrufen gesetzt, gepuffert
oder gestreamt, sobald das Gateway die Response dekodiert hat. Die Nutzung ist
vorhanden, wenn der Provider sie gemeldet hat. Bei Streams fordert GoModel nur
dann einen Usage-Chunk beim Provider an, wenn die Nutzungserfassung aktiv ist
(Standard). /v1/messages-Requests, die GoModel nativ an einen
Anthropic-Provider weiterleitet, und andere Passthrough-Aufrufe tragen nur die
Request-Attribute.
Metriken sind Histogramme in Sekunden mit denselben Attributen:
gomodel.client.empty_responses zählt gepufferte Chat- und Responses-API-Aufrufe,
die 200 ohne Choices, ohne Ausgabe oder ohne Token-Nutzung zurückgegeben
haben. Diese Aufrufe sehen in den obigen Histogrammen erfolgreich aus, richten
Sie Alerts daher stattdessen auf diesen Zähler ein. Sein error.type ist
no_choices, no_output (ein abgeschlossener Responses-API-Aufruf ohne
Ausgabeelemente) oder no_usage (Inhalt ohne Token-Nutzung).
Ein gepufferter Aufruf erzeugt einen CLIENT-Span mit dem Namen
<operation> <model>, etwa chat gpt-5, unterhalb des HTTP-Server-Spans.
Retries und Failover zu einem anderen Provider sind separate Aufrufe und damit
separate Spans. Ein Request mit Failover zeigt daher genau, welcher Provider
fehlgeschlagen ist und welcher geantwortet hat.
Ein gestreamter Aufruf von Chat Completions, Responses API oder übersetztem
/v1/messages erhält einen Client-Span, der mit dem Stream endet, sodass seine
Dauer die gesamte Generierung abdeckt. Andere Streams, etwa
Passthrough-Aufrufe, erhalten keinen Client-Span: Das Gateway sieht nur, wann
sie aufgebaut wurden, und ein Span, der bei den Headern endet, würde die Latenz
falsch angeben. Ihr HTTP-Server-Span deckt dennoch die gesamte Lebensdauer des
Streams aus Sicht des Clients ab. Ein Stream, der sich nicht aufbauen lässt
oder vor seinem ersten Chunk endet, erhält immer einen Fehler-Span, sodass
Fehler im Trace erscheinen.
Erfassung von Prompts und Completions
Die Inhaltserfassung ist standardmäßig deaktiviert. Schalten Sie sie ein, um die ausgetauschten Nachrichten in Ihrem Tracing-Backend zu sehen, zum Beispiel als Ein- und Ausgabe einer Generation in Langfuse:/v1/messages-Aufrufe enthalten dann die
GenAI-Nachrichtenattribute
als JSON:
Textteile, die länger als 64 KiB sind, werden gekürzt und gekennzeichnet, und
jedes Attribut enthält höchstens 512 KiB Text: Bei einer langen Konversation
geht zuerst der Text der ältesten Nachrichten verloren. Bilder, Audio und
Dateien werden auf ihren Teiltyp reduziert: Binärdaten und Data-URLs werden nie
exportiert. Requests, die der Trace-Sampler verwirft, werden überhaupt nicht
erfasst. Die Variable akzeptiert außerdem
SPAN_ONLY und SPAN_AND_EVENT, die
Modusnamen neuerer OpenTelemetry-Instrumentierungen.
Datenschutz
Der Exporter ist so ausgelegt, dass Telemetrie an ein Backend eines Drittanbieters gehen kann, ohne preiszugeben, was durch das Gateway fließt:- Prompts, Completions und Tool-Aufrufe werden nur dann an Spans angehängt, wenn die Inhaltserfassung aktiv ist, und niemals an Metriken. Request- und Response-Bodys werden nie unverändert exportiert.
- Zugangsdaten und Upstream-Fehlermeldungen werden nie exportiert; Fehler tragen nur einen Statuscode oder eine Fehlerklasse.
client.address,network.peer.*,server.address,server.portunduser_agent.originalwerden aus HTTP-Spans entfernt, und vom Host abgeleitete Dimensionen sind von HTTP-Metriken ausgeschlossen, damit ein Client die Kardinalität der Metriken nicht über denHost-Header aufblähen kann.
Neu laden
gomodel --reload (SIGHUP) baut die OpenTelemetry-Pipeline mit der aktuellen
Umgebung neu auf, sodass Änderungen an Exporter, Sampling und Propagation ohne
Neustart wirksam werden. Die vorherige Pipeline wird geleert, bevor sie
verworfen wird.
Beispiel mit lokalem Collector
Eine minimaledocker-compose.yml, die Traces in Jaeger anzeigt:
http://localhost:16686.