fix(monitoring): improve Grafana alert quality, message format, and env scoping - #221
Open
NikhilMM89 wants to merge 5 commits into
Open
NikhilMM89 wants to merge 5 commits into
NikhilMM89 wants to merge 5 commits into
Conversation
…rmat Reworks alerting so criticals reflect real service impact and the notification message is consistent and scannable. Message format (n8n webhook template): - One line per alert: Status | Severity | Alert name — short description - Icon derived from severity (critical/warning/resolved); removes the old icon-heavy multi-line block - Every rule gains a `short` annotation for the headline Signal quality: - Remove NoLogsReceived (critical on 10m log-absence) — fired on healthy but idle services. Liveness now comes from pod state. - Remove log-grep HighAPI500ErrorRate (matched any "500" in logs) in favor of a metric-based 5xx-rate rule. - Promote PodNotReady to critical. New metric-based rules (infra-alert-rules.yaml): - ApiHigh5xxRate (crit), ApiHighLatency (warn, traffic-gated so idle never alerts), PVCUsageHigh/Critical (85/95%), PostgresUnavailable, RedisUnavailable. DB/Redis pod-name regexes verified against the live dev/test/prod cluster to match only the primary DB / Redis master and exclude crunchy backup jobs (which finish Completed/Error). New log-based stopgap rules (delivery/queue) until backend exposes metrics: CHES/ACS/SMS/webhook failures, queue job failures, queue-not- draining.
…f in dev Dev is deployed to constantly, so most alerts there are deploy churn (transient restarts, brief unavailability, redeploy log errors) rather than actionable incidents. Narrow every rule to f6bc3f-(test|prod). The sole exception is PodCrashLoopBackOff, which stays dev|test|prod — a crash-loop is a real breakage worth surfacing even mid-deploy. Updated the SCOPE header comments in both rule files to document the new scoping and the single dev exception.
The Deploy Monitoring Stack pipeline installed Loki/Grafana but never provisioned the alert rules or dashboards — those were applied by hand (monitoring/deploy-dashboards-alerts.sh) and drifted from git. Notably: - loki/values-tools.yaml mounts a `loki-alert-rules` ConfigMap that nothing created, so the log-based rules never loaded; - grafana/infra-alert-rules.yaml (metric rules) had no deploy path at all. Wire both into deploy-monitoring.yml so git is the single source of truth: - Loki job: create the `loki-alert-rules` ConfigMap from loki/alert-rules.yaml before the helm install (populates the ruler mount), and restart Loki on redeploy so the ruler reloads. - Grafana job: create `cn-infra-alert-rules` (grafana_alert=1) from infra-alert-rules.yaml and one `cn-dashboard-*` (grafana_dashboard=1) per dashboards/*.json — the sidecar hot-loads both.
The notification wording (e.g. "🚨 Grafana Alert: No Logs Received") read as noisy and inconsistent. Switch the Grafana contactPoint message to plain text, one line per alert, no emoji: FIRING <SEVERITY> | <Alert name> | <detail> RESOLVED | <Alert name> | <detail> detail = the `short` annotation, falling back to `summary`. Note: if the downstream n8n webhook re-wraps this text (adds its own "🚨 Grafana Alert:" prefix), that wrapper must be removed in the n8n workflow too — the repo can only control what Grafana sends.
NikhilMM89
force-pushed
the
fix/grafana-alert-quality
branch
from
September 8, 2026 18:15
fb841e3 to
93822ab
Compare
NikhilMM89
force-pushed
the
fix/grafana-alert-quality
branch
from
September 10, 2026 05:05
2829c94 to
2decfc6
Compare
Fixes found after deploying rules to f6bc3f-tools and iterating on the
alert format with the team.
Prometheus scrape:
- Add fallback_scrape_protocol: PrometheusText0.0.4 to the
common-notify-app job. Prometheus 3.x rejected the backend
/api/metrics target (blank Content-Type), so the whole app scrape was
down and the API 5xx/latency rules read NoData. Now all 3 targets up.
Alert NoData storm:
- Set noDataState: OK and execErrState: OK on all 14 metric rules so a
transient no-data on Grafana restart no longer pages
(DatasourceNoData). Root cause of the storm was also two stale
duplicate rule ConfigMaps in-cluster (grafana-alert-rules,
grafana-infra-alert-rules) that pinned 8 rules to noDataState=NoData;
those were removed live and are not in git.
Message format (per updated ticket):
- Rework the contactPoint message to the ticket format with icons and
environment:
🔴 FIRING | CRITICAL | <env> | <Alert> — <detail>
🟠 FIRING | WARNING | <env> | <Alert> — <detail>
🟢 RESOLVED | <env> | <Alert> — <detail>
env is derived from .Labels.namespace (f6bc3f-dev→dev).
n8n forwarding:
- The 🚨/State/Severity:INFO wrapper is added by the n8n webhook node,
which rebuilds its own body instead of forwarding Grafana's message.
That node lives in n8n and has to be corrected there — it cannot be
applied from this repo, so nothing in this change addresses it.
NikhilMM89
force-pushed
the
fix/grafana-alert-quality
branch
from
September 10, 2026 05:14
2decfc6 to
e7dc0ce
Compare
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.
Description
Reworks Grafana/Loki alerting to cut false-positive noise, make notifications scannable, and scope alerts to the environments that matter. Addresses the alerting ticket (Grafana alerts were hard to triage — e.g. critical fired when a healthy-but-idle service produced no logs for 10 min).
What changed
Notification message format (n8n webhook template —
values-tools-sso.yaml)🔴 FIRING | CRITICAL | Notify: <alert> — <short>🟠 FIRING | WARNING | Notify: <alert> — <short>🟢 RESOLVED | Notify: <alert> — <short>severity(no per-alert icons); removed the old icon-heavy multi-line block.shortannotation for the one-line headline.Signal quality
NoLogsReceived(critical on 10-min log absence) — fired on healthy but idle services. Liveness now comes from pod state.HighAPI500ErrorRate(matched any "500" in a log line) in favor of an accurate metric-based 5xx rule.PodNotReadyto critical.New metric-based rules (
infra-alert-rules.yaml)ApiHigh5xxRate(crit),ApiHighLatency(warn, traffic-gated so idle never alerts),PVCUsageHigh/Critical(85/95%),PostgresUnavailable,RedisUnavailable.repo1-full/repo1-incr/repo-host) which finishCompleted/Errorand would otherwise fire a permanent false-positive. Also confirmedkube_pod_status_readyis present in the tools Prometheus.New log-based stopgap rules (
common-notify-delivery)CHES / ACS / SMS / webhook failures, queue job failures, queue-not-draining. These providers/queues expose no Prometheus metrics today, so thresholds are log-line rates — flagged inline for follow-up backend instrumentation.
Environment scoping
PodCrashLoopBackOffstays dev+test+prod (a crash-loop is a real breakage even mid-deploy).Testing
yaml.safe_load_all).kube_pod_status_readymetric verified against live Prometheus inf6bc3f-toolsacross dev/test/prod.Notes / follow-ups
🤖 Generated with Claude Code
Thanks for the PR!
Deployments, as required, will be available below:
Please create PRs in draft mode. Mark as ready to enable:
After merge, new images are deployed in: