Features

OpenTelemetry

BitRouter 原生支持 OpenTelemetry——为每次请求生成 trace 与指标,通过 OTLP 导出到你运行的任意后端。本页的一切都是开源的,运行在你自己的基础设施上。

BitRouter 原生支持 OpenTelemetry。你经路由器发送的每一次请求都会变成一条 trace——覆盖从入口、路由、每一次上游尝试(包括故障转移)到结算的完整生命周期——外加一组指标,全部遵循 OpenTelemetry GenAI 语义约定,并通过 OTLP 推送到你已经在运行的任意后端。

本页的一切都是开源的,完全运行在你自己的基础设施上——中间不存在任何 BitRouter 的遥测端点。它在你为它指定目标之前都是关闭的,且默认不导出消息内容。如果你不想运维一个 collector,BitRouter Cloud 提供一个无需运维的托管请求视图。

一条 trace 长什么样

每次请求产生一棵 span 树:

HTTP SERVER  POST /v1/chat/completions        (入口)
└─ chat      (INTERNAL, 入站 —— 整个请求生命周期)
   ├─ route  (INTERNAL —— 路由决策)
   ├─ chat   (CLIENT —— 上游尝试 #1,带 gen_ai.* 属性)
   ├─ chat   (CLIENT —— 故障转移尝试 #2)
   └─ settle (INTERNAL —— 结算汇总)

每次请求只有一个 GenAI generation——即入站的 chat span。每一次上游尝试都是 独立的 CLIENT span,因此一条故障转移链会按顺序展示它尝试过的每个 provider,以及 每一跳的延迟与结果。BitRouter 会提取入站的 W3C trace context 并注入出站的 traceparent,让路由器的 span 接入来自你的 agent 或网关的父 trace。由于每一次尝试 都是独立的 span,trace 正是故障转移与路由行为变得清晰可读的地方:先尝试了哪个 provider、为何回退、以及整条链上延迟去了哪里。

span 属性

属性说明
gen_ai.provider.name该跳的上游 provider(如 openaianthropic
gen_ai.response.model实际服务该响应的模型
gen_ai.token.typeinput / output,标注在 token 度量上
outcome请求的最终处置
api_key_iduser_id调用方归因(受基数上限约束)
account_label逻辑账户/租户标签

开启导出

bitrouter-observe 插件下加一个 otel 块并给它一个端点,仅此即可开启导出:

plugins:
  bitrouter-observe:
    otel:
      endpoint: "http://localhost:4318"   # 你的 OTLP 端点
      service_name: "bitrouter"

把密钥排除在提交的文件之外——任何鉴权 header 都用 ${VAR} 引用,加载时从环境解析:

plugins:
  bitrouter-observe:
    otel:
      endpoint: "https://api.honeycomb.io"
      headers:
        x-honeycomb-team: "${HONEYCOMB_API_KEY}"

每个字段都有对应的环境变量覆盖项,因此你无需修改文件即可配置导出——在容器中尤其方 便,你完全可以不写 otel 块:

环境变量设置
OTEL_EXPORTER_OTLP_ENDPOINTOTLP 端点 URL
OTEL_EXPORTER_OTLP_HEADERS鉴权 header(逗号分隔的 k=v
OTEL_SERVICE_NAME资源 service 名称
OTEL_RESOURCE_ATTRIBUTES额外资源属性(逗号分隔的 k=v
OTEL_TRACES_SAMPLER采样器类型
OTEL_TRACES_SAMPLER_ARG采样器参数(如比率)
BITROUTER_OBSERVE_CONTENT_CAPTURE内容捕获模式

OTLP 传输层在编译二进制时选择:otel-http(OTLP/HTTP + protobuf,默认)或 otel-grpc(OTLP/gRPC)。本页的配置对两者完全一致——只有当你的后端只支持其中一种 时才需要关心传输层。

指标

除 trace 外,指标也按间隔(默认 60 秒)通过 OTLP 导出:

指标类型度量
bitrouter.requestsCounter已处理请求数
gen_ai.client.operation.durationHistogram请求延迟
gen_ai.client.token.usageHistogramtoken 计数(按 gen_ai.token.type
bitrouter.errorsCounter错误数
bitrouter.stream_partsCounter发出的流式分片数

维度包括 gen_ai.provider.namegen_ai.response.modeloutcomeaccount_label 以及调用方标识。为在共享部署上控制指标基数,api_key_iduser_id 设有上限(默认 1024 与 256 个不同值);超过上限后,值会归入一个溢出桶。

没有 Prometheus 抓取端点GET /metrics 已退役——指标仅通过 OTLP 推送。如果你 的技术栈基于 Prometheus,请通过带 Prometheus exporter 的 OpenTelemetry Collector 接入。

各后端配置

下面每个块都是某个常见后端的 plugins.bitrouter-observe.otel 配置。

OpenTelemetry Collector

把所有数据发往本地或集群内的 Collector,再由它分发到你真正的后端(这也是接入基于 Prometheus 的技术栈的途径——Collector 的 Prometheus exporter 弥补了 BitRouter 没有 抓取端点这一点):

otel:
  endpoint: "http://otel-collector:4318"
  service_name: "bitrouter"
  resource_attributes:
    deployment.environment: "prod"

Honeycomb

otel:
  endpoint: "https://api.honeycomb.io"
  service_name: "bitrouter"
  headers:
    x-honeycomb-team: "${HONEYCOMB_API_KEY}"

Grafana Cloud / Tempo

Grafana Cloud 的 OTLP 网关使用 basic auth(实例 ID + API token,base64 编码)。自托 管的 Tempo 则指向它的 OTLP 端口并去掉 header。

otel:
  endpoint: "https://otlp-gateway-<region>.grafana.net/otlp"
  service_name: "bitrouter"
  headers:
    Authorization: "Basic ${GRAFANA_OTLP_TOKEN}"

Datadog

Datadog 通过 Datadog Agent 而非公开 OTLP URL 接收 OTLP——以启用 OTLP 接收的方式运行 Agent,并把 BitRouter 指向它:

otel:
  endpoint: "http://datadog-agent:4318"
  service_name: "bitrouter"
  resource_attributes:
    deployment.environment: "prod"

调节采样

默认情况下 BitRouter 遵循入站的 trace 决策,否则采样全部(parentbased_always_on)。 在高吞吐下,改为采样一部分:

otel:
  endpoint: "http://otel-collector:4318"
  sampler: "parentbased_traceidratio"
  sampler_arg: 0.1                       # 保留 10% 的根 trace
sampler行为
always_on采样每一条 trace
always_off全部不采样
traceidratio按比例(sampler_arg)采样,忽略父级
parentbased_always_on跟随父级;无父级时采样 (默认)
parentbased_always_off跟随父级;无父级时丢弃
parentbased_traceidratio跟随父级;否则按 sampler_arg 采样

parentbased_* 变体会尊重上游的决策,因此你的 agent 发起的 trace 不会在路由器处被 “半采样”。指标导出间隔与 trace 批处理队列可分别在 metricstraces.batch 下调节, 以在新鲜度与开销之间权衡。

内容捕获

prompt 与响应内容默认不导出content_capture: off)。仅当你需要在 span 上看到 prompt 与响应正文用于调试时才开启:

otel:
  content_capture: "full"   # off(默认) | full

full 会把用户 prompt 与模型响应写入你的遥测后端,这些内容随后将继承该后端的访问 控制与保留策略。在共享或受监管的环境中,请保持 off,仅在受限、短时的调试会话中捕获 内容。

验证

reload(或重启)路由器,然后询问运行中的守护进程它在做什么:

bitrouter reload                  # 不中断连接地应用配置变更
bitrouter observe status          # 端点、采样器、基数、在途 span
bitrouter observe status --json

如果它报告 stopped,说明导出器未接好——检查 otel 块是否有 endpoint(或是否设置 了 OTEL_EXPORTER_OTLP_ENDPOINT),以及二进制是否带某个 OTLP 传输特性编译。然后通过 路由器发一个请求,确认 trace 进入你的后端;你应当看到每次请求有一个入站 chat span, 每次上游尝试有一个 CLIENT 子 span。

下一步

How is this guide?

On this page