diff --git a/apps/docs/app/guides/monitoring-and-debugging/[[...slug]]/page.tsx b/apps/docs/app/guides/observability/[[...slug]]/page.tsx similarity index 58% rename from apps/docs/app/guides/monitoring-and-debugging/[[...slug]]/page.tsx rename to apps/docs/app/guides/observability/[[...slug]]/page.tsx index 94df4a9b279..d9feda75891 100644 --- a/apps/docs/app/guides/monitoring-and-debugging/[[...slug]]/page.tsx +++ b/apps/docs/app/guides/observability/[[...slug]]/page.tsx @@ -9,20 +9,18 @@ import { IS_DEV } from '~/lib/constants' type Params = { slug?: string[] } -const MonitoringTroubleshootingGuidePage = async (props: { params: Promise }) => { +const ObservabilityGuidePage = async (props: { params: Promise }) => { const params = await props.params - const slug = ['monitoring-and-debugging', ...(params.slug ?? [])] + const slug = ['observability', ...(params.slug ?? [])] const data = await getGuidesMarkdown(slug) return } -const generateStaticParams = !IS_DEV - ? genGuidesStaticParams('monitoring-and-debugging') - : getEmptyArray +const generateStaticParams = !IS_DEV ? genGuidesStaticParams('observability') : getEmptyArray const generateMetadata = genGuideMeta((params: { slug?: string[] }) => - getGuidesMarkdown(['monitoring-and-debugging', ...(params.slug ?? [])]) + getGuidesMarkdown(['observability', ...(params.slug ?? [])]) ) -export default MonitoringTroubleshootingGuidePage +export default ObservabilityGuidePage export { generateStaticParams, generateMetadata } diff --git a/apps/docs/app/guides/monitoring-and-debugging/layout.tsx b/apps/docs/app/guides/observability/layout.tsx similarity index 100% rename from apps/docs/app/guides/monitoring-and-debugging/layout.tsx rename to apps/docs/app/guides/observability/layout.tsx diff --git a/apps/docs/app/guides/troubleshooting/page.tsx b/apps/docs/app/guides/troubleshooting/page.tsx index 66d34249eb9..7d3bdfeb2b7 100644 --- a/apps/docs/app/guides/troubleshooting/page.tsx +++ b/apps/docs/app/guides/troubleshooting/page.tsx @@ -16,6 +16,8 @@ import { PROD_URL } from '~/lib/constants' import { getCustomContent } from '~/lib/custom-content/getCustomContent' import { mdAlternate } from '~/lib/md-alternates' import { type Metadata } from 'next' +import Link from 'next/link' +import { Admonition } from 'ui-patterns/Admonition' const { metadataTitle } = getCustomContent(['metadata:title']) @@ -32,6 +34,76 @@ export default async function GlobalTroubleshootingPage() {

Search or browse our troubleshooting guides for solutions to common Supabase issues.

+

+ Don't have a specific error yet? Start with{' '} + + Detecting + {' '} + to pick up a signal first. If you already have one, confirm one cause before you change + anything: +

+
    +
  1. + Capture the exact HTTP status, error code, and message. A 401 is not a{' '} + 403; PGRST002 is not PGRST106. If you use{' '} + supabase-js, errors are returned in {'{ data, error }'}, not + thrown. Inspect error; ignoring it hides the failure. +
  2. +
  3. + Query the{' '} + + log source + {' '} + for that layer. When two layers could fit, start closer to the database. +
  4. +
  5. + Search below for that error. Each article confirms one cause, applies one fix, and tells + you how to verify it. +
  6. +
  7. + Re-run the failing operation. Keep the change only when the original symptom is gone. If + verification fails, reverse the change and look again. +
  8. +
+

+ For client-side or local debugging, see{' '} + + Auth error codes + + ,{' '} + + Storage logs + + , and{' '} + + Edge Functions debugging tools + + . +

+ + Deleting data, disabling row-level security, weakening a policy, or terminating a database + process can cause data loss or a security incident. Do not let an automated routine + perform these changes. + +

+ Escalate to{' '} + + Support + {' '} + when you cannot access the diagnostic source, the evidence points to a platform failure, + or a safe fix needs a permission you do not have. Include the project reference, timestamp + with time zone, error code, request ID, and sanitized evidence. Do not include passwords, + API keys, or personal data. +


{ return MenuId.LocalDevelopment case pathname.startsWith('ai-tools'): return MenuId.AiTools - case pathname.startsWith('monitoring-and-debugging'): + case pathname.startsWith('observability'): + return MenuId.Telemetry + case pathname.startsWith('troubleshooting'): return MenuId.Telemetry case pathname.startsWith('platform'): return MenuId.Platform diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx index 31192c49a51..3e26b1f62ff 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx @@ -8,6 +8,16 @@ import React, { useEffect, useRef } from 'react' import MenuIconPicker from './MenuIconPicker' +type NavAccordionItem = { + url?: string + items?: NavAccordionItem[] +} + +function hasActiveDescendant(item: NavAccordionItem, pathname: string): boolean { + if (item.url === pathname) return true + return item.items?.some((child) => hasActiveDescendant(child, pathname)) ?? false +} + const HeaderLink = React.memo(function HeaderLink(props: { title: string id: string @@ -35,7 +45,8 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any const activeItemRef = useRef(null) const isChildActive = - props.subItem.items && props.subItem.items.some((child: any) => child.url === pathname) + props.subItem.items && + props.subItem.items.some((child: NavAccordionItem) => hasActiveDescendant(child, pathname)) const LinkContainer = (props) => { const isExternal = props.url.startsWith('https://') @@ -107,6 +118,17 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any {props.subItem.items .filter((subItem) => subItem.enabled !== false) .map((subSubItem) => { + if (subSubItem.items && subSubItem.items.length > 0) { + return ( + + ) + } + return (
  • @@ -66,14 +66,14 @@ The allow-list only states what a browser _may_ send — it doesn't change what The full list, and when each header is sent: -| Header | Sent | -| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| `authorization` | Every request (session token or API key) | -| `apikey` | Every request | -| `x-client-info` | Every request (SDK name and version) | -| `content-type` | Requests with a body | -| `x-retry-count` | Only on automatic retry attempts (`postgrest-js` retries failed idempotent requests by default) | -| `traceparent`, `tracestate`, `baggage` | **Only when [trace propagation](/docs/guides/monitoring-and-debugging/client-side-tracing) is explicitly enabled** — never by default | +| Header | Sent | +| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `authorization` | Every request (session token or API key) | +| `apikey` | Every request | +| `x-client-info` | Every request (SDK name and version) | +| `content-type` | Requests with a body | +| `x-retry-count` | Only on automatic retry attempts (`postgrest-js` retries failed idempotent requests by default) | +| `traceparent`, `tracestate`, `baggage` | **Only when [trace propagation](/docs/guides/observability/client-side-tracing) is explicitly enabled** — never by default | ### For versions before 2.95.0 diff --git a/apps/docs/content/guides/getting-started/features.mdx b/apps/docs/content/guides/getting-started/features.mdx index cb67510d501..98240af9be9 100644 --- a/apps/docs/content/guides/getting-started/features.mdx +++ b/apps/docs/content/guides/getting-started/features.mdx @@ -68,7 +68,7 @@ Deploy read-only databases across multiple regions, for lower latency and better ### Log drains -Export Supabase logs to third-party providers and external tooling. [Docs](/docs/guides/monitoring-and-debugging/log-drains). +Export Supabase logs to third-party providers and external tooling. [Docs](/docs/guides/observability/log-drains). ## Studio diff --git a/apps/docs/content/guides/monitoring-and-debugging.mdx b/apps/docs/content/guides/monitoring-and-debugging.mdx deleted file mode 100644 index 61e018404a2..00000000000 --- a/apps/docs/content/guides/monitoring-and-debugging.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Monitoring and Debugging ---- - -Monitor your project, debug errors, and understand what's happening across the Supabase stack. - -Debugging with an AI agent? See [Debug with AI tools](/docs/guides/monitoring-and-debugging/debugging#debug-with-ai-tools) for the MCP tools and agent skill that let it read your logs and advisors. - - - - diff --git a/apps/docs/content/guides/monitoring-and-debugging/access-data.mdx b/apps/docs/content/guides/monitoring-and-debugging/access-data.mdx deleted file mode 100644 index 60299f687fb..00000000000 --- a/apps/docs/content/guides/monitoring-and-debugging/access-data.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: 'access-data' -title: 'Observe the data' -description: 'Query logs, metrics, and database diagnostics from MCP, the CLI, the API, or Studio.' ---- - -This guide explains how to observe a Supabase project. - -Use this page to: - -- See [what data you can observe](#what-data-you-can-observe) -- Choose [where you can observe it](#access-via) - -## What data you can observe [#what-data-you-can-observe] - -The sources are logs, metrics, live Postgres diagnostics, and advisor findings. Open Logs and Reports in Studio when you want a UI on those sources. See [where you can observe it](#access-via). - -### Logs - -Request, database, Auth, Storage, Realtime, and function events in ClickHouse. - -- [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering) — run ClickHouse SQL from Studio, MCP, the API, or a script. Record extra Postgres, API, and Realtime events. -- [Logs field reference](/docs/guides/monitoring-and-debugging/log-field-reference) — sources and fields - -### Metrics [#metrics-api] - -Prometheus-compatible CPU, IO, WAL, connections, and query stats. Scrape the [Metrics API](/docs/guides/monitoring-and-debugging/metrics) for custom dashboards, alerting, or retention beyond Studio. - -### Database - -Live Postgres statistics such as bloat, cache hit rate, blocking sessions, index usage, and slow queries. See [Inspect the database](/docs/guides/monitoring-and-debugging/inspect) (`supabase inspect db`) for the command and SQL catalog. - -MCP `execute_sql` can run the same read-only queries. - -### Advisors - -Deterministic security and performance findings. Pull them from [Advisors](/docs/guides/monitoring-and-debugging/advisors). - -## Where you can observe it [#access-via] - -Use the interface that matches where you are working. - -### MCP [#mcp] - -Configure the [Supabase MCP server](/docs/guides/ai-tools/mcp) for one project with read-only mode. The debugging tools are: - -- `query_logs` for bounded log queries. Use the same ClickHouse SQL as [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering). -- `execute_sql` for read-only database inspection -- `get_advisors` for security and performance findings - -Ask the agent to inspect a time window, error code, or advisor finding. Keep production connections project-scoped and read-only. - -### API [#api] - -Use the Management API when you want the same data from a script: - -- [Query project logs](/docs/reference/api/v1-get-project-logs). Pass ClickHouse SQL in the `sql` parameter. See [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering). -- [Security advisors](/docs/reference/api/v1-get-security-advisors) and [performance advisors](/docs/reference/api/v1-get-performance-advisors) -- [API usage counts](/docs/reference/api/v1-get-project-usage-api-count) - -Scrape the [Metrics API](/docs/guides/monitoring-and-debugging/metrics) for Prometheus-compatible database series. That endpoint is a project URL, not a Management API route. - -### CLI [#cli] - -Use the [Supabase CLI](/docs/guides/local-development/cli/getting-started) against a linked project: - -- [`supabase inspect db`](/docs/guides/monitoring-and-debugging/inspect) for the database diagnostic catalog -- [`supabase db advisors`](/docs/reference/cli/usage#supabase-db-advisors) for security and performance findings - -Run `supabase inspect db help` on the installed CLI to see the reports available in your version. - -### Studio [#studio] - -Use Studio when you want to inspect the project in the browser: - -- [Logs](/docs/guides/monitoring-and-debugging/logs) for the unified Logs view -- [Reports](/docs/guides/monitoring-and-debugging/reports) for API, Auth, Storage, Realtime, and database dashboards -- [Advisors](/docs/guides/monitoring-and-debugging/advisors) for deterministic security and performance findings - -To send logs or traces to your own stack, see [Log drains](/docs/guides/monitoring-and-debugging/log-drains), [Client-side tracing](/docs/guides/monitoring-and-debugging/client-side-tracing), and [Sentry integration](/docs/guides/monitoring-and-debugging/sentry-monitoring). diff --git a/apps/docs/content/guides/monitoring-and-debugging/debugging.mdx b/apps/docs/content/guides/monitoring-and-debugging/debugging.mdx deleted file mode 100644 index 59c9d40ffb2..00000000000 --- a/apps/docs/content/guides/monitoring-and-debugging/debugging.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: 'debugging' -title: 'Debugging guide' -description: 'Isolate and fix Supabase issues by reading the error, isolating the failing layer, and gathering evidence from logs.' ---- - -Debug by evidence, not by guessing. A Supabase error almost always surfaces at one layer but originates at another, so the fastest path to a fix is finding _where_ the problem is, not pattern-matching the symptom. Retrying a failed request rarely helps; isolating the layer does. - -## Debug with AI tools - -An AI agent can work through this loop for you, but only if it can read your project's evidence instead of guessing from the error message. - -Debugging with an agent needs two things: - -- The [Supabase MCP server](/docs/guides/ai-tools/mcp) provides the tools this guide relies on: `get_logs` for a per-service log dump, `query_logs` to run read-only SQL against your logs for filtering and aggregation (see [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering) for the ClickHouse SQL syntax it accepts), `get_advisors` for security and performance findings, and `execute_sql` to inspect your schema and policies. -- The [Supabase agent skill](/docs/guides/ai-tools/ai-skills) teaches the agent this workflow: locate the failing layer, gather evidence from the matching log source, and verify the fix by re-running the operation that failed. - -Install both in one step with the [Supabase plugin for AI coding agents](/docs/guides/ai-tools/plugins). Connecting an agent to your project carries security risks, so read the [MCP security best practices](/docs/guides/ai-tools/mcp#security-risks) first. - -## Follow these debugging steps - -Work through these steps in order, skipping straight to a fix before you have evidence for the cause is the most common way to waste time on a bug. - -1. **Reproduce the issue and read the error precisely.** Capture the exact status code, the error code, and the full message, not a paraphrase. A `401` is not a `403`; `PGRST002` is not `PGRST106`; a Postgres `SQLSTATE` such as `42501`, `42P01`, or `23505` points at the exact failure. The precise error is your strongest clue. If you're using `supabase-js`, remember that errors are **returned, not thrown**, check the `error` field in the `{ data, error }` response object. Make sure your code inspects `error` — a swallowed error is why many bugs look like "nothing happened". -2. **Locate the failing layer.** Use the request stack below. The status code and error code usually name the layer for you. -3. **Gather evidence for that layer.** Query its logs, run the security and performance advisors, and inspect the schema. Logs are the primary tool, and the layer you identified in the previous step tells you which log source to query. See [Read the logs](#read-the-logs) below. -4. **Isolate the cause** using the troubleshooting guide for that layer (see [Find the guide for your symptom](#find-the-guide-for-your-symptom) below). Confirm your hypothesis against the evidence before you act. Most Supabase issues trace back to a small, known set of causes, and the guide explains how to tell them apart. -5. **Apply the fix, then verify.** Re-run the exact operation that failed and confirm it now succeeds, and that the corresponding log line is clean. A fix you haven't re-run is still a guess. If a couple of attempts don't resolve it, stop and gather more evidence rather than repeating the same change. - -## Check the request stack - -A request from a client passes through several layers before it reaches your data. Errors propagate upward, so the layer that _reports_ an error is often not the layer that _caused_ it. - -Knowing the shape of the stack is what makes isolating the layer possible. - -``` -Client (supabase-js / SSR) - → Edge / API gateway → edge_logs (HTTP status, routing, rate limits) - The gateway routes each request to ONE of these services. They run in parallel, - not as a chain: - ├→ PostgREST (Data API) → postgrest_logs (low-signal; PGRST* evidence lives in edge_logs and postgres_logs) - ├→ GoTrue (Auth) → auth_logs (login, JWT, OAuth, email) - ├→ Storage API → storage_logs (uploads, object access) - └→ Realtime → realtime_logs (channels, presence, broadcast) - PostgREST, GoTrue, and Storage each reach the database independently: - → Supavisor (connection pooler) → supavisor_logs (pooling, timeouts) - → Postgres (SQL, RLS, triggers) → postgres_logs (SQLSTATE, RLS, functions) -``` - -Edge Functions sit outside this stack and log separately: `function_edge_logs` for the HTTP request to the function, and `function_logs` for `console` output from inside it. - - - -A permission error or an unexpectedly empty result at the API layer is often a Postgres row-level security or privilege problem one layer down, though filters, authentication, query shape, or a stale schema cache can produce the same symptom. When in doubt, trace toward the database. - - - -## Read the logs - -Once you know the layer, query that layer's log source directly rather than scanning everything. Pick one `source`, bound the time window, and select only the fields you need. - -When a query comes up empty, widen along an anchor, such as a timestamp, request ID, or error code, to follow the same request into the adjacent source (for example from `edge_logs` into `postgres_logs`) instead of broadening into an unfiltered scan. - -A wide, unfiltered query across every source buries the one line you need and, on paid projects, costs more in scanned data. - -The [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering) guide covers the Logs Explorer, the available log sources, and how to write queries against them. - -## Find the guide for your symptom - -Match your symptom to a layer, confirm it against that layer's logs, then open the troubleshooting guide for the specific cause and fix. If a symptom could fit two layers (for example, an auth call failing with what looks like an RLS error), start with the layer closest to the database. - -Supabase updates these troubleshooting guides continuously, so treat this table as a starting point rather than the final word: if your exact symptom isn't listed, search the [troubleshooting index](/docs/guides/troubleshooting) for the error string. - -| Symptom / error | Layer → log source | Troubleshooting guides | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Empty `data` array with rows present; wrong rows returned; UPDATE/DELETE affects 0 rows; `42501` permission denied; `service_role` still blocked; policy not matching | RLS & access → `postgres_logs` | [Empty select array](/docs/guides/troubleshooting/why-is-my-select-returning-an-empty-data-array-and-i-have-data-in-the-table-xvOPgx) · [service_role hits RLS](/docs/guides/troubleshooting/why-is-my-service-role-key-client-getting-rls-errors-or-not-returning-data-7_1K9z) · [Database API 42501](/docs/guides/troubleshooting/database-api-42501-errors) · [RLS Simplified](/docs/guides/troubleshooting/rls-simplified-BJTcS8) · [Deprecated RLS features](/docs/guides/troubleshooting/deprecated-rls-features-Pm77Zs) | -| `PGRST002`/`PGRST106`; "schema cache"; "could not find table/relationship"; new column or table not recognized; `42P01`; `520`; API returns nothing | Data API (PostgREST) → `edge_logs`, `postgres_logs` | [Refresh schema cache](/docs/guides/troubleshooting/refresh-postgrest-schema) · [PGRST002](/docs/guides/troubleshooting/postgrest-error-pgrst002-could-not-query-the-database-for-the-schema-cache-c396e9) · [New objects not recognized](/docs/guides/troubleshooting/postgrest-not-recognizing-new-columns-or-functions-bd75f5) · [42P01](/docs/guides/troubleshooting/resolving-42p01-relation-does-not-exist-error-W4_9-V) · [520 errors](/docs/guides/troubleshooting/fixing-520-errors-in-the-database-rest-api-Ur5-B2) · [API not returning](/docs/guides/troubleshooting/why-is-my-supabase-api-call-not-returning-PGzXw0) | -| Sign-in/sign-out/session broken; JWT "invalid claim"/"missing sub"; cookies not sent; OAuth redirect wrong; OTP/magic-link expired; MFA/TOTP fails; auth `500`/`503`; emails not arriving | Auth → `auth_logs`, `postgres_logs` | [401 missing sub](/docs/guides/troubleshooting/auth-error-401-invalid-claim-missing-sub--AFwMR) · [500 auth errors](/docs/guides/troubleshooting/resolving-500-status-authentication-errors-7bU5U8) · [503 AuthRetryableFetchError](/docs/guides/troubleshooting/auth-error-503-authretryablefetcherror-51b88c) · [OTP expired](/docs/guides/troubleshooting/otp-verification-failures-token-has-expired-or-otp_expired-errors-5ee4d0) · [OAuth not redirecting](/docs/guides/troubleshooting/oauth-sign-in-isnt-redirecting-on-the-server-side-ShGMtr) · [No auth emails](/docs/guides/troubleshooting/not-receiving-auth-emails-from-the-supabase-project-OFSNzw) · [Next.js auth](/docs/guides/troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV) | -| `statement timeout`; duplicate key or sequence error; trigger errors; slow `ALTER`; blocked queries; disk/memory/swap pressure; index size | Database (Postgres) → `postgres_logs` | [Statement timeout](/docs/guides/troubleshooting/canceling-statement-due-to-statement-timeout-581wFv) · [Duplicate key / sequence](/docs/guides/troubleshooting/inserting-into-sequenceserial-table-causes-duplicate-key-violates-unique-constraint-error-pi6DnC) · [Blocked queries](/docs/guides/troubleshooting/how-to-check-if-my-queries-are-being-blocked-by-other-queries-NSKtR1) · [Disk not shrinking](/docs/guides/troubleshooting/disk-size-not-shrinking-after-deleting-data-135390) · [Autovacuum stalled](/docs/guides/troubleshooting/autovacuum-stalled-due-to-inactive-replication-slot-d55aa2) · [High CPU](/docs/guides/troubleshooting/high-cpu-usage) | -| "too many connections"; "remaining connection slots"; `CONNECT_TIMEOUT`; pooler vs. direct connection; read-only transaction; `prepared statement already exists`; `no pg_hba.conf entry`; IPv4/IPv6; SASL/SCRAM | Connections & pooler → `supavisor_logs`, `postgres_logs` | [Too many connections](/docs/guides/troubleshooting/too-many-connections-for-database-postgres) · [Remaining slots](/docs/guides/troubleshooting/database-error-remaining-connection-slots-are-reserved-for-non-replication-superuser-connections-3V3nIb) · [Prepared statement exists](/docs/guides/troubleshooting/error-prepared-statement-xxx-already-exists-3laqeM) · [Read-only transaction](/docs/guides/troubleshooting/resolving-cannot-execute-update-in-a-read-only-transaction-on-transaction-pooler-connections-ef582c) · [CONNECT_TIMEOUT](/docs/guides/troubleshooting/troubleshooting-connect_timeout-or-hanging-queries-in-vercel-serverless-functions-775f92) · [Supavisor terminology](/docs/guides/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO) | -| Edge Function `401`/`404`/`500`/`503`/`504`/`546`; CPU/memory/wall-clock limit hit; won't deploy; boot error; WebSocket drop; `esm.sh` import fails | Edge Functions → `function_edge_logs`, `function_logs` | [401](/docs/guides/troubleshooting/edge-function-401-error-response) · [500](/docs/guides/troubleshooting/edge-function-500-error-response) · [503 boot](/docs/guides/troubleshooting/edge-function-503-response) · [504](/docs/guides/troubleshooting/edge-function-504-error-response) · [546 resource limit](/docs/guides/troubleshooting/edge-function-546-error-response) · [Shutdown reasons](/docs/guides/troubleshooting/edge-function-shutdown-reasons-explained) · [Deploy fails](/docs/guides/troubleshooting/edge-function-fails-deploy) · [esm.sh import](/docs/guides/troubleshooting/importing-stripe-or-other-modules-from-esmsh-on-deno-edge-functions-throws-an-error-TmbB5p) | -| Realtime `TIMED_OUT`; `TooManyChannels`; silent disconnect; missed database changes; broadcast-from-DB warning; heartbeats | Realtime → `realtime_logs` | [TIMED_OUT](/docs/guides/troubleshooting/realtime-connections-timed_out-status) · [TooManyChannels](/docs/guides/troubleshooting/realtime-too-many-channels-error) · [Silent disconnects](/docs/guides/troubleshooting/realtime-handling-silent-disconnections-in-backgrounded-applications-592794) · [Broadcast warning](/docs/guides/troubleshooting/realtime-warn-sending-broadcast-message) · [Heartbeats](/docs/guides/troubleshooting/realtime-heartbeat-messages) · [Logger](/docs/guides/troubleshooting/realtime-debugging-with-logger) | -| Upload or list fails; public bucket inaccessible; `relation "objects" does not exist`; file size limit; folder or RLS issue | Storage → `storage_logs`, `postgres_logs` | [Public bucket upload/list](/docs/guides/troubleshooting/why-cant-i-uploadlistetc-my-public-bucket-Z6CmGt) · [403 RLS on upload](/docs/guides/troubleshooting/storage-error-403-forbidden-new-row-violates-row-level-security-policy-on-upload-a94384) · [relation objects does not exist](/docs/guides/troubleshooting/relation-objects-does-not-exist-error-during-storage-uploads-8f21f0) · [File size limits](/docs/guides/troubleshooting/upload-file-size-restrictions-Y4wQLT) · [Folder ops / hierarchical RLS](/docs/guides/troubleshooting/supabase-storage-inefficient-folder-operations-and-hierarchical-rls-challenges-b05a4d) | -| Webhook not firing; `pg_cron` job not running; `pg_net` queue stuck; `42501 ... http_request_queue` | Database jobs → `postgres_logs` | [Webhook debugging](/docs/guides/troubleshooting/webhook-debugging-guide-M8sk47) · [pg_cron debugging](/docs/guides/troubleshooting/pgcron-debugging-guide-n1KTaz) · [42501 http_request_queue](/docs/guides/troubleshooting/42501--permission-denied-for-table-httprequestqueue-KnozmQ) | -| Reading or querying logs; interpreting Postgres logs; finding API errors in logs; reading metrics | Diagnostics → any log source | [Logging guide](/docs/guides/monitoring-and-debugging/logs) · [Interpret Postgres logs](/docs/guides/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj) · [API errors in logs](/docs/guides/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9) · [Logging levels](/docs/guides/troubleshooting/understanding-postgresql-logging-levels-and-how-they-impact-your-project-KXiJRm) · [View database metrics](/docs/guides/troubleshooting/how-to-view-database-metrics-uqf2z_) | - -For query performance and schema-design questions such as indexing, `EXPLAIN`, N+1 queries, or partitioning, see the [Postgres guides](/docs/guides/database/overview). - -Debugging is complete only once you've re-run the failing operation, confirmed it succeeds, and checked that the layer's logs show a clean result. - -## Per-product debugging - -Each Supabase product has its own debugging resources. Use these as a starting point when the error originates in a specific service. - -- [Database — Inspect the database](/docs/guides/monitoring-and-debugging/inspect) -- [Auth — Error codes](/docs/guides/auth/debugging/error-codes) -- [Storage — Debugging](/docs/guides/storage/debugging/logs) -- [Edge Functions — Local debugging](/docs/guides/functions/debugging-tools) diff --git a/apps/docs/content/guides/observability.mdx b/apps/docs/content/guides/observability.mdx new file mode 100644 index 00000000000..7b3f6b054a9 --- /dev/null +++ b/apps/docs/content/guides/observability.mdx @@ -0,0 +1,38 @@ +--- +title: Observability +description: 'Access project data, detect issues, diagnose findings, and automate repeatable checks with an agent.' +--- + + + +Monitor your Supabase project with the tools you already use, as a person or an agent. + +## 1. Observe the data + +The sources you can query, and where to read them. + + + +## 2. Detect issues + +Use queries and checks against those sources to pick up health, security, performance, and usage signals. + + + +## 3. Diagnose and resolve + +Use a concrete finding, symptom, or error code to identify the cause and apply a known solution. + + + +## 4. Hire an agent + +Turn the checks you trust into a read-only routine in your agent harness and run it on a schedule. + + + +## Export your data + +Send logs and traces to the tools you already run. + + diff --git a/apps/docs/content/guides/observability/access-data.mdx b/apps/docs/content/guides/observability/access-data.mdx new file mode 100644 index 00000000000..4e5cdbe7ab8 --- /dev/null +++ b/apps/docs/content/guides/observability/access-data.mdx @@ -0,0 +1,31 @@ +--- +id: 'access-data' +title: 'Observe the data' +description: 'Query logs, metrics, database diagnostics, and advisors. Each source page lists Studio, MCP, the API, and the CLI.' +--- + +This guide lists the project data you can query. Each source page lists where to read that source. To pick up a signal from this data, see [Detecting](/docs/guides/observability/detecting). + +## Logs + +Request, database, Auth, Storage, Realtime, and function events in ClickHouse. + +Query them with SQL in [Query and filter logs](/docs/guides/observability/advanced-log-filtering) from the [Logs Explorer](/dashboard/project/_/logs/explorer), MCP `query_logs`, or the [Management API](/docs/reference/api/v1-get-project-logs). Filter events without SQL in [Logs](/docs/guides/observability/logs). See the [Logs field reference](/docs/guides/observability/log-field-reference) for sources and fields. + +The CLI does not query ClickHouse logs. Call the Management API from a script, or [inspect the database](/docs/guides/observability/inspect) for Postgres diagnostics. + +## Metrics [#metrics-api] + +Prometheus-compatible CPU, IO, WAL, connections, and query stats. Scrape the [Metrics API](/docs/guides/observability/metrics) for custom dashboards, alerting, or retention beyond Studio. Chart a subset of the same window in [Reports](/docs/guides/observability/reports). + +## Database + +Live Postgres statistics such as bloat, cache hit rate, blocking sessions, index usage, and slow queries. Run the same checks from the [SQL Editor](/dashboard/project/_/sql), MCP `execute_sql`, or `supabase inspect db`. See [Inspect the database](/docs/guides/observability/inspect). + +## Advisors + +Deterministic security and performance findings. Pull them from Studio, MCP `get_advisors`, [`supabase db advisors`](/docs/reference/cli/usage#supabase-db-advisors), or the Management API. See [Advisors](/docs/guides/observability/advisors). + +## Reports + +Studio dashboards for API, Auth, Storage, Realtime, and database signals. Use them to pick a time window or resource, then follow [Detecting](/docs/guides/observability/detecting). See [Reports](/docs/guides/observability/reports). diff --git a/apps/docs/content/guides/monitoring-and-debugging/advanced-log-filtering.mdx b/apps/docs/content/guides/observability/advanced-log-filtering.mdx similarity index 96% rename from apps/docs/content/guides/monitoring-and-debugging/advanced-log-filtering.mdx rename to apps/docs/content/guides/observability/advanced-log-filtering.mdx index 642c363f96a..dc4e02d7f75 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/advanced-log-filtering.mdx +++ b/apps/docs/content/guides/observability/advanced-log-filtering.mdx @@ -3,7 +3,7 @@ title: 'Query and filter logs' description: 'Query project logs from Studio, MCP, the API, or a script. Record extra Postgres, API, and Realtime events.' --- -This guide explains how to query project logs and how to record extra events. The same ClickHouse SQL runs in the [Logs Explorer](/dashboard/project/_/logs/explorer), the MCP [`query_logs`](/docs/guides/ai-tools/mcp) tool, and the [Management API](/docs/reference/api/v1-get-project-logs). Filter events without SQL in [Logs](/docs/guides/monitoring-and-debugging/logs) in Studio. From a terminal, call the Management API; the CLI inspects the database rather than ClickHouse logs. +This guide explains how to query project logs and how to record extra events. The same ClickHouse SQL runs in the [Logs Explorer](/dashboard/project/_/logs/explorer), the MCP [`query_logs`](/docs/guides/ai-tools/mcp) tool, and the [Management API](/docs/reference/api/v1-get-project-logs). Filter events without SQL in [Logs](/docs/guides/observability/logs) in Studio. From a terminal, call the Management API; the CLI inspects the database rather than ClickHouse logs. Use this page to: @@ -26,11 +26,11 @@ On hosted projects, prefer `query_logs` over `get_logs`. `get_logs` returns a se ### Studio [#studio] -Open [Logs](/dashboard/project/_/logs) to filter and inspect events. Open the [Logs Explorer](/dashboard/project/_/logs/explorer) to run ClickHouse SQL. See [Logs](/docs/guides/monitoring-and-debugging/logs) for the unified Logs interface. +Open [Logs](/dashboard/project/_/logs) to filter and inspect events. Open the [Logs Explorer](/dashboard/project/_/logs/explorer) to run ClickHouse SQL. See [Logs](/docs/guides/observability/logs) for the unified Logs interface. ### MCP [#mcp] -On hosted projects, call [`query_logs`](/docs/guides/ai-tools/mcp) with the same SQL as this guide. Keep the connection project-scoped and read-only. See [Observe the data](/docs/guides/monitoring-and-debugging/access-data#mcp). +On hosted projects, call [`query_logs`](/docs/guides/ai-tools/mcp) with the same SQL as this guide. Keep the connection project-scoped and read-only. ### API [#api] @@ -38,7 +38,7 @@ Pass ClickHouse SQL in the `sql` parameter of the [Management API logs endpoint] ### CLI [#cli] -The Supabase CLI does not query ClickHouse logs. Call the [Management API](/docs/reference/api/v1-get-project-logs) from a script, or use [`supabase inspect db`](/docs/guides/monitoring-and-debugging/inspect) for database diagnostics. See [Observe the data](/docs/guides/monitoring-and-debugging/access-data#cli). +The Supabase CLI does not query ClickHouse logs. Call the [Management API](/docs/reference/api/v1-get-project-logs) from a script, or use [`supabase inspect db`](/docs/guides/observability/inspect) for database diagnostics. ## Sources [#logs-explorer] @@ -82,7 +82,7 @@ For `postgres_logs`, statement text and error detail live in `event_message`. `p For API Load Balancer traffic, the upstream database is `log_attributes['load_balancer_redirect_identifier']`. -See the [Logs field reference](/docs/guides/monitoring-and-debugging/log-field-reference) for the ClickHouse field names on each source. +See the [Logs field reference](/docs/guides/observability/log-field-reference) for the ClickHouse field names on each source. ## Working with API logs [#working-with-api-logs] @@ -352,7 +352,7 @@ Identify which service owns the problem from the error or status code first, the 5. **Reference only fields you have confirmed.** -A misspelled or non-existent field name either errors or silently returns nothing, which leaves a working query look empty. Confirm field names in the [Logs field reference](/docs/guides/monitoring-and-debugging/log-field-reference), or select `event_message` and inspect a sample row first. +A misspelled or non-existent field name either errors or silently returns nothing, which leaves a working query look empty. Confirm field names in the [Logs field reference](/docs/guides/observability/log-field-reference), or select `event_message` and inspect a sample row first. ## Examples and templates diff --git a/apps/docs/content/guides/monitoring-and-debugging/advisors.mdx b/apps/docs/content/guides/observability/advisors.mdx similarity index 81% rename from apps/docs/content/guides/monitoring-and-debugging/advisors.mdx rename to apps/docs/content/guides/observability/advisors.mdx index 8f3e1aa818c..7f64deff229 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/advisors.mdx +++ b/apps/docs/content/guides/observability/advisors.mdx @@ -6,7 +6,7 @@ description: 'Deterministic security and performance findings you or an agent ca Advisors are programmatic checks that ship with the platform. They inspect the live schema and return deterministic findings, such as missing indexes or incorrectly configured RLS policies. -Use them as part of ongoing observability, together with [logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering). A finding is not a fix. Confirm it against recent log evidence, then search [troubleshooting](/docs/guides/troubleshooting) for the check name or the object it names. +Use them as part of ongoing observability, together with [logs](/docs/guides/observability/advanced-log-filtering). A finding is not a fix. Confirm it against recent log evidence, then search [Diagnosing](/docs/guides/troubleshooting) for the check name or the object it names. You or an agent can pull the same checks from: diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents.mdx b/apps/docs/content/guides/observability/automate-with-agents.mdx similarity index 54% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents.mdx rename to apps/docs/content/guides/observability/automate-with-agents.mdx index b12b1941afd..f36a0a83a9e 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents.mdx +++ b/apps/docs/content/guides/observability/automate-with-agents.mdx @@ -11,12 +11,12 @@ This guide explains how to run a Supabase monitoring agent in your own harness. Start with one monitor. Add another only when the project needs a different source or cadence. -| Monitor | What it watches | Default cadence | Use it when | -| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------- | -| [Health monitor](/docs/guides/monitoring-and-debugging/automate-with-agents/health) | API and Auth server errors, error-rate spikes, connection pressure | Hourly | You need incident detection and regular feedback loops | -| [Security monitor](/docs/guides/monitoring-and-debugging/automate-with-agents/security) | Security Advisor findings, authentication and authorization failures | Daily | You need a regular access-control and configuration review | -| [Performance monitor](/docs/guides/monitoring-and-debugging/automate-with-agents/performance) | Slow queries, lock waits, long-running sessions, Performance Advisor findings | Hourly | You need query and database performance checks | -| [Capacity monitor](/docs/guides/monitoring-and-debugging/automate-with-agents/usage) | Request, error, storage, table, and connection growth | Daily | You need to identify growth before it reaches a resource limit | +| Monitor | What it watches | Default cadence | Use it when | +| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------- | +| [Health monitor](/docs/guides/observability/automate-with-agents/health) | API and Auth server errors, error-rate spikes, connection pressure | Hourly | You need incident detection and regular feedback loops | +| [Security monitor](/docs/guides/observability/automate-with-agents/security) | Security Advisor findings, authentication and authorization failures | Daily | You need a regular access-control and configuration review | +| [Performance monitor](/docs/guides/observability/automate-with-agents/performance) | Slow queries, lock waits, long-running sessions, Performance Advisor findings | Hourly | You need query and database performance checks | +| [Capacity monitor](/docs/guides/observability/automate-with-agents/usage) | Request, error, storage, table, and connection growth | Daily | You need to identify growth before it reaches a resource limit | For a small project, run the most relevant routine daily or weekly and include the other categories in its prompt. Split it into specialized monitors only when you need different owners, schedules, or alert thresholds. diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/all.mdx b/apps/docs/content/guides/observability/automate-with-agents/all.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/all.mdx rename to apps/docs/content/guides/observability/automate-with-agents/all.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/health.mdx b/apps/docs/content/guides/observability/automate-with-agents/health.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/health.mdx rename to apps/docs/content/guides/observability/automate-with-agents/health.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/performance.mdx b/apps/docs/content/guides/observability/automate-with-agents/performance.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/performance.mdx rename to apps/docs/content/guides/observability/automate-with-agents/performance.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/security.mdx b/apps/docs/content/guides/observability/automate-with-agents/security.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/security.mdx rename to apps/docs/content/guides/observability/automate-with-agents/security.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/usage.mdx b/apps/docs/content/guides/observability/automate-with-agents/usage.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/automate-with-agents/usage.mdx rename to apps/docs/content/guides/observability/automate-with-agents/usage.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/client-side-tracing.mdx b/apps/docs/content/guides/observability/client-side-tracing.mdx similarity index 98% rename from apps/docs/content/guides/monitoring-and-debugging/client-side-tracing.mdx rename to apps/docs/content/guides/observability/client-side-tracing.mdx index 790e92d11de..003a67dded1 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/client-side-tracing.mdx +++ b/apps/docs/content/guides/observability/client-side-tracing.mdx @@ -279,4 +279,4 @@ After trace context is flowing through, the `trace_id` appears in: - **API Gateway logs** — every request to PostgREST, Auth, Storage, and Realtime - **Edge Function logs** — invocations and any structured logs emitted from within the function -If you forward Supabase logs to a third-party backend via [Log Drains](/docs/guides/monitoring-and-debugging/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. +If you forward Supabase logs to a third-party backend via [Log Drains](/docs/guides/observability/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. diff --git a/apps/docs/content/guides/observability/detecting.mdx b/apps/docs/content/guides/observability/detecting.mdx new file mode 100644 index 00000000000..7196a9779cd --- /dev/null +++ b/apps/docs/content/guides/observability/detecting.mdx @@ -0,0 +1,283 @@ +--- +id: 'detecting' +title: 'Detecting issues' +description: 'Run Health, Security, Performance, and Usage checks against logs and database statistics to pick up actionable signals.' +--- + +Detection is the step between accessing project data and troubleshooting a specific problem. Use the sources in [Observe the data](/docs/guides/observability/access-data) to produce a count, rate, trend, or named finding. Do not try to prove the root cause yet. + +This guide provides starting checks for [Health](#health), [Security](#security), [Performance](#performance), and [Usage](#usage). The log examples use ClickHouse SQL in the [Logs Explorer](/dashboard/project/_/logs/explorer) or MCP `query_logs`. The database examples use Postgres SQL in the [SQL Editor](/dashboard/project/_/sql) or MCP `execute_sql`. + +Use a time range that represents normal traffic, then compare it with the same period after a deployment or configuration change. When a check returns a spike, error code, SQLSTATE, object name, or advisor finding, take that evidence to [Diagnosing](/docs/guides/troubleshooting). + +## Health + +Health checks answer whether a service is available and behaving within its normal error and resource envelope. + +### Measure API server-error rate + +Count requests and 5xx responses by hour. A rate is more useful than a raw error count when traffic changes. + +```sql +select + toStartOfHour(timestamp) as hour, + count() as requests, + countIf(toInt32OrZero(log_attributes['response.status_code']) >= 500) as server_errors, + round( + 100.0 * countIf(toInt32OrZero(log_attributes['response.status_code']) >= 500) / + nullIf(count(), 0), + 2 + ) as server_error_percent +from logs +where source = 'edge_logs' +group by hour +order by hour desc +limit 24; +``` + +### Find failing API paths + +Use the rate check to find an affected window, then identify the paths and status codes producing the errors. + +```sql +select + log_attributes['request.path'] as path, + toInt32OrZero(log_attributes['response.status_code']) as status, + count() as errors +from logs +where source = 'edge_logs' + and toInt32OrZero(log_attributes['response.status_code']) >= 500 +group by path, status +order by errors desc +limit 20; +``` + +### Check Postgres connection pressure + +Compare active and waiting connections with the configured limit. A high percentage is a signal to inspect pooler settings, long-running transactions, and traffic before changing the limit. + +```sql +select + count(*) as current_connections, + count(*) filter (where state = 'active') as active_connections, + count(*) filter (where wait_event_type is not null) as waiting_connections, + current_setting('max_connections')::int as max_connections, + round( + 100.0 * count(*) / nullif(current_setting('max_connections')::int, 0), + 2 + ) as connection_percent +from pg_stat_activity; +``` + +You can read API response errors and service availability in [Reports](/docs/guides/observability/reports), or use the [Metrics API](/docs/guides/observability/metrics) for CPU and connection series. Once you have a failing path, status, or saturated resource, continue in [Diagnosing](/docs/guides/troubleshooting). + +## Security + +Security checks look for access-control findings and changes in authentication or authorization failures. Treat them as review signals, not proof of an attack. + +### Measure authorization failures + +Count 401 and 403 responses by hour and status. Compare the rate with a known-good window so normal unauthenticated traffic does not become an alert by itself. + +```sql +select + toStartOfHour(timestamp) as hour, + toInt32OrZero(log_attributes['response.status_code']) as status, + count() as failures +from logs +where source = 'edge_logs' + and toInt32OrZero(log_attributes['response.status_code']) in (401, 403) +group by hour, status +order by hour desc, status +limit 48; +``` + +### Find affected paths and methods + +After detecting a spike, group failures by route and method. This separates a broken client flow from failures spread across the API. + +```sql +select + log_attributes['request.method'] as method, + log_attributes['request.path'] as path, + toInt32OrZero(log_attributes['response.status_code']) as status, + count() as failures +from logs +where source = 'edge_logs' + and toInt32OrZero(log_attributes['response.status_code']) in (401, 403) +group by method, path, status +order by failures desc +limit 20; +``` + +### Find public-schema tables without RLS + +This database query is a focused inventory check. Confirm each result against the project's intended access model; a result is not evidence that data was exposed. + +```sql +select + n.nspname as schema_name, + c.relname as table_name +from + pg_class as c + join pg_namespace as n on n.oid = c.relnamespace +where n.nspname = 'public' and c.relkind in ('r', 'p') and not c.relrowsecurity +order by table_name; +``` + +Run [Security Advisor](/docs/guides/observability/advisors) from Studio, MCP `get_advisors`, the CLI, or the Management API for the full catalog of deterministic checks. Take a lint name, table, policy, path, or status pattern to [Diagnosing](/docs/guides/troubleshooting) before changing policies, grants, or keys. + +## Performance + +Performance checks identify expensive work, contention, and cache misses. They narrow the investigation to a query, relation, session, or resource. + +### Find long-running sessions + +Look for sessions that have been active or idle in a transaction for more than 30 seconds. + +```sql +select + pid, + usename as role, + state, + now() - query_start as duration, + wait_event_type, + wait_event, + left(query, 120) as query +from pg_stat_activity +where datname = current_database() + and pid != pg_backend_pid() + and state in ('active', 'idle in transaction') + and now() - query_start > interval '30 seconds' +order by duration desc +limit 20; +``` + +### Find blocked sessions + +Use `pg_blocking_pids` to name the blocked and blocking processes. Do not cancel either process until you understand the transaction and its impact. + +```sql +select + blocked.pid as blocked_pid, + blocked.usename as blocked_role, + blocker.pid as blocking_pid, + blocker.usename as blocking_role, + now() - blocked.query_start as blocked_for, + left(blocked.query, 120) as blocked_query, + left(blocker.query, 120) as blocking_query +from pg_stat_activity as blocked +cross join lateral unnest(pg_blocking_pids(blocked.pid)) as blocking_pid +join pg_stat_activity as blocker on blocker.pid = blocking_pid +order by blocked_for desc; +``` + +### Find expensive query patterns + +`pg_stat_statements` aggregates normalized queries over time. Rank by total execution time, then inspect mean time and calls before deciding whether a frequent query is inefficient. + +```sql +select + calls, + round(total_exec_time::numeric, 2) as total_time_ms, + round(mean_exec_time::numeric, 2) as mean_time_ms, + rows, + left(query, 160) as query +from pg_stat_statements +order by total_exec_time desc +limit 20; +``` + +### Measure shared-buffer hit rate + +A ratio below 99% means more than 1% of observed block accesses missed `shared_buffers`. Postgres cannot tell whether a miss was served by the operating system cache or physical disk. + +```sql +select + 'index hit rate' as name, + round(100.0 * sum(idx_blks_hit) / nullif(sum(idx_blks_hit) + sum(idx_blks_read), 0), 2) as ratio +from pg_statio_user_indexes +union all +select + 'table hit rate' as name, + round( + 100.0 * sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0), + 2 + ) as ratio +from pg_statio_user_tables; +``` + +Pull [Performance Advisor](/docs/guides/observability/advisors) findings and compare the same window with [Reports](/docs/guides/observability/reports) or the [Metrics API](/docs/guides/observability/metrics). The full command and SQL catalog is in [Inspect the database](/docs/guides/observability/inspect). + +## Usage + +Usage checks identify growth in traffic, data, and connections before it becomes a capacity problem. They do not calculate billing totals. + +### Trend API requests + +Count requests by hour to establish a baseline and spot step changes. + +```sql +select + toStartOfHour(timestamp) as hour, + count() as requests +from logs +where source = 'edge_logs' +group by hour +order by hour desc +limit 168; +``` + +### Find high-volume API paths + +Group by method and path to identify which workload accounts for the growth. + +```sql +select + log_attributes['request.method'] as method, + log_attributes['request.path'] as path, + count() as requests +from logs +where source = 'edge_logs' +group by method, path +order by requests desc +limit 20; +``` + +### Find the largest relations + +Measure tables and their indexes together. Save the result on a regular cadence to establish a growth trend. + +```sql +select + schemaname, + relname as table_name, + pg_total_relation_size(relid) as total_bytes, + pg_size_pretty(pg_total_relation_size(relid)) as total_size +from pg_catalog.pg_statio_user_tables +order by total_bytes desc +limit 20; +``` + +### Count connections by role and state + +Connection growth can reveal a new workload or a client that is not pooling correctly. + +```sql +select + usename as role, + state, + count(*) as connections +from pg_stat_activity +where datname = current_database() +group by role, state +order by connections desc; +``` + +[Reports](/docs/guides/observability/reports) show request, disk, and database-size trends without SQL. The [Management API usage endpoint](/docs/reference/api/v1-get-project-usage-api-count) returns request counts for authorized scripts. Use [`supabase inspect db table-sizes`](/docs/reference/cli/supabase-inspect-db-table-sizes) and [`bloat`](/docs/reference/cli/supabase-inspect-db-bloat) to run related database checks from the CLI. + +## Turn a detection into a diagnosis + +A detection result should name an affected time window and at least one concrete anchor: a path, status, SQLSTATE, request ID, query, relation, PID, policy, or advisor lint. Take that evidence to [Diagnosing](/docs/guides/troubleshooting), identify the cause, apply the smallest relevant solution, and rerun the same detection check to verify the result. + +After a check is useful and repeatable, [hire an agent](/docs/guides/observability/automate-with-agents) to run it on a schedule. diff --git a/apps/docs/content/guides/monitoring-and-debugging/inspect.mdx b/apps/docs/content/guides/observability/inspect.mdx similarity index 94% rename from apps/docs/content/guides/monitoring-and-debugging/inspect.mdx rename to apps/docs/content/guides/observability/inspect.mdx index 8169aeda1e9..41dde492d6a 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/inspect.mdx +++ b/apps/docs/content/guides/observability/inspect.mdx @@ -6,14 +6,18 @@ description: 'Read live Postgres statistics such as bloat, cache hit rate, locks Database performance is a large topic and many factors can contribute. Common causes of poor performance include inefficient schemas or queries, missing or unused indexes, insufficient memory, lock contention, and table bloat. -Use the live Postgres statistics in this guide to check for those conditions. The same checks run as `supabase inspect db` commands, as SQL in the [SQL Editor](/dashboard/project/_/sql), or as MCP `execute_sql`. +Use the live Postgres statistics in this guide to check for those conditions. You or an agent can run the same checks from: + +- Studio: [SQL Editor](/dashboard/project/_/sql) +- MCP: `execute_sql` +- CLI: [`supabase inspect db`](/docs/reference/cli/supabase-inspect-db) Use this page to: - Run [CLI inspection commands](#using-the-cli) - Copy the matching [SQL](#using-sql) -If you are checking whether something is wrong, start with the [debugging guide](/docs/guides/monitoring-and-debugging/debugging). For project logs, metrics, and advisors, see [Observe the data](/docs/guides/monitoring-and-debugging/access-data). +To pick up a signal from these checks, see [Detecting](/docs/guides/observability/detecting). For the other sources, see [Observe the data](/docs/guides/observability/access-data). ## Using the CLI @@ -238,6 +242,6 @@ from pg_statio_user_tables; This shows the ratio of data blocks fetched from the Postgres [shared_buffers](https://www.postgresql.org/docs/15/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY) cache against the data blocks that were read from disk or the OS cache. -A ratio below 99% means more than 1% of observed block accesses missed `shared_buffers`. Postgres cannot distinguish whether those reads were served by the operating system cache or physical disk. Treat that as a performance signal in the [debugging guide](/docs/guides/monitoring-and-debugging/debugging), then search [troubleshooting](/docs/guides/troubleshooting). +A ratio below 99% means more than 1% of observed block accesses missed `shared_buffers`. Postgres cannot distinguish whether those reads were served by the operating system cache or physical disk. Treat that as a [Performance](/docs/guides/observability/detecting#performance) signal, then search [Diagnosing](/docs/guides/troubleshooting). -When a check names a slow statement, get a query plan with [`explain`](/docs/guides/database/query-optimization#analyze-the-query-plan) in SQL, or [`explain()`](/docs/guides/database/debugging-performance) on the Data API. Pair `pg_stat_statements` with the [Metrics API](/docs/guides/monitoring-and-debugging/metrics) to read the same window from Postgres stats and host metrics. +When a check names a slow statement, get a query plan with [`explain`](/docs/guides/database/query-optimization#analyze-the-query-plan) in SQL, or [`explain()`](/docs/guides/database/debugging-performance) on the Data API. Pair `pg_stat_statements` with the [Metrics API](/docs/guides/observability/metrics) to read the same window from Postgres stats and host metrics. diff --git a/apps/docs/content/guides/monitoring-and-debugging/log-drains.mdx b/apps/docs/content/guides/observability/log-drains.mdx similarity index 96% rename from apps/docs/content/guides/monitoring-and-debugging/log-drains.mdx rename to apps/docs/content/guides/observability/log-drains.mdx index 21216bba6fb..968578c30aa 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/log-drains.mdx +++ b/apps/docs/content/guides/observability/log-drains.mdx @@ -9,7 +9,7 @@ Log drains send all logs of the Supabase stack to one or more desired destinatio ## What you can do with log drains - Route Supabase logs (Postgres, Auth, Storage, Edge Functions, and more) to any observability platform. -- Combine Supabase logs with application-level traces — see [Tracing with the JS SDK](/docs/guides/monitoring-and-debugging/client-side-tracing) to extend your traces into Supabase. +- Combine Supabase logs with application-level traces — see [Tracing with the JS SDK](/docs/guides/observability/client-side-tracing) to extend your traces into Supabase. - Archive logs to S3 for long-term retention and compliance. - Build alerts and dashboards on top of Supabase log data in your preferred vendor. @@ -335,5 +335,5 @@ Logs are forwarded to a remote Syslog receiver using TCP or TLS, adhering to [RF ## Additional resources - [Log Drains pricing breakdown](/docs/guides/platform/manage-your-usage/log-drains) — cost per drain, per million events, and egress charges. -- [Metrics API](/docs/guides/monitoring-and-debugging/metrics) — export Postgres performance metrics alongside your logs. -- [Tracing with the JS SDK](/docs/guides/monitoring-and-debugging/client-side-tracing) — instrument your application and combine traces with Supabase logs. +- [Metrics API](/docs/guides/observability/metrics) — export Postgres performance metrics alongside your logs. +- [Tracing with the JS SDK](/docs/guides/observability/client-side-tracing) — instrument your application and combine traces with Supabase logs. diff --git a/apps/docs/content/guides/monitoring-and-debugging/log-field-reference.mdx b/apps/docs/content/guides/observability/log-field-reference.mdx similarity index 94% rename from apps/docs/content/guides/monitoring-and-debugging/log-field-reference.mdx rename to apps/docs/content/guides/observability/log-field-reference.mdx index a42ae51c09a..ded838e551b 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/log-field-reference.mdx +++ b/apps/docs/content/guides/observability/log-field-reference.mdx @@ -6,7 +6,7 @@ description: 'Supabase Logs field reference' Use this reference to find the fields available for each log source. Query `id`, `timestamp`, `event_message`, and `source` as top-level columns. Other structured fields are keys in the `log_attributes` map: drop the `metadata.` prefix shown in the source schema and keep the rest of the dotted path. -For example, the schema path `metadata.request.cf.country` is queried as `log_attributes['request.cf.country']`. See [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering) for complete ClickHouse examples. +For example, the schema path `metadata.request.cf.country` is queried as `log_attributes['request.cf.country']`. See [Query and filter logs](/docs/guides/observability/advanced-log-filtering) for complete ClickHouse examples. {(logConstants) => ( diff --git a/apps/docs/content/guides/monitoring-and-debugging/logs.mdx b/apps/docs/content/guides/observability/logs.mdx similarity index 84% rename from apps/docs/content/guides/monitoring-and-debugging/logs.mdx rename to apps/docs/content/guides/observability/logs.mdx index 83850fd7117..6d8b9f62278 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/logs.mdx +++ b/apps/docs/content/guides/observability/logs.mdx @@ -6,11 +6,11 @@ description: 'Inspect project log events in the unified Logs view in Studio' This guide explains how to inspect project logs in Studio. Log retention is based on your [project's pricing plan](/pricing). For details on how Logs usage is billed, see [Manage Logs usage](/docs/guides/platform/manage-your-usage/logs). -Use this page to filter and inspect events in [Logs](#product-logs). To query the same data with SQL from Studio, MCP, the API, or a script, or to record extra Postgres, API, and Realtime events, see [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering). +Use this page to filter and inspect events in [Logs](#product-logs). To query the same data with SQL from Studio, MCP, the API, or a script, or to record extra Postgres, API, and Realtime events, see [Query and filter logs](/docs/guides/observability/advanced-log-filtering). -If you already have a specific error, start at [Find the guide for your symptom](/docs/guides/monitoring-and-debugging/debugging#find-the-guide-for-your-symptom). If you are checking whether the project is healthy, start with the [debugging guide](/docs/guides/monitoring-and-debugging/debugging). +If you already have a specific error, start at [Diagnosing](/docs/guides/troubleshooting). To pick up a signal from these events, see [Detecting](/docs/guides/observability/detecting). @@ -22,7 +22,7 @@ If you don't select a log type, Logs queries **Postgres** and **API Gateway** ev -For regular expression filtering, structured-field queries, and field discovery, see [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering). +For regular expression filtering, structured-field queries, and field discovery, see [Query and filter logs](/docs/guides/observability/advanced-log-filtering). @@ -38,7 +38,7 @@ Refresh the table, hide columns, download matching rows as CSV or JSON, or turn ### Log types -Selecting a log type in Studio queries the matching ClickHouse `source`. For the `source` names to use in SQL, see [Sources](/docs/guides/monitoring-and-debugging/advanced-log-filtering#logs-explorer). +Selecting a log type in Studio queries the matching ClickHouse `source`. For the `source` names to use in SQL, see [Sources](/docs/guides/observability/advanced-log-filtering#logs-explorer). | Log type | Events | | ------------- | ----------------------------------------------------------------- | @@ -56,9 +56,9 @@ Selecting **API Gateway** is not the same as selecting **Auth**, **Storage**, or ### Postgres [#postgres] -Postgres logs show queries and activity for your database. Connection lifecycle events appear here when [connection logging](/docs/guides/monitoring-and-debugging/advanced-log-filtering#logging-postgres-connections) is enabled. They are included by default; clear **Connection logs** under the Postgres log type to hide them. +Postgres logs show queries and activity for your database. Connection lifecycle events appear here when [connection logging](/docs/guides/observability/advanced-log-filtering#logging-postgres-connections) is enabled. They are included by default; clear **Connection logs** under the Postgres log type to hide them. -To record additional statement classes, see [Logging Postgres queries](/docs/guides/monitoring-and-debugging/advanced-log-filtering#logging-postgres-queries). +To record additional statement classes, see [Logging Postgres queries](/docs/guides/observability/advanced-log-filtering#logging-postgres-queries). ### Inspect a log diff --git a/apps/docs/content/guides/monitoring-and-debugging/metrics.mdx b/apps/docs/content/guides/observability/metrics.mdx similarity index 89% rename from apps/docs/content/guides/monitoring-and-debugging/metrics.mdx rename to apps/docs/content/guides/observability/metrics.mdx index addbd36aba8..bb7b7eec043 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/metrics.mdx +++ b/apps/docs/content/guides/observability/metrics.mdx @@ -6,6 +6,8 @@ description: 'Export Supabase database metrics to any Prometheus-compatible tool Every Supabase project exposes a [Prometheus](https://prometheus.io/)-compatible **Metrics API** endpoint that surfaces ~200 Postgres performance and health series. You can scrape it into any observability stack to power custom dashboards, alerting rules, or long-term retention that goes beyond what Supabase Studio provides out of the box. +Chart a subset of the same window in Studio [Reports](/docs/guides/observability/reports). Use this page when you want the Prometheus-compatible scrape endpoint. + The Metrics API is currently in beta. Metric names and labels might evolve as we expand the dataset, and the feature is not available in self-hosted Supabase instances. @@ -40,5 +42,5 @@ Pick the workflow that best matches your tooling. Cards link to Supabase-authore - [Grafana Cloud’s Supabase integration doc](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-supabase/) (community-maintained, built on this Metrics API). - [Datadog’s Supabase integration doc](https://docs.datadoghq.com/integrations/supabase/) (community-maintained, built on this Metrics API). - [Elastic’s Supabase integration doc](https://www.elastic.co/docs/reference/integrations/supabase) (community-maintained). -- [Log Drains ](/docs/guides/monitoring-and-debugging/log-drains) for exporting event-based telemetry alongside metrics. +- [Log Drains ](/docs/guides/observability/log-drains) for exporting event-based telemetry alongside metrics. - [Query Performance report](/dashboard/project/_/observability/query-performance) for built-in visualizations based on the same underlying metrics. diff --git a/apps/docs/content/guides/monitoring-and-debugging/metrics/grafana-cloud.mdx b/apps/docs/content/guides/observability/metrics/grafana-cloud.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/metrics/grafana-cloud.mdx rename to apps/docs/content/guides/observability/metrics/grafana-cloud.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/metrics/grafana-self-hosted.mdx b/apps/docs/content/guides/observability/metrics/grafana-self-hosted.mdx similarity index 95% rename from apps/docs/content/guides/monitoring-and-debugging/metrics/grafana-self-hosted.mdx rename to apps/docs/content/guides/observability/metrics/grafana-self-hosted.mdx index ad4ec6fc6b6..aa0de4b6ee5 100644 --- a/apps/docs/content/guides/monitoring-and-debugging/metrics/grafana-self-hosted.mdx +++ b/apps/docs/content/guides/observability/metrics/grafana-self-hosted.mdx @@ -10,7 +10,7 @@ Self-hosting [Prometheus](https://prometheus.io/docs/prometheus/latest/installat Use this guide only if you need full manual control (custom scrape topology, self-hosted Prometheus or non-standard auth). -Otherwise, use the [Grafana Cloud integration](/docs/guides/monitoring-and-debugging/metrics/grafana-cloud#installation) available in the Supabase Dashboard. +Otherwise, use the [Grafana Cloud integration](/docs/guides/observability/metrics/grafana-cloud#installation) available in the Supabase Dashboard. diff --git a/apps/docs/content/guides/monitoring-and-debugging/metrics/vendor-agnostic.mdx b/apps/docs/content/guides/observability/metrics/vendor-agnostic.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/metrics/vendor-agnostic.mdx rename to apps/docs/content/guides/observability/metrics/vendor-agnostic.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/reports.mdx b/apps/docs/content/guides/observability/reports.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/reports.mdx rename to apps/docs/content/guides/observability/reports.mdx diff --git a/apps/docs/content/guides/monitoring-and-debugging/sentry-monitoring.mdx b/apps/docs/content/guides/observability/sentry-monitoring.mdx similarity index 100% rename from apps/docs/content/guides/monitoring-and-debugging/sentry-monitoring.mdx rename to apps/docs/content/guides/observability/sentry-monitoring.mdx diff --git a/apps/docs/content/guides/platform/billing-faq.mdx b/apps/docs/content/guides/platform/billing-faq.mdx index 30c52f06d4e..e38bb37e388 100644 --- a/apps/docs/content/guides/platform/billing-faq.mdx +++ b/apps/docs/content/guides/platform/billing-faq.mdx @@ -12,7 +12,7 @@ subtitle: 'This documentation covers frequently asked questions around subscript ### What are organizations and projects? The Supabase Platform has "organizations" and "projects". An organization may contain multiple projects. Each project is a dedicated Supabase instance with all of its sub-services including Storage, Auth, Functions and Realtime. -Each organization only has a single subscription with a single plan (Free, Pro, Team or Enterprise). Project add-ons such as [Compute](/docs/guides/platform/compute-and-disk), [IPv4](/docs/guides/platform/ipv4-address), [Log Drains](/docs/guides/monitoring-and-debugging/log-drains), [Advanced MFA](/docs/guides/auth/auth-mfa/phone), [Custom Domains](/docs/guides/platform/custom-domains) and [PITR](/docs/guides/platform/backups#point-in-time-recovery) are configured per project and are added to your organization subscription. +Each organization only has a single subscription with a single plan (Free, Pro, Team or Enterprise). Project add-ons such as [Compute](/docs/guides/platform/compute-and-disk), [IPv4](/docs/guides/platform/ipv4-address), [Log Drains](/docs/guides/observability/log-drains), [Advanced MFA](/docs/guides/auth/auth-mfa/phone), [Custom Domains](/docs/guides/platform/custom-domains) and [PITR](/docs/guides/platform/backups#point-in-time-recovery) are configured per project and are added to your organization subscription. Read more on [About billing on Supabase](/docs/guides/platform/billing-on-supabase#organization-based-billing). diff --git a/apps/docs/content/guides/platform/billing-on-supabase.mdx b/apps/docs/content/guides/platform/billing-on-supabase.mdx index cee1f1eeb8f..deb7484c30d 100644 --- a/apps/docs/content/guides/platform/billing-on-supabase.mdx +++ b/apps/docs/content/guides/platform/billing-on-supabase.mdx @@ -84,7 +84,7 @@ While your subscription plan applies to your entire organization and is charged - [Compute](/docs/guides/platform/compute-and-disk#compute) to scale your database up to 64 cores and 256 GB RAM - [Read Replicas](/docs/guides/platform/read-replicas) to scale read operations and provide resiliency - [Disk](/docs/guides/platform/compute-and-disk#disk) to provision extra IOPS/throughput or use a high-performance SSD -- [Log Drains](/docs/guides/monitoring-and-debugging/log-drains) to sync Supabase logs to a logging system of your choice +- [Log Drains](/docs/guides/observability/log-drains) to sync Supabase logs to a logging system of your choice - [Custom Domains](/docs/guides/platform/custom-domains) to provide a branded experience - [PITR](/docs/guides/platform/backups#point-in-time-recovery) to roll back to any specific point in time, down to the minute - [IPv4](/docs/guides/platform/ipv4-address) for a dedicated IPv4 address diff --git a/apps/docs/content/guides/platform/performance.mdx b/apps/docs/content/guides/platform/performance.mdx index ffda5f369cf..246ad18e91d 100644 --- a/apps/docs/content/guides/platform/performance.mdx +++ b/apps/docs/content/guides/platform/performance.mdx @@ -8,7 +8,7 @@ The Supabase platform automatically optimizes your Postgres database to take adv ## Examining query performance -Unoptimized queries are a major cause of poor database performance. To analyze the performance of your queries, see [Inspect the database](/docs/guides/monitoring-and-debugging/inspect). +Unoptimized queries are a major cause of poor database performance. To analyze the performance of your queries, see [Inspect the database](/docs/guides/observability/inspect). ## Optimizing the number of connections diff --git a/apps/docs/content/guides/platform/postgres-connection-logging.mdx b/apps/docs/content/guides/platform/postgres-connection-logging.mdx index c8ad8eb1c0a..b0ef15ab47d 100644 --- a/apps/docs/content/guides/platform/postgres-connection-logging.mdx +++ b/apps/docs/content/guides/platform/postgres-connection-logging.mdx @@ -4,7 +4,7 @@ title: 'Postgres connection logging' description: 'Enable or disable Postgres connection logging for audit and compliance.' --- -For security monitoring and compliance audits, Postgres can log connection lifecycle events to your project's [Postgres logs](/docs/guides/monitoring-and-debugging/logs#postgres), including events such as `connection received`, `connection authenticated`, and `connection authorized`. +For security monitoring and compliance audits, Postgres can log connection lifecycle events to your project's [Postgres logs](/docs/guides/observability/logs#postgres), including events such as `connection received`, `connection authenticated`, and `connection authorized`. ## Default behavior @@ -28,7 +28,7 @@ Connection logging supports audit and monitoring controls required by some compl - **HIPAA** — High-compliance projects should keep connection logging enabled. See the [shared responsibility model for healthcare data](/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) and [HIPAA compliance guide](/docs/guides/security/hipaa-compliance). - **SOC 2** — Users who need connection audit evidence should enable logging and retain logs according to their own policies. See the [SOC 2 compliance guide](/docs/guides/security/soc-2-compliance). -Disabling connection logging does not affect other Supabase logging (for example, [Platform Audit Logs](/docs/guides/security/platform-audit-logs), [Auth Audit Logs](/docs/guides/auth/audit-logs), or [pgAudit](/docs/guides/monitoring-and-debugging/advanced-log-filtering#configuring-pgauditlog)). +Disabling connection logging does not affect other Supabase logging (for example, [Platform Audit Logs](/docs/guides/security/platform-audit-logs), [Auth Audit Logs](/docs/guides/auth/audit-logs), or [pgAudit](/docs/guides/observability/advanced-log-filtering#configuring-pgauditlog)). ## Manage connection logging via the dashboard @@ -38,7 +38,7 @@ Ensure that you have [Owner or Admin permissions](/docs/guides/platform/access-c -Connection events appear in [Postgres logs](/docs/guides/monitoring-and-debugging/logs#postgres). They are included by default when the Postgres log type is selected. Clear **Connection logs** under Postgres to hide them. +Connection events appear in [Postgres logs](/docs/guides/observability/logs#postgres). They are included by default when the Postgres log type is selected. Clear **Connection logs** under Postgres to hide them. diff --git a/apps/docs/content/guides/platform/project-transfer.mdx b/apps/docs/content/guides/platform/project-transfer.mdx index cc4718c6340..f4152076a10 100644 --- a/apps/docs/content/guides/platform/project-transfer.mdx +++ b/apps/docs/content/guides/platform/project-transfer.mdx @@ -43,7 +43,7 @@ Target organization - the organization you want to move the project to ## Usage-billing and project add-ons -For usage metrics such as disk size, egress or image transformations and project add-ons such as [Compute Add-On](/docs/guides/platform/compute-and-disk), [Point-In-Time-Recovery](/docs/guides/platform/backups#point-in-time-recovery), [IPv4](/docs/guides/platform/ipv4-address), [Log Drains](/docs/guides/monitoring-and-debugging/log-drains), [Advanced MFA](/docs/guides/auth/auth-mfa/phone) or a [Custom Domain](/docs/guides/platform/custom-domains), the source organization will still be charged for the usage up until the transfer. The charges will be added to the invoice when the billing cycle resets. +For usage metrics such as disk size, egress or image transformations and project add-ons such as [Compute Add-On](/docs/guides/platform/compute-and-disk), [Point-In-Time-Recovery](/docs/guides/platform/backups#point-in-time-recovery), [IPv4](/docs/guides/platform/ipv4-address), [Log Drains](/docs/guides/observability/log-drains), [Advanced MFA](/docs/guides/auth/auth-mfa/phone) or a [Custom Domain](/docs/guides/platform/custom-domains), the source organization will still be charged for the usage up until the transfer. The charges will be added to the invoice when the billing cycle resets. The target organization will be charged at the end of the billing cycle for usage after the project transfer. diff --git a/apps/docs/content/guides/platform/read-replicas.mdx b/apps/docs/content/guides/platform/read-replicas.mdx index a92f1776321..a5f80918644 100644 --- a/apps/docs/content/guides/platform/read-replicas.mdx +++ b/apps/docs/content/guides/platform/read-replicas.mdx @@ -152,7 +152,7 @@ When a Read Replica is deployed, it emits logs from the following services: - [PostgREST](/dashboard/project/_/logs/postgrest-logs) - [Supavisor](/dashboard/project/_/logs/pooler-logs) -Single-service [log collections](/docs/guides/monitoring-and-debugging/logs#single-service-collections) filter by database, with the Primary database displayed by default. Switch databases with the **Source** control. +Single-service [log collections](/docs/guides/observability/logs#single-service-collections) filter by database, with the Primary database displayed by default. Switch databases with the **Source** control. For API logs, logs can originate from the API Load Balancer as well. The upstream database or the one that eventually handles the request can be found under the `Redirect Identifier` field. This is equivalent to `metadata.load_balancer_redirect_identifier` when querying the underlying logs. @@ -160,7 +160,7 @@ For API logs, logs can originate from the API Load Balancer as well. The upstrea Observability and metrics for Read Replicas are available on the Supabase Dashboard. Resource utilization for a specific Read Replica can be viewed on the [Database Reports page](/dashboard/project/_/observability/database) by toggling for `Source`. Likewise, metrics on API requests going through either a Read Replica or Load Balancer API endpoint are also available on the dashboard through the [API Reports page](/dashboard/project/_/observability/api-overview) -We recommend ingesting your [project's metrics](/docs/guides/monitoring-and-debugging/metrics) into your own environment. If you have an existing ingestion pipeline set up for your project, you can [update it](https://github.com/supabase/supabase-grafana?tab=readme-ov-file#read-replica-support) to additionally ingest metrics from your Read Replicas. +We recommend ingesting your [project's metrics](/docs/guides/observability/metrics) into your own environment. If you have an existing ingestion pipeline set up for your project, you can [update it](https://github.com/supabase/supabase-grafana?tab=readme-ov-file#read-replica-support) to additionally ingest metrics from your Read Replicas. ### Centralized configuration management diff --git a/apps/docs/content/guides/platform/read-replicas/getting-started.mdx b/apps/docs/content/guides/platform/read-replicas/getting-started.mdx index 9a0d885041f..d376490f459 100644 --- a/apps/docs/content/guides/platform/read-replicas/getting-started.mdx +++ b/apps/docs/content/guides/platform/read-replicas/getting-started.mdx @@ -129,7 +129,7 @@ There is no single threshold to indicate when you should address replication lag -If you are already ingesting your [project's metrics](/docs/guides/monitoring-and-debugging/metrics) into your own environment, you can also keep track of replication lag and set alarms with the `physical_replication_lag_physical_replica_lag_seconds` metric. +If you are already ingesting your [project's metrics](/docs/guides/observability/metrics) into your own environment, you can also keep track of replication lag and set alarms with the `physical_replication_lag_physical_replica_lag_seconds` metric. diff --git a/apps/docs/content/guides/realtime/reports.mdx b/apps/docs/content/guides/realtime/reports.mdx index 48f073c5d23..a40553a12e6 100644 --- a/apps/docs/content/guides/realtime/reports.mdx +++ b/apps/docs/content/guides/realtime/reports.mdx @@ -239,7 +239,7 @@ height={625} | Check logs | Investigate replication errors or performance issues in your project dashboard | [Realtime Logs Dashboard](/dashboard/project/_/database/realtime-logs) | | Monitor database | Review database resource utilization, connection counts, and query performance that may affect replication | [Database Observability Dashboard](/dashboard/project/_/observability/database) | | Review replication metrics | Use `pg_stat_subscription`, `pg_replication_slots`, and other Postgres views to diagnose replication issues | [manual replication monitoring guide](/docs/guides/database/replication/manual-replication-monitoring) | -| Debug database issues | Use CLI inspection tools to identify bloat, lock contention, and long-running queries affecting replication | [Inspect the database](/docs/guides/monitoring-and-debugging/inspect) | +| Debug database issues | Use CLI inspection tools to identify bloat, lock contention, and long-running queries affecting replication | [Inspect the database](/docs/guides/observability/inspect) | | Optimize performance | Optimize query performance and connection management to reduce database load | [Performance Tuning Guide](/docs/guides/platform/performance) | | Configure timeouts | Configure statement timeouts to prevent long-running transactions from blocking replication | [Database Timeouts Guide](/docs/guides/database/postgres/timeouts) | | Learn broadcast from DB | Understand how broadcast from database works and best practices for implementation | [Broadcast from Database Guide](/docs/guides/realtime/broadcast#trigger-broadcast-messages-from-your-database) | diff --git a/apps/docs/content/guides/security/platform-audit-logs.mdx b/apps/docs/content/guides/security/platform-audit-logs.mdx index 47344d01696..47f6554e977 100644 --- a/apps/docs/content/guides/security/platform-audit-logs.mdx +++ b/apps/docs/content/guides/security/platform-audit-logs.mdx @@ -46,7 +46,7 @@ Each Supabase user account also has access to [Account Audit logs](/dashboard/ac ## Accessing Audit Log Drains -Audit Log Drains can be configured under your [organization's audit log drains](/dashboard/org/_/audit-log-drains). For setup instructions and supported destinations, see the [Log Drains guide](/docs/guides/monitoring-and-debugging/log-drains). +Audit Log Drains can be configured under your [organization's audit log drains](/dashboard/org/_/audit-log-drains). For setup instructions and supported destinations, see the [Log Drains guide](/docs/guides/observability/log-drains). ## Limitations diff --git a/apps/docs/content/guides/storage/cdn/metrics.mdx b/apps/docs/content/guides/storage/cdn/metrics.mdx index 3e5fb61367d..30156f93517 100644 --- a/apps/docs/content/guides/storage/cdn/metrics.mdx +++ b/apps/docs/content/guides/storage/cdn/metrics.mdx @@ -5,7 +5,7 @@ description: 'Learn how Supabase Storage caches objects with a CDN.' sidebar_label: 'CDN' --- -Cache hits can be determined via the `log_attributes['response.headers.cf_cache_status']` key in [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering#logs-explorer). Any value that corresponds to either `HIT`, `STALE`, `REVALIDATED`, or `UPDATING` is categorized as a cache hit. +Cache hits can be determined via the `log_attributes['response.headers.cf_cache_status']` key in [Query and filter logs](/docs/guides/observability/advanced-log-filtering#logs-explorer). Any value that corresponds to either `HIT`, `STALE`, `REVALIDATED`, or `UPDATING` is categorized as a cache hit. The following example query will show the top cache misses from the `edge_logs`: ```sql diff --git a/apps/docs/content/guides/storage/debugging/logs.mdx b/apps/docs/content/guides/storage/debugging/logs.mdx index fd879761d9a..2d188d8ed9f 100644 --- a/apps/docs/content/guides/storage/debugging/logs.mdx +++ b/apps/docs/content/guides/storage/debugging/logs.mdx @@ -11,7 +11,7 @@ For more advanced filtering needs, use the [SQL Editor](/dashboard/project/_/sql -For more details on filtering the log tables, see [Query and filter logs](/docs/guides/monitoring-and-debugging/advanced-log-filtering) +For more details on filtering the log tables, see [Query and filter logs](/docs/guides/observability/advanced-log-filtering) diff --git a/apps/docs/content/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9.mdx b/apps/docs/content/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9.mdx index 24fde54c165..a355e065278 100644 --- a/apps/docs/content/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9.mdx +++ b/apps/docs/content/troubleshooting/discovering-and-interpreting-api-errors-in-the-logs-7xREI9.mdx @@ -39,7 +39,7 @@ limit 100; The most useful fields for debugging are: -> NOTE: not every field is included below. For a full list, check the API Gateway and Function Edge [logs field reference](/docs/guides/monitoring-and-debugging/log-field-reference). +> NOTE: not every field is included below. For a full list, check the API Gateway and Function Edge [logs field reference](/docs/guides/observability/log-field-reference). ### Request object diff --git a/apps/docs/content/troubleshooting/exhaust-disk-io.mdx b/apps/docs/content/troubleshooting/exhaust-disk-io.mdx index 0df86d3eaac..5d7b5451eb2 100644 --- a/apps/docs/content/troubleshooting/exhaust-disk-io.mdx +++ b/apps/docs/content/troubleshooting/exhaust-disk-io.mdx @@ -25,7 +25,7 @@ Running out of Disk IO Budget means that your instance is using more disk than i To check your Disk IO Budget on the Supabase Platform, head over to [Database Health in the Observability section](/dashboard/project/_/observability/database). -It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. With Grafana you will be able to pinpoint potential causes and see more fine-grained metrics like how much of your RAM is used for caching and your Swap usage. Read the [Metrics Guide](/docs/guides/monitoring-and-debugging/metrics) to learn more. +It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. With Grafana you will be able to pinpoint potential causes and see more fine-grained metrics like how much of your RAM is used for caching and your Swap usage. Read the [Metrics Guide](/docs/guides/observability/metrics) to learn more. ## Common reasons for high disk IO usage diff --git a/apps/docs/content/troubleshooting/exhaust-ram.mdx b/apps/docs/content/troubleshooting/exhaust-ram.mdx index 30351258315..51128f0f31e 100644 --- a/apps/docs/content/troubleshooting/exhaust-ram.mdx +++ b/apps/docs/content/troubleshooting/exhaust-ram.mdx @@ -31,7 +31,7 @@ High RAM usage could come with a range of issues: To check your RAM usage on the Supabase Platform, head over to [Database Health in the Observability section](/dashboard/project/_/observability/database). -It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. With Grafana you will be able to see how much of your RAM is used for caching and you can track other metrics such as your Swap usage. Read the [Metrics Guide](/docs/guides/monitoring-and-debugging/metrics) to learn more. +It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. With Grafana you will be able to see how much of your RAM is used for caching and you can track other metrics such as your Swap usage. Read the [Metrics Guide](/docs/guides/observability/metrics) to learn more. ## Common reasons for high RAM usage diff --git a/apps/docs/content/troubleshooting/exhaust-swap.mdx b/apps/docs/content/troubleshooting/exhaust-swap.mdx index 5f8b5c60f20..db0ea394ee2 100644 --- a/apps/docs/content/troubleshooting/exhaust-swap.mdx +++ b/apps/docs/content/troubleshooting/exhaust-swap.mdx @@ -33,7 +33,7 @@ High Swap usage can affect your database performance. For example, you might see ## Monitor your swap -You can monitor your resources and set up alerts using Prometheus/Grafana. See the [metrics guide](/docs/guides/monitoring-and-debugging/metrics) for more information. +You can monitor your resources and set up alerts using Prometheus/Grafana. See the [metrics guide](/docs/guides/observability/metrics) for more information. An [example repository](https://github.com/supabase/supabase-grafana) to ingest metrics and visualize them with Grafana is provided in the linked guide, where we maintain a [list of the exported metrics](https://github.com/supabase/supabase-grafana/blob/main/docs/metrics.md). diff --git a/apps/docs/content/troubleshooting/failed-to-retrieve-tables.mdx b/apps/docs/content/troubleshooting/failed-to-retrieve-tables.mdx index acda37f4d4c..6bd2d9327a1 100644 --- a/apps/docs/content/troubleshooting/failed-to-retrieve-tables.mdx +++ b/apps/docs/content/troubleshooting/failed-to-retrieve-tables.mdx @@ -43,4 +43,4 @@ Once you are confident there will not be a crash loop, you can review the follow - Continue to monitor your project's [query performance tab](/dashboard/project/_/observability/query-performance) and [enable index advisor](/docs/guides/database/extensions/index_advisor) if you haven't already - especially if there are a lot of select queries. - If after monitoring your changes you still do not notice improvements, consider upgrading compute if you think this level of activity is going to be regular. It will give you more memory overhead to process tasks like this. You can view all compute offerings [here](/dashboard/project/_/settings/infrastructure). -If you want to effectively monitor your project's performance minute by minute, you can use the [Metrics API](/docs/guides/monitoring-and-debugging/metrics). +If you want to effectively monitor your project's performance minute by minute, you can use the [Metrics API](/docs/guides/observability/metrics). diff --git a/apps/docs/content/troubleshooting/failed-to-run-sql-query-connection-terminated-due-to-connection-timeout.mdx b/apps/docs/content/troubleshooting/failed-to-run-sql-query-connection-terminated-due-to-connection-timeout.mdx index 351692dc37c..e10774c29ec 100644 --- a/apps/docs/content/troubleshooting/failed-to-run-sql-query-connection-terminated-due-to-connection-timeout.mdx +++ b/apps/docs/content/troubleshooting/failed-to-run-sql-query-connection-terminated-due-to-connection-timeout.mdx @@ -23,4 +23,4 @@ Review the appropriate guides based on your scenario: - [High Disk I/O](/docs/guides/troubleshooting/exhaust-disk-io) - [Query optimization](/docs/guides/database/query-optimization) -You can also set up alerts using a [Prometheus endpoint / Grafana charts](/docs/guides/monitoring-and-debugging/metrics) to monitor vital resources. +You can also set up alerts using a [Prometheus endpoint / Grafana charts](/docs/guides/observability/metrics) to monitor vital resources. diff --git a/apps/docs/content/troubleshooting/grafana-not-displaying-data-sXJrMj.mdx b/apps/docs/content/troubleshooting/grafana-not-displaying-data-sXJrMj.mdx index c13e0e40dd2..34616aeec83 100644 --- a/apps/docs/content/troubleshooting/grafana-not-displaying-data-sXJrMj.mdx +++ b/apps/docs/content/troubleshooting/grafana-not-displaying-data-sXJrMj.mdx @@ -7,7 +7,7 @@ keywords = [ "grafana", "docker", "metrics", "configuration" ] database_id = "76a4099e-450f-4b5b-a539-224760348c18" --- -This guide is for identifying configuration mistakes in [self-hosted Supabase Grafana installations](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) +This guide is for identifying configuration mistakes in [self-hosted Supabase Grafana installations](/docs/guides/observability/metrics/grafana-self-hosted) ## Step 1: Ping your Grafana endpoint diff --git a/apps/docs/content/troubleshooting/high-cpu-usage.mdx b/apps/docs/content/troubleshooting/high-cpu-usage.mdx index eedcf49ba23..dcf18aa4290 100644 --- a/apps/docs/content/troubleshooting/high-cpu-usage.mdx +++ b/apps/docs/content/troubleshooting/high-cpu-usage.mdx @@ -25,7 +25,7 @@ You can check your CPU usage directly on the Supabase Platform. For this go to d ![CPU usage reported on Supabase dashboard](/docs/img/guides/platform/exhaust-cpu-report.png) -It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. You can find a guide for this [here](/docs/guides/monitoring-and-debugging/metrics). +It is also possible to monitor your resources and set up alerts using Prometheus/Grafana. You can find a guide for this [here](/docs/guides/observability/metrics). ## Common reasons for high CPU usage diff --git a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx index f2045b422d3..d588c5a938f 100644 --- a/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx +++ b/apps/docs/content/troubleshooting/how-to-interpret-and-explore-the-postgres-logs-OuCIOj.mdx @@ -391,5 +391,5 @@ To see the default types of events that are logged, you can check this [guide](h - [Debugging with the DB API logs](https://github.com/orgs/supabase/discussions/22849) - [Debugging Database Functions](/docs/guides/database/functions#debugging-functions) - [pg_audit](/docs/guides/database/extensions/pgaudit) -- [Supabase Logging](/docs/guides/monitoring-and-debugging/logs) +- [Supabase Logging](/docs/guides/observability/logs) - [Self-Hosting Logs](/docs/reference/self-hosting-analytics/introduction) diff --git a/apps/docs/content/troubleshooting/how-to-view-database-metrics-uqf2z_.mdx b/apps/docs/content/troubleshooting/how-to-view-database-metrics-uqf2z_.mdx index ee301203a7d..3587783f45d 100644 --- a/apps/docs/content/troubleshooting/how-to-view-database-metrics-uqf2z_.mdx +++ b/apps/docs/content/troubleshooting/how-to-view-database-metrics-uqf2z_.mdx @@ -7,6 +7,6 @@ keywords = [ "metrics", "grafana", "monitoring" ] database_id = "da2d95e5-abc5-47c8-8389-1554d12abf91" --- -To monitor real-time metrics of your database, like CPU, EBS, active database connections, and memory usage, you can deploy a Grafana Dashboard. Check our [GitHub repo](https://github.com/supabase/supabase-grafana) for setup instructions for local or free [Fly.io](http://fly.io/) deployments. Refer to our concise [documentation](/docs/guides/monitoring-and-debugging/metrics) to learn more about the metrics endpoint. +To monitor real-time metrics of your database, like CPU, EBS, active database connections, and memory usage, you can deploy a Grafana Dashboard. Check our [GitHub repo](https://github.com/supabase/supabase-grafana) for setup instructions for local or free [Fly.io](http://fly.io/) deployments. Refer to our concise [documentation](/docs/guides/observability/metrics) to learn more about the metrics endpoint. While the [Dashboard's Reports Page](/dashboard/project/_/observability) displays some metric data, it provides hourly averages, not real-time by the second data. However, it offers query metrics, which the Grafana Dashboard does not include. diff --git a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-cpu-charts-9JSlkC.mdx b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-cpu-charts-9JSlkC.mdx index 5e86d52777e..8d8506516f5 100644 --- a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-cpu-charts-9JSlkC.mdx +++ b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-cpu-charts-9JSlkC.mdx @@ -7,7 +7,7 @@ keywords = [ "cpu", "grafana", "metrics" ] database_id = "ef05da0a-f8bc-44a4-9719-5ae811dba104" --- -> [Guide](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) for setting up Supabase Grafana +> [Guide](/docs/guides/observability/metrics/grafana-self-hosted) for setting up Supabase Grafana ## CPU diff --git a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx index 3b93646ebe2..bdca726ddb9 100644 --- a/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx +++ b/apps/docs/content/troubleshooting/interpreting-supabase-grafana-io-charts-MUynDR.mdx @@ -7,7 +7,7 @@ keywords = [ "io", "disk", "database", "grafana" ] database_id = "0056cd40-df04-4045-bbfb-c245cb15b85d" --- -> [Supabase Grafana Installation Guide](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) +> [Supabase Grafana Installation Guide](/docs/guides/observability/metrics/grafana-self-hosted) There are two primary values that matter for IO: diff --git a/apps/docs/content/troubleshooting/monitor-supavisor-postgres-connections.mdx b/apps/docs/content/troubleshooting/monitor-supavisor-postgres-connections.mdx index 6b1592a592a..86b51f56db8 100644 --- a/apps/docs/content/troubleshooting/monitor-supavisor-postgres-connections.mdx +++ b/apps/docs/content/troubleshooting/monitor-supavisor-postgres-connections.mdx @@ -19,7 +19,7 @@ _Visual of Grafana Dashboard_ It can be run locally within Docker. Alternatively, you can deploy it to fly.io or Grafana Cloud, which are better for long-term data collection. -Installation instructions can be found in it the [metrics docs ](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) +Installation instructions can be found in it the [metrics docs ](/docs/guides/observability/metrics/grafana-self-hosted) ## Observing connections diff --git a/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx b/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx index f2d72bb059c..393f990ec76 100644 --- a/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx +++ b/apps/docs/content/troubleshooting/pgcron-debugging-guide-n1KTaz.mdx @@ -114,7 +114,7 @@ You can view your concurrent peak connection usage throughout the day at the bot Unfortunately, excessive resource strain can slow down or disrupt jobs. -Go to the [reports page](/dashboard/project/_/observability/database) (or [Supabase Grafana](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) if you have it setup), and check for signs of resource exhaustion. If it's clear your database is under pressure, consider upgrading your compute add-on or following the advice from one of the optimization guides: +Go to the [reports page](/dashboard/project/_/observability/database) (or [Supabase Grafana](/docs/guides/observability/metrics/grafana-self-hosted) if you have it setup), and check for signs of resource exhaustion. If it's clear your database is under pressure, consider upgrading your compute add-on or following the advice from one of the optimization guides: - [Connections](https://github.com/orgs/supabase/discussions/27141) - [Disk/IO](https://github.com/orgs/supabase/discussions/27003) @@ -150,7 +150,7 @@ order by timestamp desc limit 100; ``` -If you're interested in modifying the query, there is an advanced [guide](https://github.com/orgs/supabase/discussions/26224) for navigating the Postgres logs and a general-purpose [one](/docs/guides/monitoring-and-debugging/advanced-log-filtering) for applying filters. +If you're interested in modifying the query, there is an advanced [guide](https://github.com/orgs/supabase/discussions/26224) for navigating the Postgres logs and a general-purpose [one](/docs/guides/observability/advanced-log-filtering) for applying filters.
    diff --git a/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx b/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx index 2abdb07268c..40648fdb38e 100644 --- a/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx +++ b/apps/docs/content/troubleshooting/steps-to-improve-query-performance-with-indexes-q8PoC9.mdx @@ -23,7 +23,7 @@ Supabase has an [open-source Grafana Repo](https://github.com/supabase/supabase- _Visual of Grafana Dashboard_ ![image](/docs/img/troubleshooting/18ed2c88-332e-4e66-b9b4-c37e99a39104.png) -It can be run locally within Docker or can be deployed for free to fly.io. Installation instructions can be found in [Supabase's metrics docs](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) +It can be run locally within Docker or can be deployed for free to fly.io. Installation instructions can be found in [Supabase's metrics docs](/docs/guides/observability/metrics/grafana-self-hosted) ### Query optimization through indexes diff --git a/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx b/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx index 73818a7f195..a70cc475010 100644 --- a/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx +++ b/apps/docs/content/troubleshooting/supabase-grafana-memory-charts.mdx @@ -7,7 +7,7 @@ date_created = "2024-06-05" database_id = "179d70f3-1e26-4346-9ee8-d340fad382a3" --- -> [Supabase Grafana Installation Guide](/docs/guides/monitoring-and-debugging/metrics/grafana-self-hosted) +> [Supabase Grafana Installation Guide](/docs/guides/observability/metrics/grafana-self-hosted) Here are examples of unhealthy memory usage: ![image](https://github.com/supabase/supabase/assets/91111415/baebfc74-642d-4988-992c-bb0f473a05ad) diff --git a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx index 96218a1a82e..f2cef8f49c1 100644 --- a/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx +++ b/apps/docs/content/troubleshooting/supavisor-faq-YyP5tI.mdx @@ -159,7 +159,7 @@ As a rule of thumb, if you're using the DB REST API or multiple app-based "user+ Connection usage can be monitored with a Supabase Grafana Dashboard. It provides realtime visibility of over 200 database metrics, such as graphs of CPU, EBS, and active direct/pooler connections. It can be extremely useful for monitoring and debugging instances. -You can check our [GitHub repo](https://github.com/supabase/supabase-grafana) for setup instructions for local deployments or free cloud deployments on [Fly.io](http://fly.io/). Refer to Supabase [documentation](/docs/guides/monitoring-and-debugging/metrics) to learn more about the metrics endpoint. +You can check our [GitHub repo](https://github.com/supabase/supabase-grafana) for setup instructions for local deployments or free cloud deployments on [Fly.io](http://fly.io/). Refer to Supabase [documentation](/docs/guides/observability/metrics) to learn more about the metrics endpoint. ## **Can Supavisor really support a million connections?** diff --git a/apps/docs/data/ai-prompts.data.ts b/apps/docs/data/ai-prompts.data.ts index d6707390673..66081d5bcb5 100644 --- a/apps/docs/data/ai-prompts.data.ts +++ b/apps/docs/data/ai-prompts.data.ts @@ -1,3 +1,5 @@ +import { setupCommand } from '~/components/HomePageCover.constants' + /** Embedded AI prompt bodies keyed by `AiPrompt` `id`. */ export const aiPrompts = { astrojs: `Help me add Supabase to my Astro project. Create a Supabase project at @@ -265,6 +267,11 @@ database.new and run the instruments table SQL. Then: REFERENCE https://supabase.com/docs/guides/getting-started/quickstarts/vue.md`, + 'monitoring-and-debugging': `Help me monitor and debug my Supabase project. Keep all access read-only. Do the following: +1. Install the Supabase CLI globally with \`${setupCommand.installCli}\`. +2. Install the Supabase Plugin with \`${setupCommand.installPlugin}\`. The plugin includes the Supabase MCP server. +3. Review my project and determine whether Supabase is already initialized. If it is not initialized, run \`${setupCommand.initialize}\`. +4. Read https://supabase.com/docs/guides/observability.md and follow it.`, 'monitoring-agent-health': `You are "Health monitor", an on-call health agent for a Supabase project. Reach the project only through Supabase MCP in read-only mode. @@ -280,7 +287,7 @@ Run once per hour. On each shift: Do not change the project. Be terse. Lead with the suspected cause. REFERENCE -https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/health.md`, +https://supabase.com/docs/guides/observability/detecting.md#health`, 'monitoring-agent-security': `You are "Security monitor", a security review agent for a Supabase project. Reach the project only through Supabase MCP in read-only mode. @@ -295,7 +302,7 @@ Run once per day. On each review: Do not change the project. If nothing needs review, stay silent. REFERENCE -https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/security.md`, +https://supabase.com/docs/guides/observability/detecting.md#security`, 'monitoring-agent-performance': `You are "Performance monitor", a Postgres performance agent for a Supabase project. Reach the project only through Supabase MCP in read-only mode. @@ -310,7 +317,7 @@ Run once per hour. On each check: Do not change the project, create indexes, or cancel sessions. REFERENCE -https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/performance.md`, +https://supabase.com/docs/guides/observability/detecting.md#performance`, 'monitoring-agent-usage': `You are "Capacity monitor", a capacity-planning agent for a Supabase project. Reach the project only through Supabase MCP in read-only mode. @@ -327,7 +334,7 @@ Run once each morning. On each review: Do not change billing, compute, or plan settings. REFERENCE -https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/usage.md`, +https://supabase.com/docs/guides/observability/detecting.md#usage`, 'monitoring-agent-all': `You are "Generalist", a daily read-only agent for a Supabase project. TOOLS AVAILABLE @@ -452,7 +459,7 @@ or improvements beyond fixing what you found. Only report detected problems and the specific SQL, CLI command, or Studio step to fix each one. REFERENCE -https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/all.md`, +https://supabase.com/docs/guides/observability/automate-with-agents/all.md`, } as const export type AiPromptId = keyof typeof aiPrompts diff --git a/apps/docs/data/content-listings/index.ts b/apps/docs/data/content-listings/index.ts index e16bc5717a3..aca30691be8 100644 --- a/apps/docs/data/content-listings/index.ts +++ b/apps/docs/data/content-listings/index.ts @@ -29,10 +29,10 @@ import { import { storageExamples, storageGetStarted, storageResources } from './storage.data' import { telemetryAccessWhat, - telemetryAccessWhere, - telemetryDebugging, + telemetryDetect, + telemetryDiagnose, + telemetryExport, telemetryHireAgent, - telemetryMonitoring, } from './telemetry.data' const ALL_GROUPS: readonly ContentListingGroup[] = [ @@ -67,11 +67,11 @@ const ALL_GROUPS: readonly ContentListingGroup[] = [ storageGetStarted, storageExamples, storageResources, - telemetryDebugging, - telemetryMonitoring, telemetryAccessWhat, - telemetryAccessWhere, + telemetryDetect, + telemetryDiagnose, telemetryHireAgent, + telemetryExport, ] export const CONTENT_LISTINGS: Readonly> = Object.fromEntries( diff --git a/apps/docs/data/content-listings/log-drains.data.ts b/apps/docs/data/content-listings/log-drains.data.ts index d8f4b9f7f0c..6d337dc6eca 100644 --- a/apps/docs/data/content-listings/log-drains.data.ts +++ b/apps/docs/data/content-listings/log-drains.data.ts @@ -9,55 +9,55 @@ export const logDrainsDestinations: ContentListingGroup = { { title: 'Custom Endpoint', description: 'Forward logs as a POST request to any custom HTTP endpoint.', - href: '/guides/monitoring-and-debugging/log-drains#custom-endpoint', + href: '/guides/observability/log-drains#custom-endpoint', icon: { kind: 'braces', color: '#3ECF8E', bg: 'rgba(62,207,142,0.1)' }, }, { title: 'OpenTelemetry (OTLP)', description: 'Send logs to any OTLP-compatible endpoint using Protocol Buffers over HTTP.', - href: '/guides/monitoring-and-debugging/log-drains#opentelemetry-otlp', + href: '/guides/observability/log-drains#opentelemetry-otlp', icon: { kind: 'otlp', color: '#F5A623', bg: 'rgba(245,166,35,0.1)' }, }, { title: 'Datadog', description: 'Stream logs directly into Datadog for monitoring and analysis.', - href: '/guides/monitoring-and-debugging/log-drains#datadog', + href: '/guides/observability/log-drains#datadog', icon: { kind: 'datadog', color: '#632CA6', bg: 'rgba(99,44,166,0.1)' }, }, { title: 'Loki', description: 'Ingest logs into Grafana Loki using the HTTP push API.', - href: '/guides/monitoring-and-debugging/log-drains#loki', + href: '/guides/observability/log-drains#loki', icon: { kind: 'grafana', color: '#F05A28', bg: 'rgba(240,90,40,0.1)' }, }, { title: 'Amazon S3', description: 'Write batched log files directly to an S3 bucket you own.', - href: '/guides/monitoring-and-debugging/log-drains#amazon-s3', + href: '/guides/observability/log-drains#amazon-s3', icon: { kind: 'cloud', color: '#FF9900', bg: 'rgba(255,153,0,0.1)' }, }, { title: 'Sentry', description: "Send logs to Sentry's Logging product for filtering and grouping.", - href: '/guides/monitoring-and-debugging/log-drains#sentry', + href: '/guides/observability/log-drains#sentry', icon: { kind: 'sentry', color: '#362D59', bg: 'rgba(54,45,89,0.1)' }, }, { title: 'Axiom', description: 'Forward logs to an Axiom dataset for storage and analysis.', - href: '/guides/monitoring-and-debugging/log-drains#axiom', + href: '/guides/observability/log-drains#axiom', icon: { kind: 'axiom', color: '#6366F1', bg: 'rgba(99,102,241,0.1)' }, }, { title: 'Last9', description: 'Stream logs to Last9 for OpenTelemetry-native observability.', - href: '/guides/monitoring-and-debugging/log-drains#last9', + href: '/guides/observability/log-drains#last9', icon: { kind: 'last9', color: '#00B4A0', bg: 'rgba(0,180,160,0.1)' }, }, { title: 'Syslog', description: 'Forward logs to a remote Syslog receiver over TCP or TLS (RFC 5424).', - href: '/guides/monitoring-and-debugging/log-drains#syslog', + href: '/guides/observability/log-drains#syslog', icon: { kind: 'server', color: '#64748B', bg: 'rgba(100,116,139,0.1)' }, }, ], diff --git a/apps/docs/data/content-listings/telemetry.data.ts b/apps/docs/data/content-listings/telemetry.data.ts index 54b6cc1ccf1..b901c3ba481 100644 --- a/apps/docs/data/content-listings/telemetry.data.ts +++ b/apps/docs/data/content-listings/telemetry.data.ts @@ -2,141 +2,62 @@ import { monitoringAgents } from '~/data/monitoring-agents.data' import { getScheduleLabel } from '~/data/monitoring-agents.utils' import type { ContentListingGroup } from '~/lib/content-listings.schema' -export const telemetryDebugging: ContentListingGroup = { - id: 'telemetry-debugging', - heading: 'Debugging', - type: 'grid', - columns: 2, - items: [ - { - title: 'Debugging guide', - href: '/guides/monitoring-and-debugging/debugging', - description: - 'Isolate the failing layer, read logs as evidence, and match symptoms to troubleshooting guides.', - }, - { - title: 'Logs', - href: '/guides/monitoring-and-debugging/logs', - description: 'Inspect project log events in the unified Logs view in Studio.', - }, - { - title: 'Query and filter logs', - href: '/guides/monitoring-and-debugging/advanced-log-filtering', - description: 'Run ClickHouse SQL from Studio, MCP, the API, or a script.', - }, - { - title: 'Troubleshooting index', - href: '/guides/troubleshooting', - description: 'Searchable index of known error codes, symptoms, and fixes.', - }, - { - title: 'Diagnosing stuck and blocked queries', - href: '/guides/database/connection-management#diagnosing-stuck-and-blocked-queries', - description: 'Find sessions blocked by a lock, and cancel or terminate the one responsible.', - }, - ], -} - -export const telemetryMonitoring: ContentListingGroup = { - id: 'telemetry-monitoring', - heading: 'Monitoring', - type: 'grid', - columns: 2, - items: [ - { - title: 'Log drains', - href: '/guides/monitoring-and-debugging/log-drains', - description: 'Forward logs to Datadog, Loki, Axiom, S3, or a custom HTTP endpoint.', - }, - { - title: 'Reports', - href: '/guides/monitoring-and-debugging/reports', - description: 'Built-in dashboards for API, Auth, Storage, and Realtime activity.', - }, - { - title: 'Metrics', - href: '/guides/monitoring-and-debugging/metrics', - description: 'Prometheus-compatible database metrics for Grafana and other tools.', - }, - { - title: 'Client-side tracing', - href: '/guides/monitoring-and-debugging/client-side-tracing', - description: 'Correlate browser requests end-to-end using W3C Trace Context.', - }, - { - title: 'Query optimization', - href: '/guides/database/query-optimization', - description: 'Find and fix slow queries using indexes and query plan analysis.', - }, - { - title: 'Sentry integration', - href: '/guides/monitoring-and-debugging/sentry-monitoring', - description: 'Send errors to Sentry for alerting and grouping.', - }, - ], -} - export const telemetryAccessWhat: ContentListingGroup = { id: 'telemetry-access-what', - heading: 'What data you can observe', - headingLevel: 'h3', type: 'grid', columns: 2, items: [ { title: 'Logs', - href: '/guides/monitoring-and-debugging/advanced-log-filtering', + href: '/guides/observability/advanced-log-filtering', description: - 'Query project logs and look up sources and fields. Record extra Postgres, API, and Realtime events.', + 'Query ClickHouse logs from Studio, MCP, or the API. Filter events in the Logs UI.', }, { title: 'Metrics API', - href: '/guides/monitoring-and-debugging/metrics', - description: 'Scrape Prometheus-compatible database metrics for dashboards and alerting.', + href: '/guides/observability/metrics', + description: 'Scrape Prometheus-compatible database metrics, or chart a subset in Reports.', }, { title: 'Database', - href: '/guides/monitoring-and-debugging/inspect', - description: - 'Inspect live Postgres stats such as bloat, cache hit rate, locks, and slow queries.', + href: '/guides/observability/inspect', + description: 'Inspect live Postgres stats from the CLI, the SQL Editor, or MCP.', }, { title: 'Advisors', - href: '/guides/monitoring-and-debugging/advisors', - description: - 'Pull deterministic security and performance findings as part of ongoing observability.', + href: '/guides/observability/advisors', + description: 'Pull security and performance findings from Studio, MCP, the CLI, or the API.', + }, + { + title: 'Reports', + href: '/guides/observability/reports', + description: 'Studio dashboards for API, Auth, Storage, Realtime, and database signals.', }, ], } -export const telemetryAccessWhere: ContentListingGroup = { - id: 'telemetry-access-where', - heading: 'Where you can observe it', - headingLevel: 'h3', +export const telemetryDetect: ContentListingGroup = { + id: 'telemetry-detect', type: 'grid', - columns: 2, items: [ { - title: 'MCP', - href: '/guides/monitoring-and-debugging/access-data#mcp', + title: 'Detect issues', + href: '/guides/observability/detecting', description: - 'Query logs, run read-only SQL, and fetch advisor findings from an agent harness.', + 'Run health, security, performance, and usage checks against logs and database statistics to pick up a signal.', }, + ], +} + +export const telemetryDiagnose: ContentListingGroup = { + id: 'telemetry-diagnose', + type: 'grid', + items: [ { - title: 'API', - href: '/guides/monitoring-and-debugging/access-data#api', - description: 'Read logs, advisors, and usage counts, or scrape the Metrics API.', - }, - { - title: 'CLI', - href: '/guides/monitoring-and-debugging/access-data#cli', + title: 'Diagnose and resolve', + href: '/guides/troubleshooting', description: - 'Inspect the database and run security or performance advisors from the terminal.', - }, - { - title: 'Studio', - href: '/guides/monitoring-and-debugging/access-data#studio', - description: 'Open Logs, Reports, and Advisors in the browser.', + 'Use a concrete finding, symptom, or error code to identify the cause and apply a known solution.', }, ], } @@ -148,34 +69,57 @@ export const telemetryHireAgent: ContentListingGroup = { items: [ { title: 'Generalist', - href: '/guides/monitoring-and-debugging/automate-with-agents/all', + href: '/guides/observability/automate-with-agents/all', subtitle: getScheduleLabel(monitoringAgents.all), description: 'Run all four checks — health, security, performance, and usage — in one daily pass.', }, { title: monitoringAgents.health.name, - href: '/guides/monitoring-and-debugging/automate-with-agents/health', + href: '/guides/observability/automate-with-agents/health', subtitle: getScheduleLabel(monitoringAgents.health), description: 'Watch logs for 5xx spikes and Auth failures.', }, { title: monitoringAgents.security.name, - href: '/guides/monitoring-and-debugging/automate-with-agents/security', + href: '/guides/observability/automate-with-agents/security', subtitle: getScheduleLabel(monitoringAgents.security), description: 'Review advisor findings and authorization failures.', }, { title: monitoringAgents.performance.name, - href: '/guides/monitoring-and-debugging/automate-with-agents/performance', + href: '/guides/observability/automate-with-agents/performance', subtitle: getScheduleLabel(monitoringAgents.performance), description: 'Find slow queries, lock waits, and missing indexes.', }, { title: monitoringAgents.usage.name, - href: '/guides/monitoring-and-debugging/automate-with-agents/usage', + href: '/guides/observability/automate-with-agents/usage', subtitle: getScheduleLabel(monitoringAgents.usage), description: 'Track request growth, error rates, and approaching limits.', }, ], } + +export const telemetryExport: ContentListingGroup = { + id: 'telemetry-export', + type: 'grid', + columns: 3, + items: [ + { + title: 'Log drains', + href: '/guides/observability/log-drains', + description: 'Send project logs to your own destination.', + }, + { + title: 'Client-side tracing', + href: '/guides/observability/client-side-tracing', + description: 'Propagate W3C trace context from the client through Supabase services.', + }, + { + title: 'Sentry integration', + href: '/guides/observability/sentry-monitoring', + description: 'Capture supabase-js errors and spans in Sentry.', + }, + ], +} diff --git a/apps/docs/features/docs/GuidesMdx.utils.tsx b/apps/docs/features/docs/GuidesMdx.utils.tsx index ab1d34c6494..0212f9886a9 100644 --- a/apps/docs/features/docs/GuidesMdx.utils.tsx +++ b/apps/docs/features/docs/GuidesMdx.utils.tsx @@ -34,7 +34,7 @@ const PUBLISHED_SECTIONS = [ 'graphql', 'integrations', 'local-development', - 'monitoring-and-debugging', + 'observability', 'platform', 'queues', 'realtime', diff --git a/apps/docs/internals/markdown-schema/AiPrompt.test.ts b/apps/docs/internals/markdown-schema/AiPrompt.test.ts index 4b6920d94d1..528b9a5523d 100644 --- a/apps/docs/internals/markdown-schema/AiPrompt.test.ts +++ b/apps/docs/internals/markdown-schema/AiPrompt.test.ts @@ -18,16 +18,32 @@ describe('AiPrompt markdown schema', () => { }) it.each([ - ['monitoring-agent-health', 'Health monitor'], - ['monitoring-agent-security', 'Security monitor'], - ['monitoring-agent-performance', 'Performance monitor'], - ['monitoring-agent-usage', 'Capacity monitor'], - ])('serializes the %s agent prompt', (id, persona) => { + ['monitoring-agent-health', 'Health monitor', 'health'], + ['monitoring-agent-security', 'Security monitor', 'security'], + ['monitoring-agent-performance', 'Performance monitor', 'performance'], + ['monitoring-agent-usage', 'Capacity monitor', 'usage'], + ])('serializes the %s agent prompt', (id, persona, detectionSection) => { const markdown = AiPrompt({ props: { id, includeInMarkdown: true } }) expect(markdown).toContain('**AI Prompt**') expect(markdown).toContain(persona) expect(markdown).toContain('read-only') + expect(markdown).toContain( + `https://supabase.com/docs/guides/observability/detecting.md#${detectionSection}` + ) + expect(markdown).toContain('```text') + }) + + it('serializes the monitoring overview prompt', () => { + const markdown = AiPrompt({ + props: { id: 'monitoring-and-debugging', includeInMarkdown: true }, + }) + + expect(markdown).toContain('Help me monitor and debug my Supabase project.') + expect(markdown).toContain('npm install -g supabase') + expect(markdown).toContain('npx plugins add supabase-community/supabase-plugin') + expect(markdown).toContain('read-only') + expect(markdown).toContain('https://supabase.com/docs/guides/observability.md') expect(markdown).toContain('```text') }) diff --git a/apps/docs/layouts/MainSkeleton.tsx b/apps/docs/layouts/MainSkeleton.tsx index baedba068c6..25ac4a58199 100644 --- a/apps/docs/layouts/MainSkeleton.tsx +++ b/apps/docs/layouts/MainSkeleton.tsx @@ -59,7 +59,7 @@ const levelsData = { }, telemetry: { icon: 'telemetry', - name: 'Telemetry', + name: 'Observability', }, realtime: { icon: 'realtime', diff --git a/apps/docs/lib/breadcrumbs.test.ts b/apps/docs/lib/breadcrumbs.test.ts new file mode 100644 index 00000000000..14c77a48eaf --- /dev/null +++ b/apps/docs/lib/breadcrumbs.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'vitest' + +import { resolveBreadcrumbs } from './breadcrumbs' + +describe('resolveBreadcrumbs', () => { + it('places troubleshooting under detect and diagnose', () => { + expect(resolveBreadcrumbs('/guides/troubleshooting')).toEqual([ + { + name: 'Observability', + url: '/guides/observability', + }, + { name: 'Detect and diagnose' }, + { name: 'Diagnosing', url: '/guides/troubleshooting' }, + ]) + }) +}) diff --git a/apps/docs/lib/breadcrumbs.ts b/apps/docs/lib/breadcrumbs.ts index ac6643c80b5..a89f74e8c59 100644 --- a/apps/docs/lib/breadcrumbs.ts +++ b/apps/docs/lib/breadcrumbs.ts @@ -26,7 +26,7 @@ const SECTION_PATH_TO_KEY: Record = { security: 'security', 'self-hosting': 'self_hosting', storage: 'storage', - 'monitoring-and-debugging': 'telemetry', + observability: 'telemetry', } function getSectionMenu(pathname: string) { @@ -55,7 +55,14 @@ function findMenuItemByUrl( export function resolveBreadcrumbs(pathname: string): BreadcrumbItem[] { if (pathname.startsWith('/guides/troubleshooting')) { - return [{ name: 'Troubleshooting', url: '/guides/troubleshooting' }] + return [ + { + name: 'Observability', + url: '/guides/observability', + }, + { name: 'Detect and diagnose' }, + { name: 'Diagnosing', url: '/guides/troubleshooting' }, + ] } if (pathname.startsWith('/guides/getting-started/ai-prompts')) { return [ diff --git a/apps/docs/lib/content-listings.test.ts b/apps/docs/lib/content-listings.test.ts index 8de6892441a..71f0de5c6f6 100644 --- a/apps/docs/lib/content-listings.test.ts +++ b/apps/docs/lib/content-listings.test.ts @@ -69,7 +69,7 @@ describe('serializeContentListingGroupToMarkdown', () => { items: [ { title: 'Health monitor', - href: '/guides/monitoring-and-debugging/automate-with-agents/health', + href: '/guides/observability/automate-with-agents/health', subtitle: 'Every 15 minutes', description: 'Watch logs for 5xx spikes and Auth failures.', }, @@ -79,7 +79,7 @@ describe('serializeContentListingGroupToMarkdown', () => { ) expect(markdown).toContain( - '**[Health monitor](https://supabase.com/docs/guides/monitoring-and-debugging/automate-with-agents/health):** Every 15 minutes. Watch logs for 5xx spikes and Auth failures.' + '**[Health monitor](https://supabase.com/docs/guides/observability/automate-with-agents/health):** Every 15 minutes. Watch logs for 5xx spikes and Auth failures.' ) }) @@ -278,7 +278,7 @@ describe('dashboard content listing hrefs', () => { describe('contentListingItemSchema icon', () => { const baseItem = { title: 'Datadog', - href: '/guides/monitoring-and-debugging/log-drains#datadog', + href: '/guides/observability/log-drains#datadog', description: 'Stream logs directly into Datadog for monitoring and analysis.', } diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index d7969587e0c..edafab3c420 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -194,7 +194,7 @@ const nextConfig = { }, { source: '/guides/database/database-advisors', - destination: '/guides/monitoring-and-debugging/advisors', + destination: '/guides/observability/advisors', permanent: true, }, ] diff --git a/apps/docs/scripts/search/sources/index.ts b/apps/docs/scripts/search/sources/index.ts index c513e9b2d44..ed67571899a 100644 --- a/apps/docs/scripts/search/sources/index.ts +++ b/apps/docs/scripts/search/sources/index.ts @@ -140,7 +140,7 @@ export async function fetchCliLibReferenceSource() { export async function fetchLintWarningsGuideSources() { return new LintWarningsGuideLoader( 'guide', - '/guides/monitoring-and-debugging/advisors', + '/guides/observability/advisors', 'supabase', 'splinter', 'main', diff --git a/apps/studio/components/interfaces/Linter/LintDetail.tsx b/apps/studio/components/interfaces/Linter/LintDetail.tsx index 4c55e559be0..e36ccce30ab 100644 --- a/apps/studio/components/interfaces/Linter/LintDetail.tsx +++ b/apps/studio/components/interfaces/Linter/LintDetail.tsx @@ -95,7 +95,7 @@ export const LintDetail = ({ item.name === lint.name)?.docsLink || - `${DOCS_URL}/guides/database/database-linter` + `${DOCS_URL}/guides/observability/advisors` } target="_blank" rel="noreferrer" diff --git a/apps/studio/components/interfaces/Linter/Linter.utils.tsx b/apps/studio/components/interfaces/Linter/Linter.utils.tsx index 3f53b689b62..0796fb3fadd 100644 --- a/apps/studio/components/interfaces/Linter/Linter.utils.tsx +++ b/apps/studio/components/interfaces/Linter/Linter.utils.tsx @@ -33,7 +33,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/indexes?schema=${encodeURIComponent(metadata?.schema ?? '')}`, linkText: 'Create an index', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0001_unindexed_foreign_keys`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0001_unindexed_foreign_keys`, category: 'performance', }, { @@ -42,7 +42,7 @@ export const lintInfoMap: LintInfo[] = [ icon: , link: ({ projectRef }) => `/project/${projectRef}/editor`, linkText: 'View table', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0002_auth_users_exposed`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0002_auth_users_exposed`, category: 'security', }, { @@ -51,7 +51,7 @@ export const lintInfoMap: LintInfo[] = [ icon: , link: ({ projectRef }) => `/project/${projectRef}/database/policies`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0003_auth_rls_initplan`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0003_auth_rls_initplan`, category: 'performance', }, { @@ -60,7 +60,7 @@ export const lintInfoMap: LintInfo[] = [ icon: , link: ({ projectRef }) => `/project/${projectRef}/editor`, linkText: 'View table', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0004_no_primary_key`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0004_no_primary_key`, category: 'performance', }, { @@ -70,7 +70,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/indexes?schema=${encodeURIComponent(metadata?.schema ?? '')}&table=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View index', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0005_unused_index`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0005_unused_index`, category: 'performance', }, { @@ -80,7 +80,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/policies?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0006_multiple_permissive_policies`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0006_multiple_permissive_policies`, category: 'performance', }, { @@ -90,7 +90,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/policies?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0007_policy_exists_rls_disabled`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0007_policy_exists_rls_disabled`, category: 'security', }, { @@ -100,7 +100,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/policies?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View table', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0008_rls_enabled_no_policy`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0008_rls_enabled_no_policy`, category: 'security', }, { @@ -110,7 +110,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/indexes?schema=${encodeURIComponent(metadata?.schema ?? '')}&table=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View index', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0009_duplicate_index`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0009_duplicate_index`, category: 'performance', }, { @@ -118,9 +118,9 @@ export const lintInfoMap: LintInfo[] = [ title: 'Security Definer View', icon: , link: () => - `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0010_security_definer_view`, + `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0010_security_definer_view`, linkText: 'View docs', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0010_security_definer_view`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0010_security_definer_view`, category: 'security', }, { @@ -130,7 +130,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/functions?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View functions', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0011_function_search_path_mutable`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0011_function_search_path_mutable`, category: 'security', }, { @@ -139,7 +139,7 @@ export const lintInfoMap: LintInfo[] = [ icon: , link: ({ projectRef }) => `/project/${projectRef}/auth/providers`, linkText: 'View settings', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0012_auth_allow_anonymous_sign_ins`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0012_auth_allow_anonymous_sign_ins`, category: 'security', }, { @@ -149,7 +149,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/policies?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0013_rls_disabled_in_public`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0013_rls_disabled_in_public`, category: 'security', }, { @@ -159,7 +159,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/extensions?filter=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View extension', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0014_extension_in_public`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0014_extension_in_public`, category: 'security', }, { @@ -195,26 +195,25 @@ export const lintInfoMap: LintInfo[] = [ icon: , link: ({ projectRef }) => `/project/${projectRef}/database/policies`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?queryGroups=lint&lint=0015_rls_references_user_metadata`, + docsLink: `${DOCS_URL}/guides/observability/advisors?queryGroups=lint&lint=0015_rls_references_user_metadata`, category: 'security', }, { name: 'materialized_view_in_api', title: 'Materialized View in API', icon: , - link: () => - `${DOCS_URL}/guides/monitoring-and-debugging/advisors?lint=0016_materialized_view_in_api`, + link: () => `${DOCS_URL}/guides/observability/advisors?lint=0016_materialized_view_in_api`, linkText: 'View docs', - docsLink: `${DOCS_URL}/guides/monitoring-and-debugging/advisors?lint=0016_materialized_view_in_api`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0016_materialized_view_in_api`, category: 'security', }, { name: 'foreign_table_in_api', title: 'Foreign Table in API', icon: , - link: () => `${DOCS_URL}/guides/database/database-linter?lint=0017_foreign_table_in_api`, + link: () => `${DOCS_URL}/guides/observability/advisors?lint=0017_foreign_table_in_api`, linkText: 'View docs', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0017_foreign_table_in_api`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0017_foreign_table_in_api`, category: 'security', }, { @@ -222,9 +221,9 @@ export const lintInfoMap: LintInfo[] = [ title: 'Unsupported reg types', icon: , link: () => - `${DOCS_URL}/guides/monitoring-and-debugging/advisors?lint=0018_unsupported_reg_types&queryGroups=lint`, + `${DOCS_URL}/guides/observability/advisors?lint=0018_unsupported_reg_types&queryGroups=lint`, linkText: 'View docs', - docsLink: `${DOCS_URL}/guides/monitoring-and-debugging/advisors?lint=0018_unsupported_reg_types&queryGroups=lint`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0018_unsupported_reg_types&queryGroups=lint`, category: 'security', }, { @@ -334,7 +333,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/editor?schema=${encodeURIComponent(metadata?.schema ?? '')}&table=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View table', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0023_sensitive_columns_exposed`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0023_sensitive_columns_exposed`, category: 'security', }, { @@ -344,7 +343,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/policies?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View policies', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0024_permissive_rls_policy`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0024_permissive_rls_policy`, category: 'security', }, { @@ -356,7 +355,7 @@ export const lintInfoMap: LintInfo[] = [ return `/project/${projectRef}/storage/files/buckets/${encodeURIComponent(bucketId ?? metadata?.name ?? '')}` }, linkText: 'View bucket', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0025_public_bucket_allows_listing`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0025_public_bucket_allows_listing`, category: 'security', }, { @@ -366,7 +365,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/editor?schema=${encodeURIComponent(metadata?.schema ?? '')}&table=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View object', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0026_pg_graphql_anon_table_exposed`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0026_pg_graphql_anon_table_exposed`, category: 'security', }, { @@ -376,7 +375,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/editor?schema=${encodeURIComponent(metadata?.schema ?? '')}&table=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View object', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0027_pg_graphql_authenticated_table_exposed`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0027_pg_graphql_authenticated_table_exposed`, category: 'security', }, { @@ -386,7 +385,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/functions?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View function', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0028_anon_security_definer_function_executable`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0028_anon_security_definer_function_executable`, category: 'security', }, { @@ -396,7 +395,7 @@ export const lintInfoMap: LintInfo[] = [ link: ({ projectRef, metadata }) => `/project/${projectRef}/database/functions?schema=${encodeURIComponent(metadata?.schema ?? '')}&search=${encodeURIComponent(metadata?.name ?? '')}`, linkText: 'View function', - docsLink: `${DOCS_URL}/guides/database/database-linter?lint=0029_authenticated_security_definer_function_executable`, + docsLink: `${DOCS_URL}/guides/observability/advisors?lint=0029_authenticated_security_definer_function_executable`, category: 'security', }, // Health lints report on the running project rather than on schema, so they link to the diff --git a/apps/studio/components/interfaces/Linter/LinterPageFooter.tsx b/apps/studio/components/interfaces/Linter/LinterPageFooter.tsx index b00f3feeeae..fdeead296c4 100644 --- a/apps/studio/components/interfaces/Linter/LinterPageFooter.tsx +++ b/apps/studio/components/interfaces/Linter/LinterPageFooter.tsx @@ -87,7 +87,7 @@ export const LinterPageFooter = ({ )} diff --git a/apps/studio/components/interfaces/QueryPerformance/WithStatements/WithStatements.tsx b/apps/studio/components/interfaces/QueryPerformance/WithStatements/WithStatements.tsx index 44713b8fa09..e843a0a5eee 100644 --- a/apps/studio/components/interfaces/QueryPerformance/WithStatements/WithStatements.tsx +++ b/apps/studio/components/interfaces/QueryPerformance/WithStatements/WithStatements.tsx @@ -297,7 +297,7 @@ export const WithStatements = ({ diff --git a/apps/studio/components/interfaces/Settings/API/UnsafeEntitiesConfirmModal.tsx b/apps/studio/components/interfaces/Settings/API/UnsafeEntitiesConfirmModal.tsx index 5a4edd6da23..7fad3486f1a 100644 --- a/apps/studio/components/interfaces/Settings/API/UnsafeEntitiesConfirmModal.tsx +++ b/apps/studio/components/interfaces/Settings/API/UnsafeEntitiesConfirmModal.tsx @@ -21,28 +21,28 @@ const ENTITY_TYPE_META: Record< heading: 'Tables without Row Level Security', recommendation: 'Enable RLS on these tables to control access per-row.', docsUrl: - 'https://supabase.com/docs/guides/database/database-linter?lint=0013_rls_disabled_in_public', + 'https://supabase.com/docs/guides/observability/advisors?lint=0013_rls_disabled_in_public', }, 'foreign table': { heading: 'Foreign tables', recommendation: 'Foreign tables do not support RLS. Revoke access from the anon and authenticated roles.', docsUrl: - 'https://supabase.com/docs/guides/database/database-linter?lint=0017_foreign_table_in_api', + 'https://supabase.com/docs/guides/observability/advisors?lint=0017_foreign_table_in_api', }, 'materialized view': { heading: 'Materialized views', recommendation: 'Materialized views do not support RLS. Revoke access from the anon and authenticated roles.', docsUrl: - 'https://supabase.com/docs/guides/database/database-linter?lint=0016_materialized_view_in_api', + 'https://supabase.com/docs/guides/observability/advisors?lint=0016_materialized_view_in_api', }, view: { heading: 'Views without SECURITY INVOKER', recommendation: 'These views run with the permissions of the view creator, not the querying user. Set SECURITY INVOKER to enforce caller permissions.', docsUrl: - 'https://supabase.com/docs/guides/database/database-linter?lint=0010_security_definer_view', + 'https://supabase.com/docs/guides/observability/advisors?lint=0010_security_definer_view', }, } diff --git a/apps/studio/lib/ai/prompts.ts b/apps/studio/lib/ai/prompts.ts index d0a9991fc12..ec5c2771305 100644 --- a/apps/studio/lib/ai/prompts.ts +++ b/apps/studio/lib/ai/prompts.ts @@ -371,11 +371,11 @@ export const PG_BEST_PRACTICES = ` - After creating a table, check and configure Data API access and RLS before use (see the "Exposing a Table to the Data API" section in RLS knowledge for the full workflow). - Define foreign key references within the \`CREATE TABLE\` statement. - Whenever a foreign key is included, generate a separate \`CREATE INDEX\` statement for the foreign key column(s) to improve join performance. -- **Foreign Tables:** Place foreign tables in a schema named \`private\` (create the schema if needed). Explain the security risk (RLS bypass) and include a link: https://supabase.com/docs/guides/monitoring-and-debugging/advisors?queryGroups=lint&lint=0017_foreign_table_in_api. +- **Foreign Tables:** Place foreign tables in a schema named \`private\` (create the schema if needed). Explain the security risk (RLS bypass) and include a link: https://supabase.com/docs/guides/observability/advisors?queryGroups=lint&lint=0017_foreign_table_in_api. ### Views - Add \`with (security_invoker=on)\` immediately after \`CREATE VIEW view_name\`. -- **Materialized Views:** Store materialized views in the \`private\` schema (create if needed). Explain the security risk (RLS bypass) and reference: https://supabase.com/docs/guides/monitoring-and-debugging/advisors?queryGroups=lint&lint=0016_materialized_view_in_api. +- **Materialized Views:** Store materialized views in the \`private\` schema (create if needed). Explain the security risk (RLS bypass) and reference: https://supabase.com/docs/guides/observability/advisors?queryGroups=lint&lint=0016_materialized_view_in_api. ### Extensions - Always install extensions in the \`extensions\` schema or a dedicated schema; never in \`public\`. diff --git a/apps/studio/lib/ai/tools/mock-tools.ts b/apps/studio/lib/ai/tools/mock-tools.ts index e8ef8c97b18..4ab6899066c 100644 --- a/apps/studio/lib/ai/tools/mock-tools.ts +++ b/apps/studio/lib/ai/tools/mock-tools.ts @@ -92,7 +92,7 @@ const MOCK_ADVISORIES_DATA = [ category: 'security', message: 'Materialized views in API schema can bypass RLS. Move them to private schema.', remediationUrl: - 'https://supabase.com/docs/guides/monitoring-and-debugging/advisors?queryGroups=lint&lint=0016_materialized_view_in_api', + 'https://supabase.com/docs/guides/observability/advisors?queryGroups=lint&lint=0016_materialized_view_in_api', }, { id: '0031_functions_no_rls_guard', @@ -100,7 +100,7 @@ const MOCK_ADVISORIES_DATA = [ category: 'security', message: 'Function api.health_check should verify auth context before querying tables.', remediationUrl: - 'https://supabase.com/docs/guides/monitoring-and-debugging/advisors?queryGroups=lint&lint=0031_functions_no_rls_guard', + 'https://supabase.com/docs/guides/observability/advisors?queryGroups=lint&lint=0031_functions_no_rls_guard', }, { id: '1012_slow_query', diff --git a/apps/studio/pages/project/[ref]/advisors/performance.tsx b/apps/studio/pages/project/[ref]/advisors/performance.tsx index 27b3d915448..8b589bae1bf 100644 --- a/apps/studio/pages/project/[ref]/advisors/performance.tsx +++ b/apps/studio/pages/project/[ref]/advisors/performance.tsx @@ -73,7 +73,7 @@ const ProjectLints: NextPageWithLayout = () => { { { test('advisors page renders (full content or graceful fallback, never a crash)', async ({ page, }) => { - const response = await page.goto('/docs/guides/monitoring-and-debugging/advisors') + const response = await page.goto('/docs/guides/observability/advisors') expect(response?.ok(), `expected 200, got ${response?.status()}`).toBeTruthy() await expect(page.getByRole('heading', { name: 'Advisors' })).toBeVisible()