集成原生OpenTelemetry

通过 OpenTelemetry 实现 LLM 可观测性

OpenTelemetryCNCF 项目,提供一套规范、API 和库,定义了从应用收集分布式 trace 和指标的标准方式。

Litefuse 可以作为 OpenTelemetry Backend 工作,在 /api/public/otel(OTLP)端点接收 trace。除了 Langfuse SDK原生集成 之外,这个 OpenTelemetry 端点旨在提升与 SDK 与原生集成之外的框架、库和语言的兼容性。常用的 OpenTelemetry 库包括 OpenLLMetry 和 OpenLIT,它们将 Litefuse tracing 的语言支持扩展到 Java 与 Go,并覆盖 AutoGen、Semantic Kernel 等框架。

由于 GenAI trace 属性的 Semantic Conventions 仍在演进中,Litefuse 会将收到的 OTel trace 映射到 Litefuse 数据模型,并支持 OTel GenAI 生态中常见的额外属性(属性映射)。如果某个集成未按预期工作或没有解析到正确的属性,请 提交 issue

同时使用其他基于 OTEL 的工具? 如果你将 Litefuse 与其他基于 OpenTelemetry 的工具一起使用,可能会出现冲突。配置指引见 将 Litefuse 与已有的 OpenTelemetry 设置一起使用

接入选项

OpenTelemetry 原生 Langfuse SDK v3

最快开始使用 Litefuse 进行 tracing 的方式是新的 OTEL 原生 Langfuse SDK v3。该 SDK 是官方 OpenTelemetry 客户端之上的薄层,会自动将发出的 span 转换为丰富的 Litefuse observation(spans、generations、events 以及 其他 observation 类型),并为 token 用量、成本追踪、prompt 关联和打分等 LLM 专属能力提供一等公民式的辅助函数。

由于它运行在共享的 OpenTelemetry 上下文中,其他被 OTEL 插桩的库产生的 span 也可以被导出到 Litefuse。默认情况下,Litefuse 会聚焦于与 LLM 相关的 span(Langfuse SDK 的 span、带 gen_ai.* 属性的 span,以及已知的 LLM instrumentor)。如需导出全部内容,可以按 SDK 进阶文档 中的说明使用宽松的自定义过滤器。

可以从这里的 Python 实现专属指南开始:/docs/observability/sdk/overview

OpenTelemetry 端点

Litefuse 可以在 /api/public/otel(OTLP)端点接收 trace。

如果你使用的是基于 OpenTelemetry SDK 导出 trace 的 Collector,可以使用以下配置:

OTEL_EXPORTER_OTLP_ENDPOINT="https://litefuse.cloud/api/public/otel"
# OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:3000/api/public/otel" # 🏠 Local deployment (>= v3.22.0)
 
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic ${AUTH_STRING}"

Litefuse 使用 Basic Auth 来鉴权请求。

可以使用以下命令获取 base64 编码后的 API Key(即 AUTH_STRING):echo -n "pk-lf-1234567890:sk-lf-1234567890" | base64。 对于较长的 API Key,在 GNU 系统上你可能需要在末尾加上 -w 0,因为 base64 默认会自动按列换行。

如果你的 collector 需要按信号类型设置环境变量,trace 端点是 /api/public/otel/v1/traces

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://litefuse.cloud/api/public/otel/v1/traces"

请注意,Litefuse 目前支持基于 HTTP 的 OTLP,包括 HTTP/JSONHTTP/protobufgRPC 暂不支持。

通过 OpenTelemetry SDK 自定义

你可以使用 OpenTelemetry SDK,按上述配置直接将 trace 导出到 Litefuse。这样 Litefuse 的语言支持就被扩展到 Langfuse SDK(Python 与 JS/TS)之外的语言。

使用 OpenTelemetry GenAI 插桩库

任何兼容 OpenTelemetry 的插桩都可以用来将 trace 导出到 Litefuse。可以参考下面这些常用插桩 SDK 的端到端示例来快速开始:

OpenTelemetry 插桩库对比
类别项目OpenLLMetryopenlitArize
LLMsAI21
Aleph Alpha
Amazon Bedrock
Anthropic
Assembly AI
Azure AI Inference
Azure OpenAI
Cohere
DeepSeek
ElevenLabs
GitHub Models
Google AI Studio
Google Generative AI (Gemini)
Groq
HuggingFace
IBM Watsonx AI
Mistral AI
NVIDIA NIM
Ollama
OpenAI
OLA Krutrim
Prem AI
Replicate
SageMaker (AWS)
Titan ML
Together AI
vLLM
Vertex AI
xAI
Vector DBsAstraDB
Chroma
ChromaDB
LanceDB
Marqo
Milvus
Pinecone
Qdrant
Weaviate
FrameworksAutoGen / AG2
ControlFlow
CrewAI
Crawl4AI
Dynamiq
EmbedChain
FireCrawl
Guardrails AI
Haystack
Julep AI
LangChain
LlamaIndex
Letta
LiteLLM
mem0
MultiOn
Phidata
SwarmZero
LlamaIndex Workflows
LangGraph
DSPy
Prompt flow
Instructor
GPUsAMD Radeon
NVIDIA
JavaScriptOpenAI Node SDK
LangChain.js
Vercel AI SDK

基于 OpenTelemetry 的框架集成

从 OpenTelemetry Collector 导出

如果你运行了 OpenTelemetry Collector,可以使用以下配置将 trace 导出到 Litefuse:

receivers:
  otlp:
    protocols:
    grpc:
      endpoint: 0.0.0.0:4317
    http:
      endpoint: 0.0.0.0:4318
 
processors:
  batch:
  memory_limiter:
    # 80% of maximum memory up to 2G
    limit_mib: 1500
    # 25% of limit up to 2G
    spike_limit_mib: 512
    check_interval: 5s
 
exporters:
  otlphttp/litefuse:
    endpoint: "https://litefuse.cloud/api/public/otel"
    headers:
      Authorization: "Basic ${AUTH_STRING}" # Previously encoded API keys
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/litefuse]

过滤发送到 Litefuse 的 span

如果你希望有选择地将 OTel span 发送给 Litefuse,可以使用 OTel Collector 的 filterprocessor。 它允许你基于属性、span 名称等条件来过滤 span。 由于过滤是在 span 级别生效的,你可能会得到不完整的 trace,所以在使用复杂过滤规则时要谨慎。 Litefuse 还要求 root span 必须发送到我们的后端,以便正确创建 trace。

下面的配置只会转发 gen_ai.system 属性等于 openai 的 span:

receivers:
  otlp:
    protocols:
    grpc:
      endpoint: 0.0.0.0:4317
    http:
      endpoint: 0.0.0.0:4318
 
processors:
  filter/openaisystem:
    error_mode: ignore
    traces:
      span:
        - 'attributes["gen_ai.system"] != "openai"'
 
exporters:
  otlphttp/litefuse:
    endpoint: "https://litefuse.cloud/api/public/otel"
    headers:
      Authorization: "Basic ${AUTH_STRING}" # Previously encoded API keys
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [filter/openaisystem]
      exporters: [otlphttp/litefuse]

属性映射

Litefuse 致力于兼容 OpenTelemetry GenAI 语义约定 并支持主流的 LLM 插桩框架。

此外,Litefuse 在 langfuse.* 命名空间下使用一些属性,把 OpenTelemetry span 属性直接映射到 Litefuse 数据模型。这些专属属性始终优先于通用的 OpenTelemetry 约定,推荐所有手动插桩应用的用户使用。

如果某个映射或集成未按预期工作或没有解析到正确的属性,请 在 GitHub 上提 issue

Litefuse 区分 trace 级别属性和 observation 级别属性。

  • Trace 级别属性 表示整次交互的共享上下文。如果 Litefuse 在某个 span 上检测到这些属性,会把它们当作整个 trace 的属性。
  • Observation 级别属性 描述 trace 内的单个步骤。Litefuse 会将它们保留在 observation 级别。

元数据映射的工作方式

OpenTelemetry span 可以携带任意属性。Litefuse 会根据它们的命名方式以不同方式处理这些属性:

