跳至主要內容

OpenTelemetry v1

OpenTelemetry 是一項 CNCF 的可觀測性標準。它可連接到任何可觀測性工具,例如 Jaeger、Zipkin、Datadog、New Relic、Traceloop、Levo AI 等。

尋找完整請求追蹤?

LiteLLM Proxy 提供較新的、可選用的 OpenTelemetry v2 整合,可為每個請求產生一條 trace(HTTP → 驗證 → 防護欄 → LLM 呼叫 → DB 寫入),遵循官方 GenAI 語意慣例,並附帶 Arize、Phoenix、Langfuse、Weave 等預設設定。使用 LITELLM_OTEL_V2=true 來啟用它。

v1.81.0 的變更

從 v1.81.0 起,request/response 預設會設為父層 Received Proxy Server Request span 上的屬性——除非您選擇啟用,否則不會有獨立的 litellm_request span。若要還原巢狀 litellm_request spans,請設定 USE_OTEL_LITELLM_REQUEST_SPAN=true。請參閱 Span Hierarchy 了解完整情況,以及 為什麼我看不到 litellm_request span? 了解何時切換此旗標。

開始使用

安裝 OpenTelemetry SDK:

uv add opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp

設定環境變數(不同提供者可能需要不同的變數):

OTEL_EXPORTER="otlp_http"
OTEL_ENDPOINT="https://api.traceloop.com"
OTEL_HEADERS="Authorization=Bearer%20<your-api-key>"

只要 1 行程式碼,就能透過 OpenTelemetry 立即記錄您在所有提供者上的 LLM 回應:

litellm.callbacks = ["otel"]

Span 階層

LiteLLM Proxy 處理的每個 LLM 請求,都會產生一棵以 Received Proxy Server Request 為根節點的 spans 樹狀結構。下方的條件式 spans 只有在其控制旗標被設定,或其功能正在使用時才會發出。

Received Proxy Server Request                      (SpanKind.SERVER, root)

├── litellm_request (INTERNAL, only when USE_OTEL_LITELLM_REQUEST_SPAN=true)
│ ├── raw_gen_ai_request (INTERNAL — provider request/response, content-capture-gated)
│ └── guardrail (INTERNAL — one per executed guardrail)

├── raw_gen_ai_request (INTERNAL — when litellm_request is collapsed into the root)
├── guardrail (INTERNAL — when litellm_request is collapsed into the root)

├── auth, router, self, proxy_pre_call, (INTERNAL — service-hook spans, see below)
│ redis, postgres, batch_write_to_db

└── Failed Proxy Server Request (INTERNAL — only on exception)

semconv modeOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental)中,當建立 LLM-call span 時,其名稱會變成 {operation} {model}(例如 chat gpt-4),並帶有 SpanKind.CLIENT,且 raw_gen_ai_request 會被抑制。是否發出該 span 也同樣由 USE_OTEL_LITELLM_REQUEST_SPAN gating 決定。請參閱 Opt-In to Latest GenAI Semantic Conventions

SDK(無 proxy)在沒有父層 context 時,會將 litellm_request 發出為根節點——在純 SDK 使用情境中,不會有 Received Proxy Server Request span。

Span 名稱參考

