@intentsolutionsio/supabase-pack 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +73 -47
- package/package.json +4 -4
- package/skills/supabase-advanced-troubleshooting/SKILL.md +404 -200
- package/skills/supabase-advanced-troubleshooting/references/errors.md +11 -0
- package/skills/supabase-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
- package/skills/supabase-advanced-troubleshooting/references/examples.md +11 -0
- package/skills/supabase-advanced-troubleshooting/references/rls-edge-functions-realtime.md +363 -0
- package/skills/supabase-advanced-troubleshooting/references/systematic-isolation.md +56 -0
- package/skills/supabase-advanced-troubleshooting/references/timing-analysis.md +35 -0
- package/skills/supabase-architecture-variants/SKILL.md +395 -216
- package/skills/supabase-architecture-variants/references/errors.md +11 -0
- package/skills/supabase-architecture-variants/references/examples.md +12 -0
- package/skills/supabase-architecture-variants/references/serverless-and-multi-tenant.md +251 -0
- package/skills/supabase-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
- package/skills/supabase-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
- package/skills/supabase-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
- package/skills/supabase-auth-storage-realtime-core/SKILL.md +471 -37
- package/skills/supabase-ci-integration/SKILL.md +315 -67
- package/skills/supabase-ci-integration/references/errors.md +10 -0
- package/skills/supabase-ci-integration/references/examples.md +36 -0
- package/skills/supabase-ci-integration/references/implementation.md +54 -0
- package/skills/supabase-common-errors/SKILL.md +320 -62
- package/skills/supabase-common-errors/references/errors.md +53 -0
- package/skills/supabase-common-errors/references/examples.md +23 -0
- package/skills/supabase-cost-tuning/SKILL.md +365 -131
- package/skills/supabase-cost-tuning/references/cost-estimation.md +34 -0
- package/skills/supabase-cost-tuning/references/cost-reduction-strategies.md +40 -0
- package/skills/supabase-cost-tuning/references/errors.md +11 -0
- package/skills/supabase-cost-tuning/references/examples.md +15 -0
- package/skills/supabase-data-handling/SKILL.md +378 -145
- package/skills/supabase-data-handling/references/errors.md +11 -0
- package/skills/supabase-data-handling/references/examples.md +27 -0
- package/skills/supabase-data-handling/references/implementation.md +223 -0
- package/skills/supabase-data-handling/references/retention-and-backup.md +221 -0
- package/skills/supabase-debug-bundle/SKILL.md +267 -73
- package/skills/supabase-debug-bundle/references/errors.md +12 -0
- package/skills/supabase-debug-bundle/references/examples.md +24 -0
- package/skills/supabase-debug-bundle/references/implementation.md +54 -0
- package/skills/supabase-deploy-integration/SKILL.md +258 -147
- package/skills/supabase-deploy-integration/references/errors.md +11 -0
- package/skills/supabase-deploy-integration/references/examples.md +21 -0
- package/skills/supabase-deploy-integration/references/google-cloud-run.md +36 -0
- package/skills/supabase-deploy-integration/references/vercel-deployment.md +35 -0
- package/skills/supabase-enterprise-rbac/SKILL.md +327 -160
- package/skills/supabase-enterprise-rbac/references/api-scoping-and-enforcement.md +255 -0
- package/skills/supabase-enterprise-rbac/references/errors.md +11 -0
- package/skills/supabase-enterprise-rbac/references/examples.md +12 -0
- package/skills/supabase-enterprise-rbac/references/role-implementation.md +33 -0
- package/skills/supabase-enterprise-rbac/references/sso-integration.md +35 -0
- package/skills/supabase-hello-world/SKILL.md +160 -54
- package/skills/supabase-incident-runbook/SKILL.md +453 -131
- package/skills/supabase-incident-runbook/references/errors.md +11 -0
- package/skills/supabase-incident-runbook/references/examples.md +10 -0
- package/skills/supabase-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
- package/skills/supabase-install-auth/SKILL.md +186 -50
- package/skills/supabase-install-auth/references/examples.md +102 -0
- package/skills/supabase-known-pitfalls/SKILL.md +411 -241
- package/skills/supabase-known-pitfalls/references/errors.md +11 -0
- package/skills/supabase-known-pitfalls/references/examples.md +12 -0
- package/skills/supabase-load-scale/SKILL.md +346 -217
- package/skills/supabase-load-scale/references/capacity-planning.md +47 -0
- package/skills/supabase-load-scale/references/errors.md +11 -0
- package/skills/supabase-load-scale/references/examples.md +26 -0
- package/skills/supabase-load-scale/references/load-testing-with-k6.md +59 -0
- package/skills/supabase-load-scale/references/scaling-patterns.md +65 -0
- package/skills/supabase-load-scale/references/table-partitioning.md +263 -0
- package/skills/supabase-local-dev-loop/SKILL.md +272 -73
- package/skills/supabase-local-dev-loop/references/errors.md +11 -0
- package/skills/supabase-local-dev-loop/references/examples.md +21 -0
- package/skills/supabase-local-dev-loop/references/implementation.md +60 -0
- package/skills/supabase-migration-deep-dive/SKILL.md +338 -177
- package/skills/supabase-migration-deep-dive/references/backfill-versioning-rollback.md +258 -0
- package/skills/supabase-migration-deep-dive/references/errors.md +11 -0
- package/skills/supabase-migration-deep-dive/references/examples.md +12 -0
- package/skills/supabase-migration-deep-dive/references/implementation-plan.md +80 -0
- package/skills/supabase-migration-deep-dive/references/pre-migration-assessment.md +39 -0
- package/skills/supabase-multi-env-setup/SKILL.md +393 -152
- package/skills/supabase-multi-env-setup/references/configuration-structure.md +59 -0
- package/skills/supabase-multi-env-setup/references/errors.md +11 -0
- package/skills/supabase-multi-env-setup/references/examples.md +11 -0
- package/skills/supabase-observability/SKILL.md +318 -196
- package/skills/supabase-observability/references/alert-configuration.md +40 -0
- package/skills/supabase-observability/references/errors.md +11 -0
- package/skills/supabase-observability/references/examples.md +13 -0
- package/skills/supabase-observability/references/metrics-collection.md +65 -0
- package/skills/supabase-performance-tuning/SKILL.md +304 -160
- package/skills/supabase-performance-tuning/references/caching-strategy.md +49 -0
- package/skills/supabase-performance-tuning/references/errors.md +11 -0
- package/skills/supabase-performance-tuning/references/examples.md +13 -0
- package/skills/supabase-policy-guardrails/SKILL.md +248 -221
- package/skills/supabase-policy-guardrails/references/ci-cost-security.md +484 -0
- package/skills/supabase-policy-guardrails/references/errors.md +11 -0
- package/skills/supabase-policy-guardrails/references/eslint-rules.md +46 -0
- package/skills/supabase-policy-guardrails/references/examples.md +10 -0
- package/skills/supabase-prod-checklist/SKILL.md +474 -84
- package/skills/supabase-prod-checklist/references/errors.md +63 -0
- package/skills/supabase-prod-checklist/references/examples.md +153 -0
- package/skills/supabase-prod-checklist/references/implementation.md +113 -0
- package/skills/supabase-rate-limits/SKILL.md +311 -98
- package/skills/supabase-rate-limits/references/errors.md +11 -0
- package/skills/supabase-rate-limits/references/examples.md +46 -0
- package/skills/supabase-rate-limits/references/implementation.md +66 -0
- package/skills/supabase-reference-architecture/SKILL.md +249 -182
- package/skills/supabase-reference-architecture/references/errors.md +29 -0
- package/skills/supabase-reference-architecture/references/examples.md +116 -0
- package/skills/supabase-reference-architecture/references/key-components.md +244 -0
- package/skills/supabase-reference-architecture/references/project-structure.md +109 -0
- package/skills/supabase-reliability-patterns/SKILL.md +229 -234
- package/skills/supabase-reliability-patterns/references/circuit-breaker.md +36 -0
- package/skills/supabase-reliability-patterns/references/dead-letter-queue.md +48 -0
- package/skills/supabase-reliability-patterns/references/errors.md +11 -0
- package/skills/supabase-reliability-patterns/references/examples.md +11 -0
- package/skills/supabase-reliability-patterns/references/idempotency-keys.md +36 -0
- package/skills/supabase-reliability-patterns/references/offline-degradation-health-dualwrite.md +489 -0
- package/skills/supabase-schema-from-requirements/SKILL.md +373 -34
- package/skills/supabase-sdk-patterns/SKILL.md +388 -99
- package/skills/supabase-sdk-patterns/references/errors.md +11 -0
- package/skills/supabase-sdk-patterns/references/examples.md +45 -0
- package/skills/supabase-sdk-patterns/references/implementation.md +67 -0
- package/skills/supabase-security-basics/SKILL.md +282 -102
- package/skills/supabase-security-basics/references/errors.md +10 -0
- package/skills/supabase-security-basics/references/examples.md +70 -0
- package/skills/supabase-security-basics/references/implementation.md +39 -0
- package/skills/supabase-upgrade-migration/SKILL.md +248 -66
- package/skills/supabase-upgrade-migration/references/errors.md +10 -0
- package/skills/supabase-upgrade-migration/references/examples.md +51 -0
- package/skills/supabase-upgrade-migration/references/implementation.md +29 -0
- package/skills/supabase-webhooks-events/SKILL.md +412 -138
- package/skills/supabase-webhooks-events/references/errors.md +55 -0
- package/skills/supabase-webhooks-events/references/event-handler-pattern.md +106 -0
- package/skills/supabase-webhooks-events/references/examples.md +133 -0
- package/skills/supabase-webhooks-events/references/signature-verification.md +165 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
| Issue | Cause | Solution |
|
|
4
|
+
|-------|-------|----------|
|
|
5
|
+
| Wrong environment | Missing NODE_ENV | Set environment variable |
|
|
6
|
+
| Secret not found | Wrong secret path | Verify secret manager config |
|
|
7
|
+
| Config merge fails | Invalid JSON | Validate config files |
|
|
8
|
+
| Production guard triggered | Wrong environment | Check NODE_ENV value |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Examples
|
|
2
|
+
|
|
3
|
+
### Quick Environment Check
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const env = getSupabaseConfig();
|
|
7
|
+
console.log(`Running in ${env.environment} with ${env.baseUrl}`);
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -1,250 +1,372 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-observability
|
|
3
|
-
description:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
description: 'Set up monitoring and observability for Supabase projects using Dashboard
|
|
4
|
+
|
|
5
|
+
reports, CLI inspect commands, pg_stat_statements, log drains, and alerting.
|
|
6
|
+
|
|
7
|
+
Use when implementing monitoring, diagnosing slow queries, forwarding logs,
|
|
8
|
+
|
|
9
|
+
or configuring alerts for Supabase project health.
|
|
10
|
+
|
|
7
11
|
Trigger with phrases like "supabase monitoring", "supabase metrics",
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
"supabase observability", "supabase logs", "supabase alerts",
|
|
14
|
+
|
|
15
|
+
"supabase inspect", "supabase log drain".
|
|
16
|
+
|
|
17
|
+
'
|
|
18
|
+
allowed-tools: Read, Write, Edit, Bash(npx supabase:*), Bash(supabase:*), Grep
|
|
10
19
|
version: 1.0.0
|
|
11
20
|
license: MIT
|
|
12
21
|
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
22
|
+
tags:
|
|
23
|
+
- saas
|
|
24
|
+
- supabase
|
|
25
|
+
- monitoring
|
|
26
|
+
- observability
|
|
27
|
+
compatibility: Designed for Claude Code
|
|
13
28
|
---
|
|
14
|
-
|
|
15
29
|
# Supabase Observability
|
|
16
30
|
|
|
17
31
|
## Overview
|
|
18
|
-
|
|
32
|
+
|
|
33
|
+
Monitor Supabase projects end-to-end: Dashboard reports for API/database/auth metrics, `supabase inspect db` CLI for deep Postgres diagnostics, `pg_stat_statements` for query analytics, log drains for external aggregation, Edge Functions for custom metrics, and alerting on quota thresholds.
|
|
19
34
|
|
|
20
35
|
## Prerequisites
|
|
21
|
-
- Prometheus or compatible metrics backend
|
|
22
|
-
- OpenTelemetry SDK installed
|
|
23
|
-
- Grafana or similar dashboarding tool
|
|
24
|
-
- AlertManager configured
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
- Supabase CLI installed (`npx supabase --version`)
|
|
38
|
+
- Supabase project linked (`supabase link --project-ref <ref>`)
|
|
39
|
+
- Pro plan or higher for log drain support and extended log retention
|
|
40
|
+
- `@supabase/supabase-js` v2+ installed for application-level monitoring
|
|
27
41
|
|
|
28
|
-
|
|
29
|
-
| Metric | Type | Description |
|
|
30
|
-
|--------|------|-------------|
|
|
31
|
-
| `supabase_requests_total` | Counter | Total API requests |
|
|
32
|
-
| `supabase_request_duration_seconds` | Histogram | Request latency |
|
|
33
|
-
| `supabase_errors_total` | Counter | Error count by type |
|
|
34
|
-
| `supabase_rate_limit_remaining` | Gauge | Rate limit headroom |
|
|
42
|
+
## Instructions
|
|
35
43
|
|
|
36
|
-
###
|
|
44
|
+
### Step 1: Dashboard Reports and CLI Inspect Commands
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
|
|
46
|
+
Supabase Dashboard provides built-in reports under **Dashboard > Reports**:
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
| Report | What It Shows |
|
|
49
|
+
|--------|---------------|
|
|
50
|
+
| API Requests | Total requests, response times, error rates by endpoint |
|
|
51
|
+
| Database | Active connections, query counts, replication lag |
|
|
52
|
+
| Auth Usage | Signups, logins, provider breakdown, failed attempts |
|
|
53
|
+
| Storage | Bandwidth, object counts, bucket usage |
|
|
54
|
+
| Realtime | Active connections, messages per second, channel counts |
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
name: 'supabase_requests_total',
|
|
45
|
-
help: 'Total Supabase API requests',
|
|
46
|
-
labelNames: ['method', 'status'],
|
|
47
|
-
registers: [registry],
|
|
48
|
-
});
|
|
56
|
+
For deeper Postgres diagnostics, use the CLI inspect commands:
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
labelNames: ['method'],
|
|
54
|
-
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
|
|
55
|
-
registers: [registry],
|
|
56
|
-
});
|
|
58
|
+
```bash
|
|
59
|
+
# Table sizes — find the largest tables
|
|
60
|
+
npx supabase inspect db table-sizes --linked
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
help: 'Supabase errors by type',
|
|
61
|
-
labelNames: ['error_type'],
|
|
62
|
-
registers: [registry],
|
|
63
|
-
});
|
|
64
|
-
```
|
|
62
|
+
# Index usage — find unused indexes wasting space
|
|
63
|
+
npx supabase inspect db index-usage --linked
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
# Cache hit ratio — should be > 99% (below 95% means upgrade compute)
|
|
66
|
+
npx supabase inspect db cache-hit --linked
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
method: string,
|
|
71
|
-
operation: () => Promise<T>
|
|
72
|
-
): Promise<T> {
|
|
73
|
-
const timer = requestDuration.startTimer({ method });
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const result = await operation();
|
|
77
|
-
requestCounter.inc({ method, status: 'success' });
|
|
78
|
-
return result;
|
|
79
|
-
} catch (error: any) {
|
|
80
|
-
requestCounter.inc({ method, status: 'error' });
|
|
81
|
-
errorCounter.inc({ error_type: error.code || 'unknown' });
|
|
82
|
-
throw error;
|
|
83
|
-
} finally {
|
|
84
|
-
timer();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
68
|
+
# Sequential scans — tables needing indexes
|
|
69
|
+
npx supabase inspect db seq-scans --linked
|
|
88
70
|
|
|
89
|
-
|
|
71
|
+
# Long-running queries — find stuck queries
|
|
72
|
+
npx supabase inspect db long-running-queries --linked
|
|
90
73
|
|
|
91
|
-
|
|
74
|
+
# Table index sizes — compare index vs table size
|
|
75
|
+
npx supabase inspect db table-index-sizes --linked
|
|
92
76
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
): Promise<T> {
|
|
102
|
-
return tracer.startActiveSpan(`supabase.${operationName}`, async (span) => {
|
|
103
|
-
try {
|
|
104
|
-
const result = await operation();
|
|
105
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
106
|
-
return result;
|
|
107
|
-
} catch (error: any) {
|
|
108
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
109
|
-
span.recordException(error);
|
|
110
|
-
throw error;
|
|
111
|
-
} finally {
|
|
112
|
-
span.end();
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
77
|
+
# Bloat — estimate wasted space from dead tuples
|
|
78
|
+
npx supabase inspect db bloat --linked
|
|
79
|
+
|
|
80
|
+
# Blocking queries — find lock contention
|
|
81
|
+
npx supabase inspect db blocking --linked
|
|
82
|
+
|
|
83
|
+
# Replication slots — check replication health
|
|
84
|
+
npx supabase inspect db replication-slots --linked
|
|
116
85
|
```
|
|
117
86
|
|
|
118
|
-
|
|
87
|
+
### Step 2: Query Analytics with pg_stat_statements and Log Drains
|
|
88
|
+
|
|
89
|
+
Enable `pg_stat_statements` for detailed query-level metrics:
|
|
90
|
+
|
|
91
|
+
```sql
|
|
92
|
+
-- Enable the extension (Dashboard > Database > Extensions, or SQL)
|
|
93
|
+
create extension if not exists pg_stat_statements;
|
|
94
|
+
|
|
95
|
+
-- Top 20 slowest queries by average execution time
|
|
96
|
+
select
|
|
97
|
+
substring(query, 1, 80) as query_preview,
|
|
98
|
+
calls,
|
|
99
|
+
round(mean_exec_time::numeric, 2) as avg_ms,
|
|
100
|
+
round(max_exec_time::numeric, 2) as max_ms,
|
|
101
|
+
round(total_exec_time::numeric, 2) as total_ms,
|
|
102
|
+
rows
|
|
103
|
+
from pg_stat_statements
|
|
104
|
+
where mean_exec_time > 50
|
|
105
|
+
order by mean_exec_time desc
|
|
106
|
+
limit 20;
|
|
107
|
+
|
|
108
|
+
-- Most-called queries (high call count may indicate N+1 problems)
|
|
109
|
+
select
|
|
110
|
+
substring(query, 1, 80) as query_preview,
|
|
111
|
+
calls,
|
|
112
|
+
round(mean_exec_time::numeric, 2) as avg_ms,
|
|
113
|
+
rows
|
|
114
|
+
from pg_stat_statements
|
|
115
|
+
order by calls desc
|
|
116
|
+
limit 20;
|
|
117
|
+
|
|
118
|
+
-- Real-time connection monitoring
|
|
119
|
+
select
|
|
120
|
+
state,
|
|
121
|
+
count(*) as connections,
|
|
122
|
+
max(age(now(), state_change))::text as longest_duration
|
|
123
|
+
from pg_stat_activity
|
|
124
|
+
where datname = current_database()
|
|
125
|
+
group by state
|
|
126
|
+
order by connections desc;
|
|
127
|
+
|
|
128
|
+
-- Reset stats after optimization (to measure improvement)
|
|
129
|
+
select pg_stat_statements_reset();
|
|
130
|
+
```
|
|
119
131
|
|
|
120
|
-
|
|
132
|
+
**Log drains** forward Supabase logs to external aggregation tools:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Add a Datadog log drain
|
|
136
|
+
npx supabase log-drains add \
|
|
137
|
+
--name datadog-drain \
|
|
138
|
+
--type datadog \
|
|
139
|
+
--datadog-api-key "$DATADOG_API_KEY" \
|
|
140
|
+
--datadog-region us1 \
|
|
141
|
+
--linked
|
|
142
|
+
|
|
143
|
+
# Add a custom HTTP log drain (Logflare, Axiom, etc.)
|
|
144
|
+
npx supabase log-drains add \
|
|
145
|
+
--name custom-drain \
|
|
146
|
+
--type webhook \
|
|
147
|
+
--url "https://api.logflare.app/logs/supabase" \
|
|
148
|
+
--linked
|
|
149
|
+
|
|
150
|
+
# List active drains
|
|
151
|
+
npx supabase log-drains list --linked
|
|
152
|
+
|
|
153
|
+
# Remove a drain
|
|
154
|
+
npx supabase log-drains remove <drain-id> --linked
|
|
155
|
+
```
|
|
121
156
|
|
|
122
|
-
|
|
123
|
-
import pino from 'pino';
|
|
157
|
+
Log drain events include API requests, Auth events, Postgres logs, Storage operations, and Edge Function invocations.
|
|
124
158
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
});
|
|
159
|
+
### Step 3: Custom Metrics, Alerting, and Health Checks
|
|
160
|
+
|
|
161
|
+
**Custom metrics via Edge Functions** — emit structured events for business-level monitoring:
|
|
129
162
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
163
|
+
```typescript
|
|
164
|
+
// supabase/functions/collect-metrics/index.ts
|
|
165
|
+
import { createClient } from '@supabase/supabase-js';
|
|
166
|
+
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
|
167
|
+
|
|
168
|
+
serve(async () => {
|
|
169
|
+
const supabase = createClient(
|
|
170
|
+
Deno.env.get('SUPABASE_URL')!,
|
|
171
|
+
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Collect quota-relevant metrics
|
|
175
|
+
const { count: userCount } = await supabase
|
|
176
|
+
.from('profiles')
|
|
177
|
+
.select('*', { count: 'exact', head: true });
|
|
178
|
+
|
|
179
|
+
const { count: storageObjects } = await supabase
|
|
180
|
+
.storage.from('uploads')
|
|
181
|
+
.list('', { limit: 1, offset: 0 })
|
|
182
|
+
.then(({ data }) => ({ count: data?.length ?? 0 }));
|
|
183
|
+
|
|
184
|
+
const { data: dbSize } = await supabase
|
|
185
|
+
.rpc('get_database_size');
|
|
186
|
+
|
|
187
|
+
const metrics = {
|
|
188
|
+
timestamp: new Date().toISOString(),
|
|
189
|
+
user_count: userCount,
|
|
190
|
+
db_size_mb: dbSize,
|
|
191
|
+
storage_objects: storageObjects,
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// Store metrics for trend analysis
|
|
195
|
+
await supabase.from('app_metrics').insert(metrics);
|
|
196
|
+
|
|
197
|
+
// Alert on quota thresholds
|
|
198
|
+
const DB_LIMIT_MB = 8000; // 8GB Pro plan limit
|
|
199
|
+
if (dbSize > DB_LIMIT_MB * 0.85) {
|
|
200
|
+
console.warn(`[QUOTA_ALERT] Database at ${Math.round(dbSize / DB_LIMIT_MB * 100)}% capacity`);
|
|
201
|
+
// Send alert via webhook, email, or Slack
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return new Response(JSON.stringify(metrics), {
|
|
205
|
+
headers: { 'Content-Type': 'application/json' },
|
|
140
206
|
});
|
|
141
|
-
}
|
|
207
|
+
});
|
|
142
208
|
```
|
|
143
209
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
### Prometheus AlertManager Rules
|
|
147
|
-
|
|
148
|
-
```yaml
|
|
149
|
-
# supabase_alerts.yaml
|
|
150
|
-
groups:
|
|
151
|
-
- name: supabase_alerts
|
|
152
|
-
rules:
|
|
153
|
-
- alert: SupabaseHighErrorRate
|
|
154
|
-
expr: |
|
|
155
|
-
rate(supabase_errors_total[5m]) /
|
|
156
|
-
rate(supabase_requests_total[5m]) > 0.05
|
|
157
|
-
for: 5m
|
|
158
|
-
labels:
|
|
159
|
-
severity: warning
|
|
160
|
-
annotations:
|
|
161
|
-
summary: "Supabase error rate > 5%"
|
|
162
|
-
|
|
163
|
-
- alert: SupabaseHighLatency
|
|
164
|
-
expr: |
|
|
165
|
-
histogram_quantile(0.95,
|
|
166
|
-
rate(supabase_request_duration_seconds_bucket[5m])
|
|
167
|
-
) > 2
|
|
168
|
-
for: 5m
|
|
169
|
-
labels:
|
|
170
|
-
severity: warning
|
|
171
|
-
annotations:
|
|
172
|
-
summary: "Supabase P95 latency > 2s"
|
|
173
|
-
|
|
174
|
-
- alert: SupabaseDown
|
|
175
|
-
expr: up{job="supabase"} == 0
|
|
176
|
-
for: 1m
|
|
177
|
-
labels:
|
|
178
|
-
severity: critical
|
|
179
|
-
annotations:
|
|
180
|
-
summary: "Supabase integration is down"
|
|
181
|
-
```
|
|
210
|
+
Schedule it with a cron trigger in `supabase/config.toml`:
|
|
182
211
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"panels": [
|
|
190
|
-
{
|
|
191
|
-
"title": "Supabase Request Rate",
|
|
192
|
-
"targets": [{
|
|
193
|
-
"expr": "rate(supabase_requests_total[5m])"
|
|
194
|
-
}]
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"title": "Supabase Latency P50/P95/P99",
|
|
198
|
-
"targets": [{
|
|
199
|
-
"expr": "histogram_quantile(0.5, rate(supabase_request_duration_seconds_bucket[5m]))"
|
|
200
|
-
}]
|
|
201
|
-
}
|
|
202
|
-
]
|
|
203
|
-
}
|
|
212
|
+
```toml
|
|
213
|
+
[functions.collect-metrics]
|
|
214
|
+
schedule = "*/15 * * * *" # Every 15 minutes
|
|
204
215
|
```
|
|
205
216
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
### Step 1: Set Up Metrics Collection
|
|
209
|
-
Implement Prometheus counters, histograms, and gauges for key operations.
|
|
217
|
+
**Health check endpoint** for uptime monitoring (Uptime Robot, Pingdom, etc.):
|
|
210
218
|
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
```typescript
|
|
220
|
+
// supabase/functions/health/index.ts
|
|
221
|
+
import { createClient } from '@supabase/supabase-js';
|
|
222
|
+
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
|
223
|
+
|
|
224
|
+
serve(async () => {
|
|
225
|
+
const supabase = createClient(
|
|
226
|
+
Deno.env.get('SUPABASE_URL')!,
|
|
227
|
+
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const checks: Record<string, { status: string; latency_ms: number; detail?: string }> = {};
|
|
231
|
+
|
|
232
|
+
// Database check
|
|
233
|
+
const dbStart = Date.now();
|
|
234
|
+
const { error: dbErr } = await supabase.rpc('version');
|
|
235
|
+
checks.database = {
|
|
236
|
+
status: dbErr ? 'unhealthy' : 'healthy',
|
|
237
|
+
latency_ms: Date.now() - dbStart,
|
|
238
|
+
...(dbErr && { detail: dbErr.message }),
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// Auth check
|
|
242
|
+
const authStart = Date.now();
|
|
243
|
+
const { error: authErr } = await supabase.auth.admin.listUsers({ perPage: 1 });
|
|
244
|
+
checks.auth = {
|
|
245
|
+
status: authErr ? 'unhealthy' : 'healthy',
|
|
246
|
+
latency_ms: Date.now() - authStart,
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// Storage check
|
|
250
|
+
const storageStart = Date.now();
|
|
251
|
+
const { error: storageErr } = await supabase.storage.listBuckets();
|
|
252
|
+
checks.storage = {
|
|
253
|
+
status: storageErr ? 'unhealthy' : 'healthy',
|
|
254
|
+
latency_ms: Date.now() - storageStart,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const overall = Object.values(checks).every(c => c.status === 'healthy');
|
|
258
|
+
const statusCode = overall ? 200 : 503;
|
|
259
|
+
|
|
260
|
+
return new Response(
|
|
261
|
+
JSON.stringify({ status: overall ? 'healthy' : 'degraded', checks, timestamp: new Date().toISOString() }),
|
|
262
|
+
{ status: statusCode, headers: { 'Content-Type': 'application/json' } }
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
```
|
|
213
266
|
|
|
214
|
-
|
|
215
|
-
Set up JSON logging with consistent field names.
|
|
267
|
+
**Real-time connection monitoring** — track active Realtime connections:
|
|
216
268
|
|
|
217
|
-
|
|
218
|
-
|
|
269
|
+
```typescript
|
|
270
|
+
import { createClient } from '@supabase/supabase-js';
|
|
271
|
+
|
|
272
|
+
const supabase = createClient(
|
|
273
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
274
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
// Monitor channel state changes
|
|
278
|
+
const channel = supabase.channel('monitoring');
|
|
279
|
+
|
|
280
|
+
channel
|
|
281
|
+
.on('system', { event: '*' }, (payload) => {
|
|
282
|
+
console.log(`[REALTIME] System event:`, payload);
|
|
283
|
+
})
|
|
284
|
+
.subscribe((status) => {
|
|
285
|
+
console.log(`[REALTIME] Connection status: ${status}`);
|
|
286
|
+
if (status === 'CHANNEL_ERROR') {
|
|
287
|
+
console.error('[REALTIME] Connection lost — will auto-reconnect');
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
```
|
|
219
291
|
|
|
220
292
|
## Output
|
|
221
|
-
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
293
|
+
|
|
294
|
+
- Dashboard reports configured for API, database, and auth monitoring
|
|
295
|
+
- CLI inspect commands available for Postgres diagnostics (table sizes, index usage, cache hits, sequential scans, long-running queries)
|
|
296
|
+
- `pg_stat_statements` enabled with slow-query and high-frequency-query views
|
|
297
|
+
- Log drains forwarding to external tools (Datadog, Logflare, or webhook)
|
|
298
|
+
- Custom metrics Edge Function collecting quota-relevant data on a schedule
|
|
299
|
+
- Health check endpoint returning per-service status with latency
|
|
300
|
+
- Alerting on quota thresholds (database size, user count)
|
|
225
301
|
|
|
226
302
|
## Error Handling
|
|
303
|
+
|
|
227
304
|
| Issue | Cause | Solution |
|
|
228
305
|
|-------|-------|----------|
|
|
229
|
-
|
|
|
230
|
-
|
|
|
231
|
-
|
|
|
232
|
-
|
|
|
306
|
+
| `pg_stat_statements` returns no rows | Extension not enabled | Enable via Dashboard > Database > Extensions |
|
|
307
|
+
| `supabase inspect db` fails | CLI not linked to project | Run `supabase link --project-ref <ref>` |
|
|
308
|
+
| Log drain not receiving events | API key invalid or region mismatch | Verify credentials; check `supabase log-drains list` |
|
|
309
|
+
| Cache hit ratio below 95% | Working set exceeds RAM | Upgrade compute add-on or optimize queries |
|
|
310
|
+
| Health check returns 503 | One or more services degraded | Check `detail` field in response; verify service role key |
|
|
311
|
+
| Edge Function cron not firing | Missing `schedule` in config.toml | Add `[functions.<name>]` with `schedule` field and redeploy |
|
|
312
|
+
| Long-running queries growing | Missing indexes or lock contention | Run `inspect db seq-scans` and `inspect db blocking` |
|
|
233
313
|
|
|
234
314
|
## Examples
|
|
235
315
|
|
|
236
|
-
### Quick
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
316
|
+
### Quick Diagnostic Script
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
#!/bin/bash
|
|
320
|
+
# supabase-health-check.sh — run all inspect commands at once
|
|
321
|
+
echo "=== Table Sizes ==="
|
|
322
|
+
npx supabase inspect db table-sizes --linked
|
|
323
|
+
echo ""
|
|
324
|
+
echo "=== Cache Hit Ratio ==="
|
|
325
|
+
npx supabase inspect db cache-hit --linked
|
|
326
|
+
echo ""
|
|
327
|
+
echo "=== Sequential Scans ==="
|
|
328
|
+
npx supabase inspect db seq-scans --linked
|
|
329
|
+
echo ""
|
|
330
|
+
echo "=== Long Running Queries ==="
|
|
331
|
+
npx supabase inspect db long-running-queries --linked
|
|
332
|
+
echo ""
|
|
333
|
+
echo "=== Index Usage ==="
|
|
334
|
+
npx supabase inspect db index-usage --linked
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Metrics Table Schema
|
|
338
|
+
|
|
339
|
+
```sql
|
|
340
|
+
create table if not exists app_metrics (
|
|
341
|
+
id bigint generated always as identity primary key,
|
|
342
|
+
timestamp timestamptz not null default now(),
|
|
343
|
+
user_count integer,
|
|
344
|
+
db_size_mb numeric,
|
|
345
|
+
storage_objects integer,
|
|
346
|
+
api_requests_24h integer,
|
|
347
|
+
avg_response_ms numeric
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
-- Index for time-series queries
|
|
351
|
+
create index idx_app_metrics_timestamp on app_metrics (timestamp desc);
|
|
352
|
+
|
|
353
|
+
-- Retention policy: keep 90 days
|
|
354
|
+
create or replace function cleanup_old_metrics()
|
|
355
|
+
returns void as $$
|
|
356
|
+
delete from app_metrics where timestamp < now() - interval '90 days';
|
|
357
|
+
$$ language sql;
|
|
242
358
|
```
|
|
243
359
|
|
|
244
360
|
## Resources
|
|
245
|
-
|
|
246
|
-
- [
|
|
247
|
-
- [
|
|
361
|
+
|
|
362
|
+
- [Supabase Logs & Analytics](https://supabase.com/docs/guides/platform/logs)
|
|
363
|
+
- [Database Inspect Commands](https://supabase.com/docs/guides/database/inspect)
|
|
364
|
+
- [Log Drains](https://supabase.com/docs/guides/platform/log-drains)
|
|
365
|
+
- [Edge Functions Scheduling](https://supabase.com/docs/guides/functions/schedule-functions)
|
|
366
|
+
- [pg_stat_statements](https://supabase.com/docs/guides/database/extensions/pg_stat_statements)
|
|
367
|
+
- [Supabase JS Client](https://supabase.com/docs/reference/javascript/introduction)
|
|
248
368
|
|
|
249
369
|
## Next Steps
|
|
250
|
-
|
|
370
|
+
|
|
371
|
+
For incident response procedures, see `supabase-incident-runbook`.
|
|
372
|
+
For performance optimization, see `supabase-performance-tuning`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Alert Configuration
|
|
2
|
+
|
|
3
|
+
## Alert Configuration
|
|
4
|
+
|
|
5
|
+
### Prometheus AlertManager Rules
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
# supabase_alerts.yaml
|
|
9
|
+
groups:
|
|
10
|
+
- name: supabase_alerts
|
|
11
|
+
rules:
|
|
12
|
+
- alert: SupabaseHighErrorRate
|
|
13
|
+
expr: |
|
|
14
|
+
rate(supabase_errors_total[5m]) /
|
|
15
|
+
rate(supabase_requests_total[5m]) > 0.05
|
|
16
|
+
for: 5m
|
|
17
|
+
labels:
|
|
18
|
+
severity: warning
|
|
19
|
+
annotations:
|
|
20
|
+
summary: "Supabase error rate > 5%"
|
|
21
|
+
|
|
22
|
+
- alert: SupabaseHighLatency
|
|
23
|
+
expr: |
|
|
24
|
+
histogram_quantile(0.95,
|
|
25
|
+
rate(supabase_request_duration_seconds_bucket[5m])
|
|
26
|
+
) > 2
|
|
27
|
+
for: 5m
|
|
28
|
+
labels:
|
|
29
|
+
severity: warning
|
|
30
|
+
annotations:
|
|
31
|
+
summary: "Supabase P95 latency > 2s"
|
|
32
|
+
|
|
33
|
+
- alert: SupabaseDown
|
|
34
|
+
expr: up{job="supabase"} == 0
|
|
35
|
+
for: 1m
|
|
36
|
+
labels:
|
|
37
|
+
severity: critical
|
|
38
|
+
annotations:
|
|
39
|
+
summary: "Supabase integration is down"
|
|
40
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
| Issue | Cause | Solution |
|
|
4
|
+
|-------|-------|----------|
|
|
5
|
+
| Missing metrics | No instrumentation | Wrap client calls |
|
|
6
|
+
| Trace gaps | Missing propagation | Check context headers |
|
|
7
|
+
| Alert storms | Wrong thresholds | Tune alert rules |
|
|
8
|
+
| High cardinality | Too many labels | Reduce label values |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Examples
|
|
2
|
+
|
|
3
|
+
### Quick Metrics Endpoint
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
app.get('/metrics', async (req, res) => {
|
|
7
|
+
res.set('Content-Type', registry.contentType);
|
|
8
|
+
res.send(await registry.metrics());
|
|
9
|
+
});
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|