Skip to main content
GoModel exportiert OpenTelemetry-Traces und -Metriken für eingehende HTTP-Requests (außer Betriebs-Endpunkten, siehe unten) und für jeden ausgehenden Aufruf an einen Modell-Provider. Provider-Aufrufe folgen den GenAI Semantic Conventions, sodass Jaeger, Grafana Tempo, Honeycomb, Datadog oder jedes andere OTLP-kompatible Backend zeigt, welches Modell über welchen Provider aufgerufen wurde, wie lange der Aufruf gedauert hat und ob er fehlgeschlagen ist. Zugangsdaten und Fehlermeldungen werden nie exportiert. Prompts und Completions werden nur exportiert, wenn Sie die Inhaltserfassung einschalten. Für das Scraping durch Prometheus siehe Prometheus-Metriken; beides kann gleichzeitig laufen.

Schnellstart

Der Export ist standardmäßig deaktiviert. Setzen Sie OTEL_ENABLED=true und richten Sie den Exporter auf Ihren Collector aus:
GoModel protokolliert beim Start 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:
Sampling betrifft nur Traces. Metriken sind immer vollständig.
Export-Header wie authorization werden mit jedem Export-Request übertragen. Verwenden Sie einen https://-Endpunkt (oder einen gRPC-Endpunkt mit TLS), sobald Header Zugangsdaten enthalten; Klartext ist nur für einen Collector auf demselben Host akzeptabel. GoModel protokolliert beim Start eine Warnung, wenn Header konfiguriert sind und der effektive Endpunkt Klartext verwendet (http:// oder gRPC mit OTEL_EXPORTER_OTLP_INSECURE=true) und keine Loopback-Adresse ist.

Was exportiert wird

HTTP-Server-Spans und -Metriken

Jeder Request erhält einen SERVER-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:
Die Spans der Provider-Aufrufe für Chat Completions, Responses API und übersetzte /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.
Bei aktivierter Erfassung verlässt jeder gesampelte Prompt und jede gesampelte Completion das Gateway zusammen mit ihrem Trace. Aktivieren Sie sie nur für ein Backend, das diese Daten speichern darf, und erwägen Sie Sampling (OTEL_TRACES_SAMPLER), um das Volumen zu begrenzen. Das Audit-Log behält Inhalte stattdessen in Ihrem eigenen Speicher.

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.port und user_agent.original werden aus HTTP-Spans entfernt, und vom Host abgeleitete Dimensionen sind von HTTP-Metriken ausgeschlossen, damit ein Client die Kardinalität der Metriken nicht über den Host-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 minimale docker-compose.yml, die Traces in Jaeger anzeigt:
Senden Sie einen Request über das Gateway und öffnen Sie http://localhost:16686.
Zuletzt geändert am 24. Oktober 2026