Repository navigation
feat(infra): prod uptime check + [P0] API Down; /health fails on DB down, TCP probes - #843
Merged
Merged
Conversation
…ates Prod had no GCM uptime check and no API-down page: the monitoring module gates both on api_domain, which main.tf fed from var.domain, and prod leaves domain empty because the GCLB serves api_host_suffix. Fall back to api_host_suffix when the LB is on. The three PromQL gates (api_latency, oauth_refresh, upstream_error) are on in both envs; their descriptors were measured present 2026-10-27. The OAuth, upstream and webhook ratio queries clamped a per-second denominator to 1, which at our volume made them unable to fire; they now use a 0.001 floor plus a minimum-sample guard, as the latency alert already did. Same fix on the two Actions & OAuth dashboard ratio charts. Runbook: docs/runbooks/uptime-and-alerts.md. Not applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Code diff size+18 / −31 across 1 file (net -13)
Source files under |
The HTTP liveness probe on /health (1s default timeout) lost the race with the 2s DB check once Cloud SQL went away, so dev's instance was shut down ~90s into every nightly stop and no replacement could boot: Cloud Run answered 500 until morning. The always-200 /health existed only to protect those probes, and it did not. Probes now open a TCP socket on the container port (the listener binds only after create_app has connected, migrated and preflighted, so startup loses nothing). /health shares /ready's gate: 200 ok, or 503 degraded when the DB probe fails, so [P0] API Down covers the database too. Dev's nightly API Down is accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced Oct 29, 2026
Merged
Merged
This branch was successfully 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.
Why
Prod has 0 uptime checks and no
[P0] API Down(TODO §1.6). The only P0 isAPI High 5xx Rate, which can't fire when the API returns nothing. status.overslash.com (Better Stack) does catch an outage, but it's console-managed and doesn't page.status-page.mdalso claimed the GCM API-down alert "continues to page on-call", which was false.Root cause
modules/monitoringgates both the uptime check andapi_downonapi_domain != "", andinfra/main.tfpassedvar.domain. Prod setsdomain = ""on purpose, because the GCLB servesapi_host_suffix. Now:domain, orapi_host_suffixwhendomainis empty andenable_api_lbis on. The LB host rule and cert already cover the apex,curl https://api.overslash.com/health→ 200, and Cloud Armor has no rate rules that would hit the checkers.The 3 disabled prod gates
All three descriptors exist in both projects (measured 2026-10-27 via the Monitoring REST API):
overslash_http_request_duration_seconds/histogram,overslash_oauth_events_total/counter,overslash_upstream_responses_total/counter. Soapi_latency,oauth_refreshandupstream_erroraretruein dev and prod.Turning them on unchanged would have added alerts that can't fire. The OAuth and upstream ratios, and the already-deployed webhook ratio, divided by
clamp_min(rate, 1). Prod traffic is under 1/s, so the denominator was always 1 and the "ratio" was failures per second. They now follow the latency alert: a0.001divide-by-zero floor plus an explicit minimum-sampleandguard (~10 refreshes / ~20 upstream responses / ~10 terminal webhook deliveries per window). The two Actions & OAuth dashboard ratio charts had the same clamp and are fixed too.Plan (read-only, from the agent sandbox)
A full plan isn't possible here:
module.monitoring'sdepends_onpulls in IAM, which the factory SA can't read, and the providers'user_project_overrideneedsserviceusageon the project. I ran-refresh=false -lock=false -target=module.monitoringwith a temporary, uncommitted provider override:domain.overview+actions_and_oauthdashboards replaced (the overview's uptime tile now gets a real check ID). The plan then stopped on the PagerDuty secret read (the SA is correctly denied), soapi_downdidn't render. Its only input past that point is the P0 channel list.tofu validateandtofu fmt -checkpass.Not applied
Infra is never auto-applied. Apply dev first, then prod, and verify per docs/runbooks/uptime-and-alerts.md (
gcloud monitoring uptime list-configs, alert-policy listing via REST, plus an optional dev drill that points the check at a 404 path). Expected in prod after apply: 14 policies, 1 uptime check (10 today).Docs:
gcp-posture.mdmonitoring section re-measured (10 policies today, both channels present) and carries the remediation; TODO item checked as in code, pending apply;STATUS.mdmonitoring line corrected to what's actually deployed;status-page.mdno longer claims a page that doesn't exist.Applied (commit 1), verified 2026-10-27
Both envs. Prod: 14 policies,
[P0] API Down→ PagerDuty + email;overslash-prod-api-healthcheck_passedtrue from all 6 regions.Follow-up (commit 2):
/health503s on DB down, Cloud Run probes are TCPFound while checking dev's nightly behaviour. Dev's uptime check failed 100% every night: the HTTP liveness probe on
/health(1s default timeout, against a 2s DB check) shut the instance down ~90s after the Cloud SQL stop (LIVENESS HTTP probe failed 3 times consecutively … The instance has been shut down, 2026-10-26 22:01:38Z). No replacement could boot (eager DB connect), so Cloud Run returned 500 all night. The always-200/healthexisted only to protect those probes, and it didn't.infra/modules/cloud-run/main.tf: startup + liveness →tcp_socketon the container port. The listener binds only aftercreate_apphas connected, migrated and preflighted, so startup readiness is unchanged.routes/health.rs:/healthreturns 503degradedwhen the DB probe fails (same gate as/ready), so prod's[P0] API Downand Better Stack cover the database. No new endpoint.D-NEXT, SPEC §health, status-page/uptime runbooks updated. Tests:routes::healthunit tests (new 503 case) +tests/health.rs/version/security_headerspass.Needs: a Cloud Run apply (
module.cloud_run) + an API release, both envs.🤖 Generated with Claude Code