Skip to main content
GoModel eksportuje trace’y i metryki OpenTelemetry dla przychodzących requestów HTTP (z wyjątkiem endpointów operacyjnych, zobacz niżej) i każdego wychodzącego wywołania providera modeli. Wywołania providerów są zgodne z GenAI semantic conventions, więc Jaeger, Grafana Tempo, Honeycomb, Datadog czy dowolny inny backend kompatybilny z OTLP pokazuje, który model został wywołany, przez którego providera, ile to trwało i czy się nie powiodło. Dane uwierzytelniające i komunikaty błędów nigdy nie są eksportowane. Prompty i odpowiedzi modelu są eksportowane tylko wtedy, gdy włączysz przechwytywanie treści. Scrapowanie przez Prometheusa opisuje strona Metryki Prometheusa; oba mechanizmy mogą działać jednocześnie.

Szybki start

Eksport jest domyślnie wyłączony. Ustaw OTEL_ENABLED=true i skieruj exporter na swój collector:
Przy starcie GoModel loguje opentelemetry enabled razem z wybranymi exporterami. Exportery są asynchroniczne: gateway startuje nawet wtedy, gdy collector nie działa, i ponawia próby w tle.
Bez OTEL_EXPORTER_OTLP_ENDPOINT SDK wysyła dane do http://localhost:4318 (http/protobuf) lub localhost:4317 (grpc).

Konfiguracja

OTEL_ENABLED to jedyny przełącznik specyficzny dla GoModel. Cała reszta korzysta ze standardowych zmiennych środowiskowych OpenTelemetry, więc GoModel konfiguruje się dokładnie tak jak każdą inną instrumentowaną usługę. Najczęstsze ustawienia są też dostępne pod opentelemetry: w config.yaml; zmienna ustawiona w środowisku ma pierwszeństwo przed wartością z YAML. Typowa konfiguracja produkcyjna:
Sampling dotyczy tylko trace’ów. Metryki są zawsze kompletne.
Nagłówki eksportu, takie jak authorization, są dołączane do każdego requestu eksportu. Używaj endpointu https:// (lub endpointu gRPC z TLS) zawsze, gdy nagłówki zawierają dane uwierzytelniające; zwykły tekst jest dopuszczalny tylko dla collectora na tym samym hoście. GoModel loguje ostrzeżenie przy starcie, gdy skonfigurowano nagłówki, a efektywny endpoint używa niezaszyfrowanego połączenia (http:// lub gRPC z OTEL_EXPORTER_OTLP_INSECURE=true) i nie jest adresem loopback.

Co jest eksportowane

Spany i metryki serwera HTTP

Każdy request dostaje span SERVER nazwany według swojej trasy (na przykład POST /v1/chat/completions) ze standardowymi atrybutami http.request.method, http.route, http.response.status_code i url.scheme, a także histogram http.server.request.duration oraz histogramy rozmiaru body requestu i odpowiedzi. Kontekst trace’a od wywołującego jest respektowany, więc span gatewaya pojawia się jako dziecko spanu aplikacji wywołującej zawsze, gdy klient wysyła traceparent (lub nagłówki wybrane przez OTEL_PROPAGATORS). /health, /health/ready, endpoint Prometheusa (METRICS_ENDPOINT) i /debug/pprof są wykluczone: są regularnie odpytywane i w przeciwnym razie zdominowałyby wolumen trace’ów.

Spany wywołań providerów i metryki GenAI

