客户端跟踪
Supabase 的 JS、Swift、Dart 和 Python SDK 可以在外发请求中附加 W3C Trace Context 头(traceparent、tracestate、baggage)。生成的 trace_id 会在 Supabase 服务中流动,并出现在 API Gateway 和 Edge Function 的日志中,这样你就可以将客户端的跨度与它们产生的服务器端日志关联起来——端到端,跨越网络边界。
🌐 The Supabase JS, Swift, Dart and Python 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)都能在服务端捕获到追踪信息,包括在自托管的收集器中。在客户端,一些厂商的 SDK 在发送标准头部之前需要做一个小的配置修改 —— 详见 JavaScript 标签下的 使用厂商追踪 SDK。
🌐 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. On the client side, some vendor SDKs need a small configuration change before they emit the standard headers — see Using a vendor tracing SDK in the JavaScript tab.
要求 #
🌐 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:
import '@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:
import '@supabase/supabase-js/tracing'import { trace } from '@opentelemetry/api'import { createClient } from '@supabase/supabase-js'const supabase = createClient(SUPABASE_URL, SUPABASE_KEY, { tracePropagation: true,})const tracer = trace.getTracer('my-app')await tracer.startActiveSpan('fetch-users', async (span) => { // Outgoing request carries the active trace context. const { data, error } = await supabase.from('users').select('*') span.end()})为了安全起见,追踪头只会附加到针对 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.
从浏览器调用开启 trace 传播的 Edge Functions 需要函数的 CORS 允许列表中包含 trace 头。在函数中,从 npm:@supabase/supabase-js@^2.112.3/cors 导入 corsHeaders,或者将 traceparent、tracestate 和 baggage 添加到你自己的允许列表,然后重新部署该函数。参见 Edge Functions 的 CORS 支持。
🌐 Calling Edge Functions from the browser with trace propagation enabled requires the function's CORS allow-list to include the trace headers. In the function, import corsHeaders from npm:@supabase/supabase-js@^2.112.3/cors or add traceparent, tracestate, and baggage to your own allow-list, then redeploy the function. See CORS support for Edge Functions.
高级设置 #
🌐 Advanced configuration
传入一个对象而不是 true 来进行更精细的控制:
🌐 Pass an object instead of true for fine-grained control:
import '@supabase/supabase-js/tracing'const supabase = createClient(SUPABASE_URL, SUPABASE_KEY, { tracePropagation: { enabled: true, // Default: true. Non-sampled requests carry only `traceparent` (with the // sampled flag preserved, so nothing is recorded downstream) — log // correlation keeps working while `tracestate` and `baggage` are withheld. // Set to false to always send the full trace context regardless of sampling. respectSamplingDecision: false, },})| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enabled | boolean | false | 启用追踪传播。 |
respectSamplingDecision | boolean | true | 当 true 时,未采样的请求只发送 traceparent(保留采样标志),并省略 tracestate 和 baggage;false 总是发送完整的追踪上下文。在 2.112.3 之前的版本中,true 会跳过未采样请求的所有追踪头。 |
使用供应商追踪 SDK #
🌐 Using a vendor tracing SDK
许多追踪 SDK 都是建立在 OpenTelemetry 之上的,但它们在 propagator 是否默认发送标准的 traceparent 头部上有所不同:
🌐 Many tracing SDKs are built on top of OpenTelemetry, but they differ in whether their propagator emits the standard traceparent header by default:
| 供应商设置 | 能与 tracePropagation 一起使用吗? | 必需的配置 |
|---|---|---|
| OpenTelemetry SDK(也支持 Honeycomb、Grafana、New Relic 通过 OTLP) | 是 | 无 — 默认使用 W3C 传播器 |
| Sentry(Node.js,包括 Next.js 服务器端) | 是的,只需一个标志 | 在 Sentry.init() 中设置 propagateTraceparent: true —— Sentry 的传播器默认会忽略 traceparent |
| Sentry(浏览器) | 通过 Sentry 自身的监控工具 | 设置 propagateTraceparent: true 并将你的项目 URL(https://<ref>.supabase.co)添加到 tracePropagationTargets —— Sentry 的浏览器 SDK 只会为列出的目标附加跨域头。对于 Edge Functions,还需将 sentry-trace 添加到函数的 CORS 允许列表:Sentry 总是会发送它自己的头,这个头不属于 corsHeaders |
Datadog dd-trace(Node.js) | 开箱即用 | 无 — dd-trace 甚至在没有 tracePropagation 的情况下,也会在 HTTP 层注入 W3C 头 |
| Datadog 浏览器 RUM | 是的,需要配置 | 将你的项目 URL 添加到 allowedTracingUrls,使用 tracecontext 传播类型 |
如果一个传播器处于激活状态但没有发送 traceparent,SDK 会在控制台记录一次性警告,列出传播器写入的头信息(从 2.112.3 版本开始)。
🌐 If a propagator is active but doesn't emit traceparent, the SDK logs a one-time console warning naming the headers the propagator wrote (version 2.112.3 and later).
故障排除 #
🌐 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 的传播器不会发送 W3C
traceparent。 例如,Sentry 的传播器只有在设置了propagateTraceparent: true时才会发送。从2.112.3版本开始,SDK 会记录一次性警告,列出传播器写入的头信息——详见 使用厂商追踪 SDK。 - 上游追踪未被采样(
2.112.3之前的版本)。旧版本在上游追踪未被采样时会跳过所有追踪头。从2.112.3开始,未采样的请求仍然会携带traceparent,因此日志关联默认依然有效。将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.