Repository navigation
feat(backend): add Prometheus alert metrics and health telemetry to Database Row-Level Security Service - #1610
Open
Abidoyesimze wants to merge 2 commits into
Conversation
…or Database Row-Level Security Service withMerchantContext previously passed merchantId straight to SET LOCAL accepting anything truthy, and the rollback path could mask the original error if ROLLBACK itself failed: - Adds a strict Zod schema for merchantId (length bounds + allowed character class) applied before any SQL runs; invalid IDs fail fast with a clear error before a connection is taken from the pool. - Sanitizes/normalizes the ID (trim + strip disallowed characters) for both the transaction and logging paths, and exposes sanitizeMerchantId for safe log enrichment. - Validates the callback is actually a function, so a bad call site fails deterministically instead of crashing mid-transaction. - Rollback is now wrapped so a rollback failure is logged rather than replacing the original error, and the client is always released. Adds unit tests covering accepted/rejected IDs, sanitization edge cases, and transaction commit/rollback/release ordering.
…atabase Row-Level Security Service Every merchant-scoped transaction goes through withMerchantContext() but the RLS path had no metrics, health signal or alerting, so connection exhaustion, failing SET LOCAL transactions and rollback storms were invisible until queries started failing in callers: - Adds db-rls-telemetry.js: outcome counters, latency histogram, active- transaction gauge and a rolling-window health monitor with scrape-time gauges, on its own prom-client registry. Label values are a fixed set (committed | rolled_back | invalid_input | connection_error | transaction_error) — never merchant ids, SQL or error strings — so cardinality stays bounded. - Instruments withMerchantContext to record one outcome per attempt (invalid_input fails fast before touching the pool; connection_error covers pool.connect failure; rolled_back covers callback failures; transaction_error covers BEGIN/SET LOCAL/COMMIT and failed ROLLBACK). - Exposes GET /health/database-row-level-security (503 only when unhealthy; degraded still 200) and reports status under services in GET /health. - Merges the RLS registry into the /metrics scrape output. - Adds alert rules (docs/alerts/database-row-level-security.rules.yml) for unhealthy state, error ratio, rollback ratio, invalid-input spikes and missing traffic, plus docs/DATABASE_ROW_LEVEL_SECURITY.md. Adds db-rls-telemetry.test.js (18 tests) covering the health monitor windows, thresholds and expiry, counter/histogram recording, and outcome attribution through withMerchantContext with a mocked pool.
|
@Abidoyesimze is attempting to deploy a commit to the Emmanuel's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Abidoyesimze Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1468
Every merchant-scoped transaction runs through
withMerchantContext(), but the RLS path had no metrics, no health signal and no alerting: connection exhaustion, failingSET LOCALtransactions and rollback storms were invisible until callers started seeing query errors.New
src/lib/db-rls-telemetry.js(own prom-client registry, merged into/metricsbysrc/routes/prometheus.js):database_rls_transactions_totaloutcomedatabase_rls_transaction_duration_secondsoutcomedatabase_rls_active_transactionsdatabase_rls_health_state(0/1/2)database_rls_error_ratio/database_rls_rollback_ratiodatabase_rls_last_transaction_timestamp_secondsoutcomeis a fixed set:committed,rolled_back(callback threw),invalid_input(failed validation, pool never touched),connection_error(pool.connect()failed),transaction_error(BEGIN/SET LOCAL/COMMITfailed, orROLLBACKitself failed).withMerchantContext()records exactly one outcome per attempt via a timing wrapper; the active gauge is incremented on connect and decremented infinally.Rolling-window health monitor (fixed ring of time buckets, constant memory): unhealthy when connection+transaction errors ≥ 5% of ≥ 20 samples; degraded when callback rollbacks ≥ 50%, or ≥ 10
invalid_inputoutcomes (a caller is misbehaving). Gauges refresh at scrape time so they decay when idle. Thresholds are env-overridable (DATABASE_RLS_*).Endpoints:
GET /health/database-row-level-security— 503 only when unhealthy; degraded still 200services.database_row_level_securityadded toGET /health(informational, does not affectok)Alert rules
docs/alerts/database-row-level-security.rules.yml(promtool-valid):DatabaseRlsUnhealthy(critical),DatabaseRlsHighErrorRatio(critical),DatabaseRlsHighRollbackRatio(warning),DatabaseRlsInvalidInputSpike(warning),DatabaseRlsNoTraffic(info). Reference doc:docs/DATABASE_ROW_LEVEL_SECURITY.md.Test plan
18 new telemetry tests: health-monitor windows (healthy / unhealthy error ratio / degraded rollback ratio / invalid-input spike / min-sample floor / expiry of stale buckets / last-transaction timestamp), counter + histogram + gauge recording, unknown-outcome fallback, and outcome attribution through
withMerchantContextwith a mocked pool (committed, rolled_back, invalid_input ×2, connection_error, BEGIN failure → transaction_error, active gauge returning to zero). The 19 existing #1609 RLS tests still pass — no behavioural change to the transaction contract.Full backend suite: no new failures vs.
origin/main(identical pre-existing failure count).Security notes
/metricsor/health/*output, so the monitoring stack sees no customer data.invalid_inputas a security signal: a spike in sanitized-away merchant ids usually means a caller (or an attacker probing the API) is sending malformed IDs; the dedicated alert turns that into a detectable event rather than silent log noise.finally, so a throwing callback cannot leak a permanently "in flight" count that would mask real leaks in the alert rules.