feat(metrics): expose DB pool saturation as autoscaling signal #524 - #807
Open
Ajibola6921 wants to merge 1 commit into
Open
feat(metrics): expose DB pool saturation as autoscaling signal #524#807Ajibola6921 wants to merge 1 commit into
Ajibola6921 wants to merge 1 commit into
Conversation
|
@Ajibola6921 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! 🚀 |
Author
|
@thlpkee20-wq done closes #524 |
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.
Overview
This PR adds DB pool saturation as a horizontal autoscaling signal so the API workload scales on the real bottleneck (connection-pool contention) instead of CPU alone. It exports
db.pool.waitersanddb.pool.utilizationas OpenMetrics from a new scrape-authenticated endpoint, and documents the HPA/KEDA guidance, alert rules, and runbook thresholds.Related Issue
Closes #524
Changes
OpenMetrics endpoint (
GET /metrics/db-pool)src/db/pool.ts—getDbPoolSaturation,getPrimaryPoolSaturation,getReplicaPoolSaturation: synchronous snapshots from pg's in-process counters (waitingCount,totalCount,idleCount,options.max). Never issues queries, so a scrape cannot load the database it observes.src/lib/metrics.ts—MetricsCollector.collectDbPoolSaturation: emitsdb.pool.waiters{pool="primary"|"replica"}anddb.pool.utilization{pool=...}gauges (ratio clamped to [0,1]). Both series are set on every scrape, so they stay defined (value 0) when the pool is idle.src/middleware/metricsMiddleware.ts—createDbPoolMetricsHandler: refreshes the gauges and serves OpenMetrics v1.0.0 filtered to thedb.pool.families.src/app.ts— mountsGET /metrics/db-poolbehind the existingcreateMetricsAuthMiddleware()(METRICS_TOKENbearer scrape auth), same guard as/metrics.src/lib/metrics.ts—sanitizeNamenow preserves dots. Dots are valid OpenMetrics names (v1.0.0); the previous regex silently mangled the codebase's own intended names (db.replica.lag_ms→db_replica_lag_ms), which would have corrupted the newdb.pool.*families.Tests (targeted suites: 102/102 passing)
src/db/pool.test.ts— idle pool (defined 0), partial/saturated utilization, clamping (active > max, negative active), default max fallback,max: 0, replica-null case.src/lib/metrics.test.ts—collectDbPoolSaturation(labels, idle-defined, multiple pools, disabled config, prefix filtering) + dotted-name sanitization regression test.src/middleware/metricsMiddleware.test.ts— OpenMetrics content type,db.pool.*families present, idle-zero series, unrelated families excluded, error path → structured 500.Documentation
docs/autoscaling-db-pool-signal.md— metric reference, endpoint + security assumptions, runbook target thresholds (utilization ≤ 0.7, waiters 0), HPA guidance (Prometheus adapter + KEDA manifests), alert rules example (DbPoolWaitersHigh,DbPoolUtilizationHigh), troubleshooting, related code.docs/runbooks/README.md— mapping-table rows + runbook index entries for the two new alerts.scripts/validate-alert-mappings.ts— registers the new alerts (CI gate).docs/prometheus-metrics-endpoint.md— documents the new endpoint and changelog entry.Verification Results
Notes:
npm test(full suite): 169 failed / 63 passed suites — identical class of failures on the untouched baseline (192 failed / 40 passed); all are environment-dependent integration tests (Postgres, Stellar RPC, rate-limit timing) unrelated to this change. CI (ci.yml) gates onlyaudit:ciandvalidate:alert-mappings.npm run lintfails on the baseline too (ESLint 9 with a legacy.eslintrc.cjsand noeslint.config.js) — pre-existing repo-wide config issue, unchanged by this PR.db.pool.waitersanddb.pool.utilizationpoollabel, OpenMetrics v1.0.0createMetricsAuthMiddleware(METRICS_TOKEN)DbPoolWaitersHigh/DbPoolUtilizationHigh+ runbook mapping