Alert State Report — 2026-05-01

alert-report-2026-05-01 Doc

doc ops alerts observability

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 — disabled kubernetesApps rule family removed KubeContainerWaiting.
  • Deployment replica mismatches — same reason (KubeDeploymentReplicasMismatch disabled).
  • HTTP 5xx rates on basketball-api endpoints — prometheus-fastapi-instrumentator not wired yet (separate ticket).
  • Webhook processing errors per event type — WebhookErrorRate doesn'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=critical suppresses severity=warning when alertname and namespace match. Works for OOMKilled (no warning version exists), but misses GmailOAuthToken* 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

  • WebhookStale lit up ~30 min ago. Worth checking whether it caught a real outage or whether the time-of-day filter (hour() >= 16 or hour() < 4 UTC) 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 TargetDown rules.

Cleanup proposal (from prior discussion)

  • Ship branch 290-payment-pipeline-observability — already silences kubeStateMetrics/kubernetesApps, raises blackbox for from 2m→5m, drops noisy probes, adds basketball-api-golden-signals dashboard, adds WebhookErrorRate + WebhookStale.
  • Fix the Gmail inhibit rule. Restructure so Expired/ExpiringSoon share an alertname with different severity, OR equal-on secret label.
  • 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 kubernetesApps family included real signal (KubeContainerWaiting, KubePodNotReady). Either selectively re-enable a subset or write a tighter custom rule scoped to known-good namespaces.