客户端跟踪
Supabase 的 JS、Swift 和 Dart SDK 可以在外发请求中附加 W3C Trace Context 头(traceparent、tracestate、baggage)。生成的 trace_id 会流经 Supabase 的各项服务,并出现在 API Gateway 和 Edge Function 的日志中,这样你就可以把客户端的跨度与它们在服务器端产生的日志关联起来——端到端,跨越网络边界。
🌐 The Supabase JS, Swift, and Dart SDKs can attach W3C Trace Context headers (traceparent, tracestate, baggage) to outgoing requests. The resulting trace_id flows through Supabase services and appears in API Gateway and Edge Function logs, so you can correlate client-side spans with the server-side logs they produced — end-to-end, across the network boundary.
因为这些头部遵循 W3C 标准,任何符合规范的跟踪 SDK(比如 OpenTelemetry、Sentry、Datadog 或 Honeycomb)都可以在服务器端获取这个追踪信息,包括在自托管的收集器中。
🌐 Because the headers follow the W3C standard, any compliant tracing SDK (such as OpenTelemetry, Sentry, Datadog, or Honeycomb) can pick up the trace on the server side, including in self-hosted collectors.
要求 #
🌐 Requirements
@supabase/supabase-js版本2.106.0或更高@opentelemetry/api在运行时可用——可以直接安装,也可以作为你的追踪 SDK 的传递依赖被引入- 一个追踪 SDK,它在 OpenTelemetry API 中注册了一个符合 W3C 标准的传播器
从 @supabase/supabase-js 版本 2.112.0 开始,OpenTelemetry 集成位于一个可选择的子路径,你只需在应用入口点加载一次:
🌐 As of @supabase/supabase-js version 2.112.0, the OpenTelemetry integration lives in an opt-in subpath that you load once at your application entry point:
1import '@supabase/supabase-js/tracing'主包本身不包含任何 OpenTelemetry 代码——这个导入就是用来把它接上。子路径直接导入了 @opentelemetry/api,所以你的打包工具会把它包括进来,如果没安装就会直接报错。如果在没有这个导入的情况下启用了 tracePropagation,SDK 会记录一次性警告,并发送没有 trace 头的请求。
🌐 The main bundle contains no OpenTelemetry code — this import is what wires it up. The subpath imports @opentelemetry/api directly, so your bundler includes it and module resolution fails loudly if it isn't installed. If tracePropagation is enabled without this import, the SDK logs a one-time warning and sends requests without trace headers.
在 2.106.0–2.111.x 版本中,子路径不存在 —— 不要在那里添加导入。那些版本会动态加载 @opentelemetry/api,如果缺少它,则会静默地不执行任何操作。
🌐 On versions 2.106.0–2.111.x, the subpath doesn't exist — don't add the import there. Those versions load @opentelemetry/api dynamically and silently no-op when it's missing.
通过 CDN (UMD) 构建无法进行追踪传播——那里没办法加载追踪运行时。
🌐 Trace propagation isn't available through the CDN (UMD) build — there's no way to load the tracing runtime there.
先设置 OpenTelemetry #
🌐 Set up OpenTelemetry first
SDK 会读取你全局注册的任何 TracerProvider —— 它不会为你配置一个。如果你还没有为你的应用添加监控,可以按照 OpenTelemetry JavaScript 入门指南 安装 SDK(Node 用 @opentelemetry/sdk-trace-node,浏览器用 @opentelemetry/sdk-trace-web)以及你的后台导出器(OTLP、Jaeger、Zipkin 或特定厂商的导出器)。
🌐 The SDK reads from whatever TracerProvider you register globally — it doesn't configure one for you. If you haven't instrumented your app yet, follow the OpenTelemetry JavaScript getting started guide to install an SDK (@opentelemetry/sdk-trace-node for Node, @opentelemetry/sdk-trace-web for browsers) and an exporter for your backend (OTLP, Jaeger, Zipkin, or a vendor-specific one).
Supabase SDK 只会传递在发出请求时已经激活的跟踪上下文。
🌐 The Supabase SDK only propagates the trace context that's already active when a request is made.
启用跟踪传播 #
🌐 Enable trace propagation
追踪传播是可选的,需要两个步骤:在入口点加载追踪运行时(版本 2.112.0 及更高),并在创建客户端时传入 tracePropagation: true:
🌐 Trace propagation is opt-in and takes two steps: load the tracing runtime at your entry point (version 2.112.0 and later), and pass tracePropagation: true when creating the client:
1import '@supabase/supabase-js/tracing'23import { trace } from '@opentelemetry/api'4import { createClient } from '@supabase/supabase-js'56const supabase = createClient(SUPABASE_URL, SUPABASE_KEY, {7 tracePropagation: true,8})910const tracer = trace.getTracer('my-app')1112await tracer.startActiveSpan('fetch-users', async (span) => {13 // Outgoing request carries the active trace context.14 const { data, error } = await supabase.from('users').select('*')15 span.end()16})为了安全起见,追踪头只会附加到针对 Supabase 域的请求(在本地开发中是 *.supabase.co、*.supabase.in 和 localhost)。通过自定义 fetch 调用的第三方主机从不被标记。
🌐 For security, trace headers are only attached to requests targeting Supabase domains (*.supabase.co, *.supabase.in, and localhost for local development). Third-party hosts called through a custom fetch are never tagged.
高级设置 #
🌐 Advanced configuration
传入一个对象而不是 true 来进行更精细的控制:
🌐 Pass an object instead of true for fine-grained control:
1import '@supabase/supabase-js/tracing'23const supabase = createClient(SUPABASE_URL, SUPABASE_KEY, {4 tracePropagation: {5 enabled: true,6 // Default: true. When false, headers are attached even if the7 // upstream trace is not sampled — useful when you want every8 // Supabase request tagged with a trace_id for log correlation.9 respectSamplingDecision: false,10 },11})| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enabled | boolean | false | 启用跟踪传播。 |
respectSamplingDecision | boolean | true | 如果 true,上游跟踪未采样时跳过传播。 |
使用供应商追踪 SDK #
🌐 Using a vendor tracing SDK
许多追踪 SDK 都是建立在 OpenTelemetry 之上的。只要注册了符合 W3C 标准的传播器,它们就可以按照本指南工作。一些厂商 SDK 默认只注入他们的专有头,需要额外配置才能同时发送标准的 traceparent 头。查看你厂商的 OTel 集成文档以获取具体设置。
🌐 Many tracing SDKs are built on top of OpenTelemetry. They work with this guide as long as a W3C-compliant propagator is registered. Some vendor SDKs inject only their proprietary headers by default and need extra configuration to also emit the standard traceparent header. Check your vendor's OTel integration docs for the exact setup.
故障排除 #
🌐 Troubleshooting
当 SDK 无法传播时,它从不抛出异常,这让启用它很安全,但可能掩盖配置问题。如果你的 Supabase 日志中缺少 trace_id,请按以下顺序检查:
🌐 The SDK never throws when it can't propagate, which keeps it safe to enable but can mask configuration issues. If trace_id is missing from your Supabase logs, check these in order:
- 追踪运行时未加载(版本
2.112.0及更高)。tracePropagation已启用,但你的入口点从未导入@supabase/supabase-js/tracing。SDK 会在控制台记录一次性警告,并发送不带追踪头的请求——在控制台中查找该警告。 - 请求时没有活动的 span。 SDK 会读取_当前_上下文。如果
supabase.from(...)在tracer.startActiveSpan(...)(或等效操作)之外被调用,就没有内容可以传播。把调用封装在一个 span 里,或者使用 OpenTelemetry 的自动化监控。 @opentelemetry/api没有安装 在发起请求的应用中。在2.112.0及更高版本中,跟踪子路径会直接导入它,因此缺少的包会以模块解析错误的形式出现。在2.106.0–2.111.x之间,它是动态加载的,SDK 会悄悄地不执行任何操作。- 没有注册
TracerProvider。@opentelemetry/api默认为一个不会记录的空操作提供者。在发起请求前,确保你的应用调用了provider.register()(或你的供应商 SDK 的等效方法)。 - 上游追踪未被采样。 默认情况下,SDK 会遵循上游的采样决定。设置
respectSamplingDecision: false可以在不管采样情况的情况下传递每个请求。 - 你正在通过自定义
fetch调用非 Supabase 主机。 跟踪头只会附加到 Supabase 域名(*.supabase.co、*.supabase.in、localhost)。 - 你正在使用 CDN (UMD) 版本。 追踪传播在这里不可用——追踪运行时无法从脚本标签加载。
关联 Supabase 日志 #
🌐 Correlating with Supabase logs
在追踪上下文传递之后,trace_id 出现在:
🌐 After trace context is flowing through, the trace_id appears in:
- API 网关日志 — 每一次对 PostgREST、Auth、Storage 和 Realtime 的请求
- 边缘函数日志 — 函数内部的调用记录和任何结构化日志
如果你通过 Log Drains 将 Supabase 日志转发到第三方后端,你可以使用共享的 trace_id 将 Supabase 日志与自己的客户端和服务器追踪结合起来。这对于自托管的设置尤其有用,特别是当你已经在运行自己的 OpenTelemetry 收集器时——Supabase 日志在你现有的追踪界面中就像本地数据一样。
🌐 If you forward Supabase logs to a third-party backend via Log Drains, you can join Supabase logs to your own client and server traces using the shared trace_id. This is especially useful for self-hosted setups where you already operate your own OpenTelemetry collector — Supabase logs become first-class citizens in your existing tracing UI.