Alert State Report — 2026-05-01
Snapshot
Captured 2026-05-01 ~16:30 UTC on branch
290-payment-pipeline-observability. Cluster: pal-e (k3s). Alertmanager v2 + Prometheus via kube-prometheus-stack. Single receiver telegram. Zero active silences.- 9 firing, 0 pending, 0 silenced
- 123 alerting rules total across 36 rule groups (7.3% active)
- 3 westside-relevant, 5 platform-infra, 1 heartbeat
Why some "expected" failure modes are missing
The recent commit on this branch (
432e24e, issue #290) disabled kubeStateMetrics and kubernetesApps default rule families to cut noise. That silenced ~30 helm-default alerts including KubePodNotReady, KubeContainerWaiting, KubeJobFailed, KubeDeploymentReplicasMismatch.Side effect: we are now blind to pods stuck in
ImagePullBackOff (e.g. westside-ai-assistant-8586c7c767-7xv6c, broken 27 days) and Init:0/1 (e.g. default/basketball-api-65f46d6ddd-5gm4s). Real failed states with no alert.Currently firing — full list
Westside-relevant (3)
| # | Alert | Sev | Since | Detail |
|---|---|---|---|---|
| 1 | <code>WebhookStale</code> | warning | 2026-05-01 16:00:27 (~30 min) | basketball-api has not received a <code>checkout.session.completed</code> webhook for 30+ min during business hours. Pod <code>basketball-api-6fd588f9f8-jcknx</code>. <strong>This is the new alert from <code>payment-pipeline-alerts</code> actively catching something.</strong> Either Stripe can't reach the endpoint, no live checkouts are happening, or the webhook handler is broken. |
| 2 | <code>GmailOAuthTokenExpired</code> | critical | 2026-04-29 01:57:20 (2d 10h) | Gmail OAuth token for <code>westsidebasketball@gmail.com</code> is older than 7 days. Westside email sends are broken right now. Auto-reauth lifecycle (PR #222) was supposed to refresh this — it's not running. |
| 3 | <code>GmailOAuthTokenExpiringSoon</code> | warning | 2026-04-29 01:57:20 (2d 10h) | Same root cause as #2. Fires at 6 days; #2 fires at 7. Both firing simultaneously = noise duplicate. |
Not westside — platform infra (5)
| # | Alert | Sev | Since | Detail |
|---|---|---|---|---|
| 4 | <code>OOMKilled</code> | critical | 2026-04-29 01:57:44 (2d 10h) | <code>pal-e-docs/pal-e-docs-6c7fdd96d7-fll8h</code>. Container memory limit too low or leak. |
| 5 | <code>OOMKilled</code> | critical | 2026-04-29 01:57:44 (2d 10h) | <code>argocd/argocd-application-controller-0</code>. Known kube-prometheus-stack issue — controller hits default 256Mi limit on growing app sets. |
| 6 | <code>MacAgentDown</code> | critical | 2026-04-15 12:45:15 (<strong>16d</strong>) | <code>lucass-macbook-air-1</code> Mac CI node-exporter unreachable. Laptop offline. iOS CI builds blocked. |
| 7 | <code>TargetDown</code> | warning | 2026-04-15 12:45:29 (<strong>16d</strong>) | Same Mac, hit by the generic <code>up == 0</code> rule. |
| 8 | <code>TargetDown</code> | warning | 2026-03-28 18:07:49 (<strong>34d</strong>) | Same Mac, hit by the helm-default aggregate-targets rule. Triple-counted. |
Heartbeat (1)
| # | Alert | Sev | Since | Detail |
|---|---|---|---|---|
| 9 | <code>Watchdog</code> | none | 2026-04-15 12:45:19 | DeadMansSnitch test alert. Always firing = correct. Tells you Alertmanager is alive. |
Where each rule comes from (123 total alerting rules)
| Source | Rules | Firing |
|---|---|---|
| <code>kube-prometheus-stack-node-exporter</code> (helm default) | 26 | 0 |
| <code>kube-prometheus-stack-prometheus</code> (self-monitoring) | 23 | 0 |
| <code>kube-prometheus-stack-kubernetes-system-kubelet</code> | 15 | 0 |
| <code>kube-prometheus-stack-alertmanager.rules</code> | 8 | 0 |
| <code>kube-prometheus-stack-kubernetes-resources</code> | 8 | 0 |
| <code>kube-prometheus-stack-prometheus-operator</code> | 8 | 0 |
| <code>kube-prometheus-stack-kubernetes-system-apiserver</code> | 6 | 0 |
| <code>kube-prometheus-stack-kubernetes-storage</code> | 5 | 0 |
| <strong><code>kube-prometheus-stack-platform-alerts</code> (our custom)</strong> | 5 | <strong>4</strong> (MacAgentDown, OOMKilled×2, TargetDown) |
| <code>kube-prometheus-stack-kube-apiserver-slos</code> | 4 | 0 |
| <code>kube-prometheus-stack-general.rules</code> | 3 | 2 (Watchdog, TargetDown) |
| <code>kube-prometheus-stack-kubernetes-system</code> | 2 | 0 |
| <code>blackbox-alerts</code> (our custom) | 2 | 0 |
| <code>embedding-alerts</code> (our custom) | 2 | 0 |
| <strong><code>gmail-oauth-expiry</code> (our custom)</strong> | 2 | <strong>2</strong> |
| <strong><code>payment-pipeline-alerts</code> (NEW on this branch)</strong> | 2 | <strong>1</strong> (WebhookStale) |
| <code>kube-prometheus-stack-config-reloaders</code> | 1 | 0 |
| <code>kube-prometheus-stack-node-network</code> | 1 | 0 |
Our custom rules are doing 7 of the 9 firing alerts; helm defaults are doing 2 (TargetDown aggregate + Watchdog).
What's NOT covered by any rule
westside-contracts,westside-email,westside-ai-assistant— no probes, no metrics scrapes, no rules. Invisible.- Pods in
ImagePullBackOff/Init— disabledkubernetesAppsrule family removedKubeContainerWaiting. - Deployment replica mismatches — same reason (
KubeDeploymentReplicasMismatchdisabled). - HTTP 5xx rates on basketball-api endpoints —
prometheus-fastapi-instrumentatornot wired yet (separate ticket). - Webhook processing errors per event type —
WebhookErrorRatedoesn't differentiate signature-fail vs handler-throw vs idempotency-skip.
Routing & inhibition (Alertmanager config)
- Single receiver:
telegram(everything goes there) - One inhibit rule (added on this branch):
severity=criticalsuppressesseverity=warningwhenalertnameandnamespacematch. Works forOOMKilled(no warning version exists), but missesGmailOAuthToken*because the two have different alertnames — that's why both are firing. - No grouping by severity — critical and warning hit telegram with the same routing.
Three things stand out
WebhookStalelit up ~30 min ago. Worth checking whether it caught a real outage or whether the time-of-day filter (hour() >= 16 or hour() < 4UTC) is wrong for actual MST business hours — it's currently early morning MST on a Friday, which means it just rolled into "business hours" by the rule's definition. If no real checkouts happen until later, this fires daily at the same time. May need an "after first checkout of the day" variant.- Gmail OAuth has been broken for 2+ days. Westside email is dead. The auto-reauth cron isn't doing its job. Real fire.
- The Mac alerts are 16-34 days old. Three firing alerts for one offline laptop. Either silence the Mac during expected-offline windows or cut the duplicate
TargetDownrules.
Cleanup proposal (from prior discussion)
- Ship branch
290-payment-pipeline-observability— already silenceskubeStateMetrics/kubernetesApps, raises blackboxforfrom 2m→5m, drops noisy probes, addsbasketball-api-golden-signalsdashboard, addsWebhookErrorRate+WebhookStale. - Fix the Gmail inhibit rule. Restructure so
Expired/ExpiringSoonshare an alertname with different severity, OR equal-onsecretlabel. - Triage non-westside criticals as separate tickets: pal-e-docs OOM (bump memory or fix leak), argocd OOM (raise limits), MacAgentDown (time-window the alert).
- Add a westside-unified dashboard + add probes for
westside-contracts,westside-email,westside-ai-assistant. - Fix the actual Gmail OAuth lifecycle. Auto-reauth (#222) shipped but token is 52 days old — cron either isn't running or is failing silently.
- Re-add coverage for failed pod states. The disabled
kubernetesAppsfamily included real signal (KubeContainerWaiting,KubePodNotReady). Either selectively re-enable a subset or write a tighter custom rule scoped to known-good namespaces.