Każde logiczne wywołanie providera modeli jest instrumentowane następującymi atrybutami: Atrybuty odpowiedzi i użycia są ustawiane dla chat completions, Responses API i tłumaczonych wywołań /v1/messages, buforowanych lub streamowanych, gdy gateway zdekoduje odpowiedź. Użycie jest obecne, gdy provider je zaraportował. W przypadku streamów GoModel prosi providera o chunk z użyciem tylko wtedy, gdy śledzenie użycia jest włączone (domyślnie). Requesty /v1/messages, które GoModel przekazuje natywnie do providera Anthropic, oraz inne wywołania passthrough mają tylko atrybuty requestu. Metryki to histogramy w sekundach z tymi samymi atrybutami: gomodel.client.empty_responses zlicza buforowane wywołania czatu i Responses API, które zwróciły 200 bez żadnych choices, bez outputu lub bez użycia tokenów. Takie wywołania w powyższych histogramach wyglądają na udane, więc alertuj na podstawie tego licznika. Jego error.type to no_choices, no_output (zakończone wywołanie Responses API bez elementów output) lub no_usage (treść z zerowym użyciem tokenów). Buforowane wywołanie tworzy span CLIENT nazwany <operation> <model>, np. chat gpt-5, zagnieżdżony pod spanem serwera HTTP. Retry i failover do innego providera to osobne wywołania, a więc osobne spany, dzięki czemu request, który przeszedł failover, pokazuje dokładnie, który provider zawiódł, a który odpowiedział. Streamowane wywołanie chat completion, Responses API lub tłumaczone wywołanie /v1/messages dostaje span klienta, który kończy się wraz z końcem streamu, więc jego czas trwania obejmuje całe generowanie. Inne streamy, takie jak wywołania passthrough, nie dostają spanu klienta: gateway widzi tylko moment ich ustanowienia, a span kończący się na nagłówkach błędnie raportowałby latencję. Ich span serwera HTTP nadal obejmuje cały czas życia streamu widziany przez klienta. Stream, którego nie udało się ustanowić lub który zakończył się przed dostarczeniem pierwszego chunka, zawsze dostaje span błędu, więc błędy są śledzone.

Przechwytywanie promptów i odpowiedzi

Przechwytywanie treści jest domyślnie wyłączone. Włącz je, żeby widzieć wymieniane wiadomości w swoim backendzie tracingu, na przykład jako wejście i wyjście generacji w Langfuse:
Spany wywołań providerów dla chat completions, Responses API i tłumaczonych wywołań /v1/messages zawierają wtedy atrybuty wiadomości GenAI w formacie JSON: Części tekstowe dłuższe niż 64 KiB są obcinane i oznaczane, a każdy atrybut przechowuje maksymalnie 512 KiB tekstu: długa rozmowa najpierw traci tekst najstarszych wiadomości. Obrazy, audio i pliki są redukowane do typu części: dane binarne i data URL-e nigdy nie są eksportowane. Requesty odrzucone przez sampler trace’ów nie są w ogóle przechwytywane. Zmienna akceptuje też SPAN_ONLY i SPAN_AND_EVENT – nazwy trybów z nowszych instrumentacji OpenTelemetry.
Przy włączonym przechwytywaniu każdy objęty samplingiem prompt i każda odpowiedź opuszczają gateway razem z trace’em. Włączaj to tylko dla backendu, który może przechowywać takie dane, i rozważ sampling (OTEL_TRACES_SAMPLER), żeby ograniczyć wolumen. Log audytowy przechowuje natomiast treść we własnym storage’u po Twojej stronie.

Prywatność

Exporter zaprojektowano tak, żeby telemetria mogła trafiać do zewnętrznego backendu bez ujawniania tego, co przepływa przez gateway:
  • Prompty, odpowiedzi modelu i wywołania narzędzi są dołączane do spanów tylko wtedy, gdy przechwytywanie treści jest włączone, i nigdy do metryk. Body requestów i odpowiedzi nigdy nie są eksportowane w niezmienionej postaci.
  • Dane uwierzytelniające i komunikaty błędów z upstreamu nigdy nie są eksportowane; błędy zawierają tylko kod statusu lub klasę błędu.
  • client.address, network.peer.*, server.address, server.port i user_agent.original są usuwane ze spanów HTTP, a wymiary zależne od hosta są wykluczone z metryk HTTP, żeby klient nie mógł zawyżać kardynalności metryk przez nagłówek Host.

Przeładowywanie

gomodel --reload (SIGHUP) przebudowuje pipeline OpenTelemetry z bieżącym środowiskiem, więc zmiany exportera, samplingu i propagacji zaczynają obowiązywać bez restartu. Poprzedni pipeline jest opróżniany przed odrzuceniem.

Przykład z lokalnym collectorem

Minimalny docker-compose.yml, który pokazuje trace’y w Jaegerze:
Wyślij request przez gateway i otwórz http://localhost:16686.
Ostatnia modyfikacja 24 października 2026