diff --git a/apps/docs/content/guides/observability/advanced-log-filtering.mdx b/apps/docs/content/guides/observability/advanced-log-filtering.mdx index fc46a5c8b22..230af769df6 100644 --- a/apps/docs/content/guides/observability/advanced-log-filtering.mdx +++ b/apps/docs/content/guides/observability/advanced-log-filtering.mdx @@ -95,6 +95,39 @@ limit 100; Combine predicates with `and`, `or`, and `not`. Select only the fields needed for the investigation. To correlate sources, use an identifier present in both; a shared timestamp alone does not establish that events belong to the same request. +## Correlate requests [#correlating-requests] + +Use a request ID or trace ID to join events across sources. These fields are potentially present on any source but are not guaranteed to be populated. + +### Correlating by request ID [#request-id] + +Every API Gateway response includes an `sb-request-id` header. The gateway unpacks that value into `log_attributes['request_id']` — there is no `log_attributes['request.headers.sb-request-id']` key. To find the edge log for a known request ID: + +```sql +-- find the edge log for a given sb-request-id +select timestamp, log_attributes +from logs +where source = 'edge_logs' + and log_attributes['request_id'] = '' +limit 1; +``` + +If the response header `log_attributes['response.headers.cf_cache_status']` is `HIT`, the request was served from Cloudflare and never reached PostgREST, Auth, or Storage — no downstream logs exist for that `request_id`. + +### Fanning out by trace ID [#trace-id] + +If the client sends a `traceparent` header (W3C Trace Context), the gateway records it in `log_attributes['request.headers.traceparent']` and extracts the trace and span IDs into `log_attributes['trace_id']` and `log_attributes['span_id']`. Use the `trace_id` to correlate across all sources: + +```sql +-- correlate across all sources by trace_id +select source, timestamp, log_attributes +from logs +where log_attributes['trace_id'] = '' +order by timestamp; +``` + +See [Client-side tracing](/docs/guides/observability/client-side-tracing) for how to attach trace context from Supabase client SDKs. + ## Query limits [#limit-and-result-row-limitations] Use an explicit `limit` and narrow time range. The logs query surface rejects `select *` and `count(*)`; list columns and use `count()`. A result limit bounds returned rows, not the time range scanned. diff --git a/apps/docs/content/guides/observability/log-field-reference.mdx b/apps/docs/content/guides/observability/log-field-reference.mdx index d3e7ef6db3c..3a71bba7f80 100644 --- a/apps/docs/content/guides/observability/log-field-reference.mdx +++ b/apps/docs/content/guides/observability/log-field-reference.mdx @@ -46,6 +46,7 @@ Request headers: - `x-forwarded-user-agent` - `range` - `prefer` +- `traceparent` Response headers: @@ -64,6 +65,7 @@ Response headers: ## Capture limits +- `log_attributes['request_id']`, `log_attributes['trace_id']`, and `log_attributes['span_id']` are potentially present on any source but are not guaranteed to be populated. The API gateway unpacks the `sb-request-id` request header into `log_attributes['request_id']` — there is no `log_attributes['request.headers.sb-request-id']` key. - Hosted Postgres events longer than 100,000 characters and Edge Function log messages longer than 10,000 characters are truncated. - Internal Supabase service connection events are not recorded in hosted Postgres logs. - An Edge Function invocation uses `function_edge_logs`; its console output uses `function_logs`. diff --git a/packages/shared-data/log-constants.ts b/packages/shared-data/log-constants.ts index a7c214981fb..a43edd16464 100644 --- a/packages/shared-data/log-constants.ts +++ b/packages/shared-data/log-constants.ts @@ -87,8 +87,12 @@ const schemas: LogSchema[] = [ { path: 'metadata.response.headers.sb_gateway_version', type: 'string' }, { path: 'metadata.response.headers.transfer_encoding', type: 'string' }, { path: 'metadata.response.headers.x_kong_proxy_latency', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, { path: 'metadata.response.origin_time', type: 'number' }, { path: 'metadata.response.status_code', type: 'number' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -116,8 +120,12 @@ const schemas: LogSchema[] = [ { path: 'metadata.path', type: 'string' }, { path: 'metadata.referer', type: 'string' }, { path: 'metadata.remote_addr', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, { path: 'metadata.status', type: 'number' }, { path: 'metadata.timestamp', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -141,6 +149,10 @@ const schemas: LogSchema[] = [ { path: 'metadata.host', type: 'string' }, { path: 'metadata.level', type: 'string' }, { path: 'metadata.msg', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -176,6 +188,10 @@ const schemas: LogSchema[] = [ { path: 'metadata.responseTime', type: 'number' }, { path: 'metadata.tenantId', type: 'string' }, { path: 'metadata.rawError', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -203,7 +219,11 @@ const schemas: LogSchema[] = [ { path: 'metadata.response.headers.date', type: 'string' }, { path: 'metadata.response.headers.server', type: 'string' }, { path: 'metadata.response.headers.vary', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, { path: 'metadata.response.status_code', type: 'number' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'metadata.version', type: 'string' }, ], }, @@ -222,6 +242,9 @@ const schemas: LogSchema[] = [ { path: 'metadata.project_ref', type: 'string' }, { path: 'metadata.region', type: 'string' }, { path: 'metadata.timestamp', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'metadata.version', type: 'string' }, ], }, @@ -249,6 +272,9 @@ const schemas: LogSchema[] = [ { path: 'metadata.parsed.transaction_id', type: 'number' }, { path: 'metadata.parsed.user_name', type: 'string' }, { path: 'metadata.parsed.virtual_transaction_id', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -264,6 +290,9 @@ const schemas: LogSchema[] = [ { path: 'metadata.measurements.limit', type: 'number' }, { path: 'metadata.measurements.sum', type: 'number' }, { path: 'metadata.external_id', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -275,6 +304,10 @@ const schemas: LogSchema[] = [ { path: 'identifier', type: 'string' }, { path: 'timestamp', type: 'datetime' }, { path: 'metadata.host', type: 'string' }, + { path: 'metadata.request.headers.traceparent', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, ], }, { @@ -301,6 +334,9 @@ const schemas: LogSchema[] = [ { path: 'metadata.project', type: 'string' }, { path: 'metadata.region', type: 'string' }, { path: 'metadata.type', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'metadata.user', type: 'string' }, ], }, @@ -313,6 +349,9 @@ const schemas: LogSchema[] = [ { path: 'file', type: 'string' }, { path: 'timestamp', type: 'datetime' }, { path: 'metadata.host', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'project', type: 'string' }, ], }, @@ -322,6 +361,9 @@ const schemas: LogSchema[] = [ fields: [ { path: 'event_message', type: 'string' }, { path: 'id', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'timestamp', type: 'datetime' }, ], }, @@ -335,6 +377,9 @@ const schemas: LogSchema[] = [ { path: 'id', type: 'string' }, { path: 'namespace', type: 'string' }, { path: 'node_name', type: 'string' }, + { path: 'metadata.request_id', type: 'string' }, + { path: 'metadata.span_id', type: 'string' }, + { path: 'metadata.trace_id', type: 'string' }, { path: 'pod_name', type: 'string' }, { path: 'project', type: 'string' }, { path: 'region', type: 'string' },