属性类型在 Litefuse 中的位置示例
显式元数据映射metadata 中的一级 key(可过滤)langfuse.trace.metadata.customer_tiermetadata.customer_tier
未映射的 OTel 属性嵌套在 metadata.attributes 下(兜底)http.methodmetadata.attributes.http.method
资源属性嵌套在 metadata.resourceAttributesservice.namemetadata.resourceAttributes.service.name

Langfuse SDK 与标准 OpenTelemetry SDK

  • Langfuse SDK 提供了一些工具函数(比如带 metadata 参数的 update()),它们会自动设置带 langfuse.*.metadata.* 前缀的属性。这意味着自定义元数据会出现在一级 key 中并可被过滤。
  • 标准 OpenTelemetry SDK 会直接把属性设置在 span 上。除非你显式使用 langfuse.trace.metadata.*langfuse.observation.metadata.* 前缀,否则这些属性会落入 metadata.attributes 兜底区域,无法在 Litefuse 中直接被过滤。

将 trace 属性传播到所有 span

当你使用 OpenTelemetry 插桩将 trace 发送到 Litefuse 时,某些 trace 级别的属性应该被传播到 trace 内的 所有 span,以便在 Litefuse 中进行准确的聚合与过滤。这些属性包括:

  • userId(通过 langfuse.user.iduser.id
  • sessionId(通过 langfuse.session.idsession.id
  • metadata(通过 langfuse.trace.metadata.* 设置顶级 metadata key)
  • version(通过 langfuse.version
  • release(通过 langfuse.release
  • tags(通过 langfuse.trace.tags

在未来某个版本中,Litefuse 的聚合查询和过滤将作用于单个 observation(span),而不仅是 trace 级别。这意味着如果你想按这些属性进行过滤或聚合,它们必须出现在 trace 中的每一个 span 上。我们强烈建议现在就实现这种传播,以便兼容未来版本的 Litefuse。

使用 OpenTelemetry Baggage 进行传播

推荐的做法是使用 OpenTelemetry Baggage 配合 BaggageSpanProcessor 把这些属性传播到所有 span。Baggage 是 OpenTelemetry 内置的上下文传播机制,可以自动把指定的键值对复制到 trace 上下文中的所有 span。

要实现这个模式:

  1. 在 trace 起始处把目标属性设置为 baggage 条目
  2. 在当前激活的 span 上设置这些属性
  3. 在你的 OpenTelemetry 设置中配置 BaggageSpanProcessor,自动把 baggage 条目复制到 span 属性上
  4. 处理器会确保 trace 上下文中所有下游 span 都收到这些属性

实现细节和代码示例可以参考 PythonJavaScript 的 OpenTelemetry 文档。

⚠️

安全注意事项:OpenTelemetry baggage 会跨服务边界传播,并被传到第三方 API。使用此方式时 不要包含敏感信息(密码、API Key、个人数据等),因为它会被传输到所有下游服务。

备选:使用 Langfuse SDK

如果你使用 Langfuse SDK 配合 OpenTelemetry 集成,可以使用便捷方法 propagate_attributes()(Python)或 propagateAttributes()(TypeScript),它们会自动处理属性传播。这些方法提供了更简洁的接口,是使用 Langfuse SDK 时的推荐做法。

Trace 级别属性

这些属性会被应用到 Litefuse 中的 trace 记录上。它们可以设置在 trace 中的任意 span 上。

Litefuse 字段描述映射自的 OTel 属性
nametrace 的名称。langfuse.trace.namestring
• root span 的 span 名称
userId终端用户的唯一标识。langfuse.user.idstring
user.idstring
sessionId用户会话的唯一标识。langfuse.session.idstring
session.idstring
release应用的发布版本。langfuse.releasestring
public布尔标志,用于将 trace 标记为公开,从而可以通过 URL 分享。langfuse.trace.publicboolean
tags用于给 trace 分类或打标签的字符串数组。langfuse.trace.tagsstring[]
metadata一个灵活对象,用于在 trace 上存放任意附加的非结构化数据。见下方说明。langfuse.trace.metadata.*string
• root span 的 observation metadata
input整个 trace 的初始输入。langfuse.trace.inputstring
• root span 的 observation input
output整个 trace 的最终输出。langfuse.trace.outputstring
• root span 的 observation output
versiontrace 的 版本,用于跟踪应用逻辑的变更。• root span 的属性映射到 version
environmenttrace 产生时所在的部署 环境• root span 的属性映射到 environment

在 Litefuse 中按 metadata key 过滤

Litefuse 只支持按事件 metadata 中的顶层 key 进行过滤。

默认情况下,所有 OpenTelemetry 属性和资源属性会被映射到 metadata 中的 attributesresourceAttributes key 下,因此无法直接查询。

如果你想按特定属性查询,可以使用 langfuse.trace.metadata 前缀,把它们映射到 trace 的顶层 metadata 对象。 下面的代码片段会在 trace 的 metadata 对象中产生一个可过滤的 user_name 属性:

with tracer.start_as_current_span("Langfuse Attributes") as span:
    span.set_attribute("langfuse.trace.metadata.user_name", "user-123")

Observation 级别属性

这些属性会应用到 trace 中的单个 observation(span)上(数据模型)。

Litefuse 字段描述映射自的 OTel 属性
typeobservation 类型。任何带有 model 属性的 span 都会被记为 generationlangfuse.observation.type"span" | "generation" | "event",默认 "span"
levelobservation 的 严重级别langfuse.observation.level"DEBUG" | "DEFAULT" | "WARNING" | "ERROR",默认 "DEFAULT"
• 由 span.status.code 推断
statusMessage描述 observation 状态的消息,常用于错误。langfuse.observation.status_messagestring
• 由 span.status.message 推断
metadata用于存放附加非结构化数据的灵活对象。见下方说明。langfuse.observation.metadata.*string
input该 observation 的输入数据。langfuse.observation.input(JSON) string
gen_ai.prompt
input.value(OpenInference)
mlflow.spanInputs(MLFlow)
output该 observation 的输出数据。langfuse.observation.output(JSON) string
gen_ai.completion
output.value(OpenInference)
mlflow.spanOutputs(MLFlow)
model所使用的生成式模型名称。仅 generation 适用。langfuse.observation.model.name
gen_ai.request.model
gen_ai.response.model
llm.model_name
model
modelParameters模型调用设置的键值对。仅 generation 适用。langfuse.observation.model.parametersJSON string
gen_ai.request.*
llm.invocation_parameters.*
usage此次 generation 的 token 计数。仅 generation 适用。langfuse.observation.usage_detailsJSON string
gen_ai.usage.*
llm.token_count.*
cost计算得到的费用(USD)。仅 generation 适用。langfuse.observation.cost_detailsJSON string
gen_ai.usage.cost(设为 total key)
prompt在 Litefuse 中管理的版本化 prompt 名称。仅 generation 适用。langfuse.observation.prompt.namestring
langfuse.observation.prompt.versioninteger
completionStartTime模型开始生成时的时间戳。仅 generation 适用。langfuse.observation.completion_start_timeISO 8601 date string
versionobservation 的 版本langfuse.versionstring
environmentobservation 产生时所在的部署 环境langfuse.environment
deployment.environment
deployment.environment.name

在 Litefuse 中按 metadata key 过滤

Litefuse 只支持按事件 metadata 中的顶层 key 进行过滤。

默认情况下,所有 OpenTelemetry 属性和资源属性会被映射到 metadata 中的 attributesresourceAttributes key 下,因此无法直接查询。

如果你想按特定属性查询,可以使用 langfuse.observation.metadata 前缀,把它们映射到 observation 的顶层 metadata 对象。 下面的代码片段会在 metadata 对象中产生一个可过滤的 user_name 属性:

with tracer.start_as_current_span("Langfuse Attributes") as span:
    span.set_attribute("langfuse.observation.metadata.user_name", "user-123")

故障排查

  • 如果在自托管 Litefuse 时遇到 4xx 错误,请将部署升级到最新版本。OpenTelemetry 端点最早在 Litefuse v3.22.0 引入,之后又有显著改进。
  • Litefuse 支持基于 HTTP 的 OTLP,包括 HTTP/JSONHTTP/protobufgRPC 暂不支持。
这个页面对你有帮助吗?