Span 名稱Span 類型父層發出時機
Received Proxy Server RequestSERVERroot(或外部 traceparent,若存在)每次對 LiteLLM Proxy 的 HTTP 請求一次
litellm_requestINTERNALproxy root(proxy)或 root(SDK)USE_OTEL_LITELLM_REQUEST_SPAN=true(proxy)或不存在父層 context(SDK)時。於 semconv mode 中會替換為 {operation} {model}
raw_gen_ai_requestINTERNAL若存在則為 litellm_request,否則為 proxy root每個上游提供者呼叫一次。會透過 llm.{provider}.* 攜帶提供者原生 request/response。於 semconv mode 且停用 message content capture 時會被抑制
guardrailINTERNAL(OpenInference kind = guardrail若存在則為 litellm_request,否則為 proxy root每次防護欄執行一個 span(pre-call、during-call 或 post-call)
Failed Proxy Server RequestINTERNALproxy root當 proxy 在完成請求前拋出例外時
{route}(例如 /user/info/key/infoINTERNALproxy root管理端點呼叫(非 LLM proxy 路由)
authrouterselfproxy_pre_callredispostgresbatch_write_to_dbreset_budget_jobpod_lock_managerINTERNALproxy root服務 hook spans——見下方

服務 hook spans(又稱「基礎設施」spans)

LiteLLM 有一個獨立的 hook(async_service_success_hook / async_service_failure_hook),會記錄內部子系統的時間,例如 router、auth 檢查、Redis、Postgres,以及 proxy pre-call pipeline。當 OTEL 整合啟用且 context 中存在父層 span 時,這些 hooks 會各自建立一個 INTERNAL 子 span。

span 名稱就是 ServiceTypes enum 值authrouterselfproxy_pre_callredispostgres、…)。完整集合定義於 litellm/types/services.pyself 是 LiteLLM SDK 本身(例如 make_openai_chat_completion_request 的時間);router 可能在每個請求中出現多次(一次用於 async_get_available_deployment,一次用於包裹的 acompletion)。

每個 service-hook span 會帶有:

屬性
service服務 enum 值(例如 "router""redis"
call_type特定操作(例如 "async_get_available_deployment""acompletion""add_litellm_data_to_request"
error僅在失敗 spans 上設定
(自訂 event_metadata)呼叫端附加的任何內容

這些 spans 是營運/基礎設施 spans,不是 GenAI 語意 spans。它們適用於 SRE 等級的除錯(LiteLLM 內部的時間都花在哪裡?),但它們不會帶有 gen_ai.* 屬性。若您只想在後端保留 AI 語意 spans,請依 gen_ai.system(或 span 名稱)是否存在來過濾。

目前沒有可停用單一 service-hook span 的環境變數。若您需要過濾它們,請在 OTLP collector/後端層處理(例如透過依 name 丟棄的 tail-based sampler)。

為什麼我看不到 litellm_request span?

行為在 v1.81.0 中已變更。預設情況下,USE_OTEL_LITELLM_REQUEST_SPAN=false,而 proxy 會將 litellm_request span 折疊進父層 Received Proxy Server Request span——其 gen_ai.* 屬性會改設在父層上。這樣做可:

  • 避免在父層與子層之間重複屬性。
  • 將 span 數量(以及儲存成本)每個請求約減少 1 個 span。
  • 在已存在父層 context 時,維持 trace 較淺。

若要恢復舊的巢狀行為——亦即每次 LLM 呼叫都會有自己的 litellm_request span,且作為 proxy root span 的子層——請設定:

USE_OTEL_LITELLM_REQUEST_SPAN=true

若符合以下情況,這是正確的設定:

  • 一個 HTTP 請求會發出多個 litellm.completion 呼叫——在預設行為下,最後一次呼叫的屬性會覆蓋共享父層上較早的屬性。
  • 您希望為 raw_gen_ai_requestguardrail 子層提供一個乾淨的父層,而不是 HTTP 請求 span。
  • 您後端的 UI 是以 litellm_request 這類 AI 語意 span 名稱為基礎。

不是回歸問題;這個變更是刻意設計的。此旗標會在每次請求時重新讀取,因此可在不重新啟動的情況下切換。

在 semconv mode(OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental)中,相同的 USE_OTEL_LITELLM_REQUEST_SPAN gating 仍決定是否發出 LLM-call span;semconv mode 只會改變 span 的名稱(變為 {operation} {model})、類型(變為 CLIENT)以及子層結構。

Context 傳遞(W3C traceparent

LiteLLM 會遵循 W3C Trace Context 標頭。如果您的用戶端(或上游閘道)傳送 traceparent 標頭,LiteLLM 會將 Received Proxy Server Request span 建立為該外部追蹤的子項,因此 LiteLLM 的 spans 會內嵌顯示在您的應用程式既有的分散式追蹤中。

父層 context 的解析順序(優先順序由高到低):

  1. 請求 metadata 中明確指定的 litellm_parent_otel_span
  2. 傳入的 traceparent HTTP 標頭(透過 TraceContextTextMapPropagator 擷取)。
  3. 目前在 OTEL 全域 context 中作用中的 span(thread-local)。
  4. 無 — LiteLLM 的 span 為根節點。

若要強制每個 LiteLLM 追蹤都成為自己的根節點,不論傳入標頭或作用中的 context 為何,請設定 OTEL_IGNORE_CONTEXT_PROPAGATION=true

執行多個 OpenTelemetry 處理器

您可以在同一個程序中執行多個 OpenTelemetry 處理器,例如通用 OTLP exporter 與特定後端的子類別並行。請在第一個之後的每個處理器上設定 skip_set_global=True,讓每個處理器都擁有自己私有的 TracerProviderMeterProviderLoggerProvider。之後 spans、metrics 與 log events 只會透過該處理器的 exporter 傳送。

import litellm
from litellm.integrations.opentelemetry import OpenTelemetry, OpenTelemetryConfig

# Primary handler. Claims the global TracerProvider.
primary = OpenTelemetry(config=OpenTelemetryConfig(
exporter="otlp_http",
endpoint="https://your-collector/v1/traces",
))

# Secondary handler. Has its own private providers.
secondary = OpenTelemetry(config=OpenTelemetryConfig(
exporter="otlp_http",
endpoint="https://second-collector/v1/traces",
skip_set_global=True,
))

litellm.callbacks = [primary, secondary]

初始化順序沒有影響。不論哪個先建立,兩個處理器都會接收到各自的 spans。

跨收集器行為(例如 LangSmith + 通用 OTEL)

當兩個會發出 OTEL 的整合同時啟用時——例如自訂的 LangSmith OTEL 處理器加上通用 otel exporter——兩者都會遵循相同的 traceparent 傳播規則,以及在 Context propagation 中描述的相同父層解析順序。只要其中一個處理器使用 skip_set_global=True,兩者都會:

  • 看到同一個 trace_id 對應於給定請求。
  • 產生相同的 span 階層(Received Proxy Server Requestlitellm_request(若啟用)→ raw_gen_ai_request / guardrail)。
  • 只會在將 spans 傳送到哪個 exporter 上不同。

如果自訂的 LangSmith OTEL 處理器被設定為僅在請求帶有 litellm_request 時掛載 traceparent(否則不執行任何動作),通用 OTEL 處理器仍會輸出完整的階層。由於 span 名稱與屬性都相同,兩種檢視可以各自獨立閱讀。

擷取訊息內容

LiteLLM 使用標準的 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT 環境變數來控制是否擷取 prompts 與 completions,以及擷取位置:

# Do not capture message content
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=NO_CONTENT

# Capture content on span attributes only
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY

# Capture content on event attributes only
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=EVENT_ONLY

# Capture content on both spans and events
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_AND_EVENT

也支援布林形式:true 對應到 EVENT_ONLYfalse 對應到 NO_CONTENT

每個處理器的內容政策

當執行多個 OpenTelemetry 處理器時,請在每個 OpenTelemetryConfig 上設定 capture_message_content,讓處理器可以有不同的內容政策。範例來說,可將完整 prompts 傳送到除錯後端,同時從重視合規性的 OTLP collector 中移除內容:

import litellm
from litellm.integrations.opentelemetry import OpenTelemetry, OpenTelemetryConfig

stripped = OpenTelemetry(config=OpenTelemetryConfig(
exporter="otlp_http",
endpoint="https://compliance-collector/v1/traces",
capture_message_content="NO_CONTENT",
))

verbose = OpenTelemetry(config=OpenTelemetryConfig(
exporter="otlp_http",
endpoint="https://debug-collector/v1/traces",
capture_message_content="SPAN_AND_EVENT",
skip_set_global=True,
))

litellm.callbacks = [stripped, verbose]

解析順序(優先順序由高到低):

  1. litellm.turn_off_message_logging=True 強制 NO_CONTENT(動態 kill-switch;覆寫下方所有設定)。
  2. OpenTelemetryConfig.capture_message_content(每個處理器的欄位,在處理器初始化時取樣)。
  3. OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT 環境變數(在處理器初始化時取樣)。
  4. 舊版的每個執行個體 message_logging 旗標 — 預設為 True,其對應到 SPAN_AND_EVENT

選擇加入最新 GenAI 語意慣例

設定 OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental 以發出符合 最新 OpenTelemetry GenAI 語意慣例 的 spans:

OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental

這會變更 LLM 呼叫 span 的名稱、類型與結構,抑制非標準的 raw_gen_ai_request 子 span,新增 gen_ai.provider.name 屬性並與 gen_ai.system 並列,若有提供則填入額外的請求與 cache-token 屬性,並將每則訊息事件整併為單一 gen_ai.client.inference.operation.details 事件。各列差異請見下方的 Spans ReferenceAttributes Reference

OpenTelemetryConfig.semconv_stability 是程式化等效設定。依 OTEL 規格,這個旗標可用逗號分隔。

從 OpenTelemetry 記錄中移除訊息、回應內容

從所有 OpenTelemetry 記錄中移除訊息與回應

設定 litellm.turn_off_message_logging=True 這會防止訊息與回應被記錄到 OpenTelemetry,但請求中繼資料仍會被記錄。

從特定 OpenTelemetry 記錄中移除訊息與回應

在通常傳給文字完成或 embedding 呼叫的 metadata 中,您可以設定特定鍵值,將這次呼叫的訊息與回應遮罩。

mask_input 設為 True,會將這次呼叫的輸入從記錄中遮罩

mask_output 設為 True,會使輸出不被記錄到這次呼叫中。

請注意,如果您正在延續既有追蹤,並將 update_trace_keys 設定為包含 inputoutput,且您設定了對應的 mask_inputmask_output,那麼該追蹤既有的輸入和/或輸出將會以已移除內容的訊息取代。

疑難排解

我沒有看到 litellm_request span

v1.81.0+ 預設行為(USE_OTEL_LITELLM_REQUEST_SPAN=false):proxy root span 會吸收 LLM 呼叫屬性,且不會有獨立的 litellm_request span。若要恢復巢狀 spans,請設定 USE_OTEL_LITELLM_REQUEST_SPAN=true。請參考 為什麼我看不到 litellm_request span?

如果您處於 semconv 模式,LLM 呼叫 span 仍然存在,但名稱會改為 {operation} {model}(例如 chat gpt-4)— 請依 gen_ai.system 搜尋,而不是依字面名稱 litellm_request

我只看到基礎架構 spans(routerauthredisproxy_pre_call

那些是 service-hook spans。它們會與 AI-semantic spans(raw_gen_ai_requestguardrail,以及若已啟用則為 litellm_request)一起發出,而不是取代它們。如果您真的在追蹤中任何地方都看不到 gen_ai.* 屬性:

  1. 驗證 litellm.callbacks(或 litellm_settings.callbacks)是否包含 "otel"
  2. 驗證該請求確實命中了 /chat/completions(或其他 LLM)路由 — 管理端點(/key/info/user/info,…)不會有 gen_ai.* 屬性。
  3. 檢查是否設定了 litellm.turn_off_message_logging=true 和/或 mask_input/mask_output — 它們會抑制訊息與原始提供者屬性。
  4. 設定 USE_OTEL_LITELLM_REQUEST_SPAN=true,讓 LLM 屬性落在名為 litellm_request 的 span 上,而不是與 Received Proxy Server Request 上的 HTTP 請求屬性混合在一起。

在失敗請求上追蹤 LiteLLM Proxy 的使用者/金鑰/組織/團隊資訊

LiteLLM 會在成功與失敗的請求上都發出 metadata.user_api_key_* 屬性(金鑰雜湊、金鑰別名、組織 ID、使用者 ID、團隊 ID)。若有,它們會出現在 litellm_request span 上,否則會出現在 Received Proxy Server Request 上。

沒有看到 traces 送達 Integration

如果您沒有看到 traces 送達您的整合,請在 LiteLLM 環境中設定 OTEL_DEBUG="True",然後再試一次。

export OTEL_DEBUG="True"

這會將任何記錄問題輸出到主控台。常見原因:

  • OTEL_EXPORTER_OTLP_ENDPOINT 指向 HTTPS 端點,但協定是 grpc(或反之)。
  • OTEL_HEADERS 缺少後端預期的驗證標頭。
  • 防火牆/sidecar 正在封鎖 4317/4318 的對外 OTLP 流量。
  • 對於 gRPC,未安裝 grpciouv add "litellm[grpc]")。

spans 被截斷或捨棄

OTLP 匯出器會批次處理 span。非常大的 gen_ai.input.messages/gen_ai.output.messages(例如多 MB 的提示)可能會超過收集器預設的 OTLP 屬性大小限制。您可以:

  • 將大型負載移出 trace(設定 litellm.turn_off_message_logging=true,並依賴 Spend Logs / cold storage,透過 metadata.cold_storage_object_key 參照)。
  • 提高收集器的 max_attribute_value_length 和 OTLP receiver 的 max_recv_msg_size_mib

控制 metric 屬性的基數

啟用 metrics 時,每個 gen_ai.client.* sample 都會附上一組共通屬性,因此您可以依模型、提供者、key 和 team 切分直方圖。預設下,這組屬性也包含每個請求的欄位,例如 hidden_params 和數個 metadata.* 值。這些值對每個請求來說幾乎都是唯一的,因此每一個都會讓後端追蹤的 time series 數量倍增(每種不同的屬性組合各一條 series)。在大量流量下,這會讓 metric 基數爆增,而有些後端,例如 Splunk Observability Cloud,會開始節流或捨棄這些 metrics。

若要限制基數,請過濾要附加到 metrics 的屬性。在 callback_settings.otel 底下巢狀加入 attributes 區塊,並使用 include_list(allowlist;只輸出列出的屬性)或 exclude_list(denylist;輸出除列出屬性之外的全部屬性)。兩者互斥,若同時設定,啟動時會引發設定錯誤。若沒有 attributes 區塊,行為維持不變,且會輸出每個屬性,因此既有 dashboard 仍可正常運作。

此過濾器只套用於 metrics。Span 會保留完整屬性集合,因此 trace 仍然豐富,同時 metric 基數保持受限。

排除高基數屬性(exclude_list)

最常見的情境。保留穩定的識別屬性,並移除會驅動基數的每請求 blob。

litellm_settings:
callbacks: ["otel"]

callback_settings:
otel:
attributes:
exclude_list:
- hidden_params
- metadata.requester_metadata
- metadata.requester_ip_address
- metadata.spend_logs_metadata
- metadata.mcp_tool_call_metadata
- metadata.vector_store_request_metadata
- metadata.prompt_management_metadata

只輸出明確指定的集合(include_list)

當您想要最小且最可預測的屬性集合時,請精確列出要保留的屬性。未列出的項目都會從 metrics 中移除。

litellm_settings:
callbacks: ["otel"]

callback_settings:
otel:
attributes:
include_list:
- gen_ai.operation.name
- gen_ai.system
- gen_ai.request.model
- gen_ai.framework
- metadata.user_api_key_team_id
- metadata.user_api_key_org_id

gen_ai.token.type 無法被過濾。它是於過濾後加到 input 與 output token series 上的結構性區分器,讓兩者保持不同;若將它列入 include_listexclude_list,會在啟動時遭拒絕,而不是靜默忽略。

有效的屬性名稱

這兩個清單都會在啟動時依下列集合驗證。未知名稱會引發設定錯誤,因此拼字錯誤絕不會悄悄回退為輸出所有屬性。有效名稱包括 gen_ai.* core attributes、hidden_params,以及 metadata.* keys:

  • gen_ai.operation.name
  • gen_ai.system
  • gen_ai.request.model
  • gen_ai.framework
  • hidden_params
  • metadata.user_api_key_hash
  • metadata.user_api_key_alias
  • metadata.user_api_key_team_id
  • metadata.user_api_key_org_id
  • metadata.user_api_key_user_id
  • metadata.user_api_key_team_alias
  • metadata.user_api_key_user_email
  • metadata.user_api_key_end_user_id
  • metadata.spend_logs_metadata
  • metadata.requester_ip_address
  • metadata.requester_metadata
  • metadata.prompt_management_metadata
  • metadata.applied_guardrails
  • metadata.mcp_tool_call_metadata
  • metadata.vector_store_request_metadata

設定參考

除非另有註明,以下所有旗標都從環境變數讀取。布林旗標接受 true/false(不區分大小寫)。

匯出器與資源

變數預設值用途
OTEL_EXPORTER(別名:OTEL_EXPORTER_OTLP_PROTOCOLconsole匯出器類型。常見值:consoleotlp_httpotlp_grpchttp/jsonhttp/protobufgrpc
OTEL_ENDPOINT(別名:OTEL_EXPORTER_OTLP_ENDPOINTnoneOTLP 端點 URL
OTEL_HEADERS(別名:OTEL_EXPORTER_OTLP_HEADERSnone以逗號分隔的 key=value,key2=value2 標頭清單
OTEL_SERVICE_NAMElitellm資源屬性 service.name
OTEL_ENVIRONMENT_NAMEproduction資源屬性 deployment.environment
OTEL_MODEL_IDOTEL_SERVICE_NAME資源屬性 model_id
OTEL_TRACER_NAMElitellmTracer 名稱
LITELLM_METER_NAMElitellmMeter 名稱(啟用 metrics 時)
LITELLM_LOGGER_NAMElitellmLogger 名稱(啟用 events 時)
OTEL_LOGS_EXPORTERnone啟用 events 時的 logs 匯出器(例如 console

Span / metric / event 切換

變數預設值影響
USE_OTEL_LITELLM_REQUEST_SPANfalse強制讓 litellm_request 一律以 proxy root span 的子項目形式輸出。請參閱為什麼我看不到 litellm_request span?
OTEL_SEMCONV_STABILITY_OPT_INunset設為 gen_ai_latest_experimental 以切換到最新的 GenAI semantic conventions。依 OTEL 規格可用逗號分隔
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENTunset → 回退至舊版 message_logging(預設 TrueSPAN_AND_EVENTNO_CONTENT / SPAN_ONLY / EVENT_ONLY / SPAN_AND_EVENT。接受布林形式(trueEVENT_ONLYfalseNO_CONTENT
LITELLM_OTEL_INTEGRATION_ENABLE_METRICSfalse啟用 OTLP metrics(TTFT、TPOT、回應時間、成本、token 使用量、操作時間)
LITELLM_OTEL_INTEGRATION_ENABLE_EVENTSfalse啟用 OTLP 語意 logs(gen_ai.content.prompt/gen_ai.content.completion,或 semconv 模式中的 gen_ai.client.inference.operation.details
OTEL_IGNORE_CONTEXT_PROPAGATIONfalse若為 true,忽略傳入的 traceparent 標頭與任何作用中的 span——每個 LiteLLM trace 都會成為自己的 root
OTEL_DEBUG / DEBUG_OTELfalse將 exporter 與 span 建立診斷輸出到 stderr
litellm.turn_off_message_logging(Python global / litellm_settings.turn_off_message_loggingfalse內容擷取的總開關。會抑制 llm.{provider}.* 原始請求/回應、gen_ai.input.messagesgen_ai.output.messages,以及 gen_ai.content.* 記錄事件。會覆寫每個 handler 的 capture_message_content

每請求去識別化(request metadata

可在 metadata 中傳入的每請求 key,用於在不全域停用記錄的情況下,去識別化單一呼叫。

Key影響
mask_inputtrue 時,去識別化此請求的輸入訊息
mask_outputtrue 時,去識別化此請求的輸出訊息
update_trace_keys控制在延續現有 trace 時,哪些 trace keys(inputoutput)會被取代
generation_name以此值覆寫 raw_gen_ai_request span 的名稱

OpenTelemetryConfig 程式化等價設定

欄位預設值用途
exporterconsoleOTEL_EXPORTER
endpointOTEL_ENDPOINT
headersOTEL_HEADERS
enable_metricsfalseLITELLM_OTEL_INTEGRATION_ENABLE_METRICS
enable_eventsfalseLITELLM_OTEL_INTEGRATION_ENABLE_EVENTS
capture_message_contentenv var每個處理器的覆寫;與 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT 相同的值空間
semconv_stabilityenv varOTEL_SEMCONV_STABILITY_OPT_IN
skip_set_globalfalse不要宣告程序全域的 TracerProvider/MeterProvider/LoggerProvider
ignore_context_propagationfalseOTEL_IGNORE_CONTEXT_PROPAGATION
attributes指標屬性包含/排除過濾器。請參閱 控制指標屬性基數

附錄:Span、Metric 與屬性參考

本附錄列舉 LiteLLM 發出的每一個 span、metric 與 AI 語義屬性,包括在啟用 semconv 模式 時各自如何變化。

Span 參考

LLM 呼叫 span 是 AI 語義的核心。其名稱、類型與支援的子 span 取決於 semconv 模式是否啟用。

Span類型預設模式Semconv 模式
Proxy request frameSERVERReceived Proxy Server RequestReceived Proxy Server Request(不變)
LLM-call spanINTERNAL(預設) / CLIENT(semconv)litellm_request(僅在 USE_OTEL_LITELLM_REQUEST_SPAN=true 時);否則屬性會落在 proxy frame span 上{operation} {model}(例如 chat gpt-4embeddings text-embedding-3-small);與預設模式相同的 USE_OTEL_LITELLM_REQUEST_SPAN 閘控
原始提供者負載INTERNALraw_gen_ai_request(在允許擷取訊息內容時)不會發出(資料存在 LLM-call span 與彙總事件中)
防護欄檢查INTERNAL每次防護欄呼叫一個 span,依防護欄命名不變
管理端點INTERNAL每次 proxy 管理呼叫一個 span,依端點命名不變

semconv 模式下發出的 operation 名稱:chat(預設)、embeddings(當呼叫類型包含 embedding 時)、text_completion(當呼叫類型包含 text_completion 時)。

事件參考

當在設定中啟用 LoggerProvider 時,事件會落在 LiteLLM 管理的 enable_events=True 上。

事件預設模式Semconv 模式
每則訊息的 promptgen_ai.content.prompt(每個輸入訊息一個事件)由彙總事件取代
每個選項的 completiongen_ai.content.completion(每個選項一個事件)由彙總事件取代
彙總的推論詳細資料不會發出gen_ai.client.inference.operation.details(每次呼叫一個事件,依規格承載 gen_ai.input.messagesgen_ai.output.messages 陣列)

Metric 參考

當在 OpenTelemetryConfig 上設定 enable_metrics=True 時,LiteLLM 會發出下列 histogram。Metric 名稱符合 OTEL GenAI 語義慣例。

指標單位說明
gen_ai.client.operation.durations包含 LiteLLM 額外負擔的端到端操作持續時間。
gen_ai.client.token.usage{token}Token 用量。每次呼叫記錄兩個 histogram(標籤 gen_ai.token.type"input""output")。
gen_ai.client.token.costUSD計算出的請求成本。
gen_ai.client.response.time_to_first_tokens從請求開始到第一個串流 token 的時間(僅限串流請求)。
gen_ai.client.response.time_per_output_tokens每個輸出 token 的平均時間(生成時間 / completion token)。
gen_ai.client.response.durationsLLM API 生成時間,不含 LiteLLM 額外負擔。

每個 histogram 的共同標籤:gen_ai.operation.namegen_ai.systemgen_ai.request.modelgen_ai.framework="litellm"

常見 metric 需求指標
TTFTgen_ai.client.response.time_to_first_token
TPS1 / gen_ai.client.response.time_per_output_token 推導
Token 用量gen_ai.client.token.usage(依 gen_ai.token.type 拆分)
提供者/模型延遲(不含額外負擔)gen_ai.client.response.duration
提供者/模型延遲(含額外負擔)gen_ai.client.operation.duration

Spans → 推導出的 Metric

即使關閉 metric,下面每個 metric 也都可以從 span 推導出來。這也是大多數儀表板的作法。

指標如何從 span 推導
TTFT(Time to First Token)僅限串流請求。使用專用的 gen_ai.client.response.time_to_first_token metric,或透過自訂回呼從請求 kwargs 擷取 completion_start_time
TPOT(Time per Output Token)使用 gen_ai.client.response.time_per_output_token metric,或推導為 gen_ai.client.response.duration ÷ gen_ai.usage.output_tokens
總回應持續時間gen_ai.client.response.duration metric,或 LLM-call span 的 end_time − start_time(或 proxy root span 減去 LiteLLM 額外負擔——請參閱 hidden_params.litellm_overhead_time_ms)。
提供者(提供者)延遲raw_gen_ai_request span 的持續時間(預設模式)——純粹等待上游提供者的時間。在 semconv 模式下,使用 gen_ai.client.response.duration
LiteLLM 額外負擔proxy root span 上的 hidden_params.litellm_overhead_time_ms。或 Received Proxy Server Request.duration − raw_gen_ai_request.duration
Token 用量LLM span 上的 gen_ai.usage.input_tokensgen_ai.usage.output_tokensgen_ai.usage.total_tokens(或 gen_ai.client.token.usage metric)。
成本LLM span 上的 gen_ai.cost.total_cost(以及 gen_ai.cost.* 的其餘部分);或 gen_ai.client.token.cost metric。
防護欄評估時間每個 guardrail span 的持續時間。以 guardrail_nameguardrail_mode 區分。
Router / 驗證 / Redis / DB 延遲對應 service-hook span 的持續時間(routerauthredispostgres、…)。
重試 / 備援次數proxy root span 上的 hidden_params.x-litellm-attempted-retrieshidden_params.x-litellm-attempted-fallbacks
串流?llm.is_streaming 屬性("True"/"False")。

屬性參考

設定在 LLM-call span 上的屬性。名稱遵循 OTEL GenAI semconv

屬性預設模式Semconv 模式
gen_ai.operation.namelitellm call_type(例如 acompletionsemconv operation(chatembeddingstext_completion
gen_ai.system提供者名稱(例如 openai不變
gen_ai.provider.name未設定提供者名稱(依規格重新命名的 Required 屬性)
gen_ai.frameworklitellmlitellm
gen_ai.request.modelmodelmodel
gen_ai.request.max_tokenstemperaturetop_p在請求中設定時在請求中設定時
gen_ai.request.frequency_penaltypresence_penaltytop_kseedstop_sequencesstreamchoice.count未設定在請求中設定時
gen_ai.response.modelgen_ai.response.idgen_ai.response.finish_reasons在回應中出現時不變
gen_ai.usage.input_tokensgen_ai.usage.output_tokensgen_ai.usage.total_tokens在出現時不變
gen_ai.usage.cache_creation.input_tokensgen_ai.usage.cache_read.input_tokens未設定在回應中出現時
gen_ai.input.messagesgen_ai.output.messagesgen_ai.system_instructions當訊息內容擷取允許時,為 JSON 編碼的 {role, parts: [...]} 物件陣列不變
gen_ai.cost.input_costoutput_costtotal_cost(以及相關的成本明細 attrs)LiteLLM 特定的成本屬性不變

gen_ai.cost.*(成本明細,所有模式)

LiteLLM 會將 standard_logging_payload["cost_breakdown"] 中的每個鍵展開為 gen_ai.cost.{key}。目前可觀察到的鍵:

屬性含義
gen_ai.cost.input_costPrompt token 成本(USD)
gen_ai.cost.output_costCompletion token 成本(USD)
gen_ai.cost.total_cost收費總額(USD)
gen_ai.cost.tool_usage_cost可歸因於 tool/function 呼叫的成本
gen_ai.cost.original_cost折扣前成本
gen_ai.cost.discount_percentgen_ai.cost.discount_amount套用的折扣
gen_ai.cost.margin_percentgen_ai.cost.margin_fixed_amountgen_ai.cost.margin_total_amount利潤率組成項目

litellm.*(代理根節點與 LLM span)

屬性
litellm.call_id每次 litellm.completion 呼叫皆唯一。請用此將 trace 資料與 LiteLLM Spend Logs 及 LiteLLM UI 進行關聯
litellm.request.typecall_type 相同(例如 acompletionaembeddingaimage_generation

llm.*(代理根節點與 LLM span)

屬性
llm.request.typeLiteLLM call_type
llm.is_streaming"True""False"
llm.useruser 參數(若已設定)

llm.{provider}.*(原始提供者請求/回應,僅預設模式)

raw_gen_ai_request 上設定,以避免屬性重複。對於原始提供者請求本文中的每個鍵,LiteLLM 會輸出 llm.{provider}.{key}。原始回應本文亦同。

openai 的可觀察範例:

llm.openai.messages
llm.openai.model
llm.openai.temperature
llm.openai.max_tokens
llm.openai.id
llm.openai.object
llm.openai.created
llm.openai.choices
llm.openai.usage
llm.openai.system_fingerprint
llm.openai.service_tier
llm.openai.extra_body

對於 Anthropic,將 openai 替換為 anthropicllm.anthropic.messagesllm.anthropic.stop_reason 等)。其他每個提供者也採用相同模式。

OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=NO_CONTENT、當 litellm.turn_off_message_logging=true,或在 semconv 模式下(整個 raw_gen_ai_request span 都會被抑制)時,這些屬性會被抑制。

metadata.*(代理根節點,有時為 LLM span)

LiteLLM 會迭代 standard_logging_payload["metadata"],並將每個項目輸出為 metadata.{key}。常見鍵(非完整):

屬性含義
metadata.user_api_key_hash使用之虛擬金鑰的 SHA 雜湊
metadata.user_api_key_alias虛擬金鑰別名
metadata.user_api_key_team_idmetadata.user_api_key_team_alias團隊識別碼
metadata.user_api_key_org_idmetadata.user_api_key_org_alias組織識別碼
metadata.user_api_key_user_idmetadata.user_api_key_user_emailLiteLLM 內部使用者識別碼
metadata.user_api_key_end_user_id在請求中傳入的終端使用者
metadata.user_api_key_project_idmetadata.user_api_key_project_alias專案識別碼
metadata.user_api_key_spendmetadata.user_api_key_max_budgetmetadata.user_api_key_budget_reset_at預算狀態
metadata.user_api_key_request_route路由命中(例如 /v1/chat/completions
metadata.requester_ip_addressmetadata.user_agent用戶端識別碼
metadata.requester_metadatametadata.requester_custom_headers標頭與請求內容
metadata.applied_guardrails本次請求執行的防護欄清單
metadata.mcp_tool_call_metadatametadata.vector_store_request_metadataMCP 與向量儲存請求資訊
metadata.usage_object完整 token 用量物件
metadata.spend_logs_metadata持久化到 Spend Logs 的自訂中繼資料
metadata.cold_storage_object_key當請求負載卸載到冷儲存時
metadata.user_api_key_auth_metadata額外驗證內容

另外還有 hidden_params——一個單一屬性,內含 JSON 序列化的 dict,其中包括 litellm_overhead_time_msapi_baseresponse_costadditional_headersmodel_idx-litellm-attempted-retriesx-litellm-attempted-fallbacks 等。

防護欄 span 屬性

設定於每個 guardrail 子 span:

屬性
openinference.span.kind"guardrail"(依 OpenInference 慣例)
guardrail_name例如 "presidio-pii""lakera""aporia"
guardrail_mode"pre_call""during_call""post_call"
masked_entity_count若防護欄遮罩了實體
guardrail_response防護欄的回應/動作

該 span 的 start_time/end_time 來自防護欄本身的計時,因此 span 持續時間等於 防護欄評估時間

目前沒有獨立的 guardrail_pre/guardrail_post span 名稱——兩者都會以 guardrail 輸出,並透過 guardrail_mode 屬性加以區分。

服務回呼 span 屬性

請參閱 Service-hook spans。每個都包含 servicecall_type、可選的 error,以及呼叫端附加的任何自訂事件中繼資料。

例外狀況屬性

Failed Proxy Server Request(以及任何失敗的 LLM 呼叫 span)上:

屬性
exceptionstr(original_exception)
Span statusStatusCode.ERROR

資源屬性(每個 span)

屬性預設值覆寫
service.namelitellmOTEL_SERVICE_NAME
deployment.environmentproductionOTEL_ENVIRONMENT_NAME
model_idservice.name 相符OTEL_MODEL_ID
telemetry.sdk.{language,name,version}由 SDK 設定

穩定性

Span 名稱、metric 名稱,以及上述屬性集在 LiteLLM 的 patch 版本之間是穩定的。LLM 呼叫 span 的名稱與種類會在 預設模式與 Semconv 模式 之間變更,並透過文件所述的 opt-in flag 進行遷移,而非在版本之間變更。

支援

如有 LiteLLM OTEL 整合問題,請到 BerriAI/litellm 提出 issue。若有 OpenLLMetry / Traceloop semantic-convention 問題,請參閱 Slack 或寄信至 dev@traceloop.com