signoz-investigating-alerts
Skill8 starsChanged 2 months agoMITView on GitHub
Diagnose why a SigNoz alert fired by correlating the alert's own signal with neighbor signals (error rate, latency, throughput, CPU/memory), traces, and logs around the fire window, and rank likely causes. Use whenever the user asks "why did this alert fire", "what caused alert X", "investigate this alert", "RCA for the alert that paged me", "what's wrong with [service]" in the context of a recent fire, or otherwise asks for a root-cause analysis of a firing or recently-fired alert. Read-only; does not modify any alert or notification.
We split this skill into the rules it gives an agent
20 rules. About 0 are common, 12 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈12
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 33
Use when the user wants to:
- Distinctive: line 39
Do NOT use when the user wants to:
- Very specific: line 41
Create a new alert → signoz-creating-alerts.
- Very specific: line 44
Run a free-form investigation with no alert anchor → signoz-generating-queries.
- Very specific: line 55
Call signoz_list_alert_rules, paginate, fuzzy-match the name.
- Distinctive: line 60
If no firing transition exists in the queried lookback, stop — there is nothing to investigate.
- Very specific: line 77
Call signoz_get_alert for the full rule config (query, threshold, resource scope the alert evaluated).
- Very specific: line 79
Call signoz_get_alert_history with timeRange: "7d", order: "desc", and state omitted so the timeline includes firing and inactive …
- Distinctive: line 105
Never infer flapping from different fingerprints.
- Distinctive: line 134
Early-stop gate: if breach magnitude < 10% over threshold AND fire duration < 1 evaluation window, classify as "marginal fire" (alert may …
- Distinctive: line 157
Early-stop gate: if no neighbor signal shows ≥ 25% deviation from baseline, classify as "isolated fire: the alert's own signal moved but …
- Very specific: line 174
Logs: call signoz_search_logs with <scope_filter> AND severity_text IN ('ERROR', 'FATAL'), cap at top 20 most recent.
- Distinctive: line 178
Cross-reference: do the traces and logs point at the same downstream service, dependency, or code path?
- Distinctive: line 187
Use this exact section order.
- Distinctive: line 198
If no hypothesis reaches medium confidence, lead with "No clear root cause found." rather than a dressed-up low-confidence guess.
- Very specific: line 225
If only Tier 1 ran (marginal / no neighbor anomalies), output fewer hypotheses at low confidence and call out the limitation.
- Distinctive: line 242
No generic filler ("verify connectivity", "check dashboards").
- Distinctive: line 268
Correlation ≠ causation: only call something a cause with ≥2 converging signals (see Confidence in Step 5).
- Distinctive: line 270
Report uncertainty honestly: if nothing reaches medium confidence, the answer is "No clear root cause found" — false positives waste …
- Very specific: line 278
Read-only: never call signoz_update_alert.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Alert Investigate
Diagnose why a SigNoz alert fired: correlate the alert's own signal with
neighbor signals around the fire window and surface a ranked list of likely
causes with evidence. Companion to signoz-explaining-alerts (explain
decodes the rule statically; investigate diagnoses a specific incident).
Prerequisites
Needs SigNoz MCP tools (signoz_get_alert, signoz_get_alert_history,
signoz_execute_builder_query, signoz_query_metrics,
signoz_search_traces, signoz_search_logs, signoz_get_trace_details,
etc.). Confirm signoz_* tools are available before starting; if not, run
signoz-mcp-setup to initialize/repair the MCP connection. Without the
server there is no way to ground the analysis.
When to use
Use when the user wants to:
- Understand why a specific alert fired.
- Find the root cause of a recent incident triggered by an alert.
- Correlate the alert's signal with related metrics, traces, and logs.
- Distinguish "real signal" fires from flapping or threshold-mistuning.
Do NOT use when the user wants to:
- Understand what an alert monitors →
signoz-explaining-alerts. - Create a new alert →
signoz-creating-alerts. - Modify an alert (raise threshold, add hysteresis) → call
signoz_update_alertdirectly. - Run a free-form investigation with no alert anchor →
signoz-generating-queries.
Required inputs
| Input | Required | Source if missing |
| Alert identifier (rule ID or name) | yes | $ARGUMENTS[0] or recent context |
| Time window | no | default to most recent fire from signoz_get_alert_history |
Fuzzy alert name (best-effort, read-only):
- Call
signoz_list_alert_rules, paginate, fuzzy-match the name. - State the interpretation ("Investigating fire of 'High Error Rate - Checkout' (id 42) at 14:32 UTC. If you meant a different alert or fire, tell me.") and proceed.
If no firing transition exists in the queried lookback, stop — there is nothing to investigate. Respond:
"Alert '[name]' has not fired in the last 7d, so there is no fire window to investigate. Use
signoz-explaining-alertsto walk through the rule, or check whether the alert is enabled."
Workflow
Three tiers with strict early-stop gates. Tier 1 always runs; Tier 2 runs only if Tier 1 confirms a real fire; Tier 3 runs only if Tier 2 surfaces correlated anomalies. Skipping the gates fires hundreds of unnecessary trace/log queries on quiet alerts.
Step 1: Resolve alert + fire window (Tier 0)
- Resolve the alert id via
signoz_list_alert_rules(paginated) if not given. - Call
signoz_get_alertfor the full rule config (query, threshold, resource scope the alert evaluated). - Call
signoz_get_alert_historywithtimeRange: "7d",order: "desc", andstateomitted so the timeline includes firing and inactive transitions. Paginate only whendata.nextCursorexists (completeness note reportshasMore: true): pass it ascursor, replacetimeRangewith the note's resolved absolutestart/end, and preserve the same state/filter (including omission) and order. Stop whennextCursoris absent /hasMore: false; never useoffsetor page fullness. If a later intentional filter means "resolved"/"recovered", useinactive. Enum:inactive|pending|recovering|firing|nodata|disabled;recoveringis a transient keep-firing state, not resolution. Pattern analysis needs the complete transition set. Rows are emitted per label-groupfingerprint; do not interleave them. From the response:- Build rule-wide incident windows from distinct rows where
overallStateChanged: true:overallState: "firing"opens an incident; the nextoverallState: "inactive"closes it. Deduplicate matching timestamps and sort byunixMilliascending before pairing. Default to the most recent incident unless$ARGUMENTS[1]selects another. - Partition affected series by
fingerprintand retain each row's labels. Use onlystateChanged: truerows to decide when that group fired/resolved and which group scopes Tier 1–3 queries. - Note the fire pattern from rule-wide transitions or one named
fingerprint:
one-off→ single fire with a long quiet period before/after.sustained→ fires that stayed firing for ≥ 1 evaluation cycle.flapping→ ≥ 3 fires within a 1h window, alternating fire/resolve.recurring→ fires at regular intervals (cron-like, e.g. hourly).
- Never infer flapping from different fingerprints. The pattern guides tiers 2/3.
- Build rule-wide incident windows from distinct rows where
Step 2: Tier 1 — what fired and how hard (always runs)
Establishes the fire is real (vs. transient threshold tickle or flap) and quantifies magnitude.
- Re-run the alert's primary query over
[fire_start - 30m, fire_start + 30m]viasignoz_execute_builder_queryfor the alert's stored builder, formula, PromQL, or ClickHouse envelope. Preserve positive bounds/order so Tier 1 reproduces the stored alert. If a formula input is below 10000, record truncation risk and compare at 10000 before ruling groups out. For omissions, use 10000 on formula-inputbuilder_queryleaves and 100 on standalone/formula results. Find leaves from every formula expression (includingdisabled: trueformulas), following references through the dependency graph. This walk sets comparison bounds only; it does not prove deterministic formula-to-formula order. Use v5order:__result descfor metrics/formulas or primary aggregation desc for logs/traces, never dashboardorderBy. Time-series top-N ranks over the whole window and may omit a short-lived local spike. - Compute:
- Peak value during the fire window.
- Threshold breach magnitude:
(peak - threshold) / threshold * 100for "above" alerts, inverted for "below". - Fire duration: the rule's overall firing→inactive interval, or the selected fingerprint's interval for a group-scoped investigation. Say which.
- Pre-fire baseline: average in the 30m before fire start.
- Early-stop gate: if breach magnitude < 10% over threshold AND fire duration < 1 evaluation window, classify as "marginal fire" (alert may be too sensitive). Skip tiers 2/3 and go to Step 5 with a single hypothesis: "threshold may be too tight, recommend tuning."
Step 3: Tier 2 — neighbor signals vs baseline (only if Tier 1 confirms a real breach)
Pull related signals for the alert's resource scope and compare fire window to a baseline window.
- Pick a baseline window: same hour, previous day (
fire_start - 24h, fire_start - 24h + fire_duration). If the alert fired during a known-anomalous time (deploy, weekly job), note it but still proceed. - Look up neighbor signals for the alert's resource type — see
references/neighbor-signals.md. Common cases:- Service (
service.name = X): error rate, p95/p99 latency, request throughput, dependency error rates (if trace data available). - Host / VM (
host.name = X): CPU, memory, disk I/O, network I/O. - K8s pod / namespace: pod restarts, container CPU/memory limits, node pressure, recent rollouts.
- Service (
- For each neighbor signal: query both windows via
signoz_execute_builder_queryorsignoz_query_metrics, compute the delta (% change fire vs baseline), rank by absolute delta. - Early-stop gate: if no neighbor signal shows ≥ 25% deviation from baseline, classify as "isolated fire: the alert's own signal moved but nothing else did" (unusual, worth surfacing). Skip Tier 3 and go to Step 5 with hypotheses focused on the alert's own query (likely causes: data source change, instrumentation change, downstream silent failure that only shows in this metric).
Step 4: Tier 3 — traces and logs at the fire window (only if Tier 2 found correlated anomalies)
- Traces (if service-scoped and traces available): call
signoz_search_tracesfor the fire window withservice.name = <scope>ANDhas_error = true, cap at top 20. Group bynameandstatus_message; surface the sample's top 3 with one trace ID each (do not treat a 20-row sample count as full-window frequency). Optionally callsignoz_get_trace_detailsfor span attributes — pass the search row'strace_idastraceIdplus the same absolute fire-windowstartandend, else the 6h default misses older incidents. - Logs: call
signoz_search_logswith<scope_filter>ANDseverity_text IN ('ERROR', 'FATAL'), cap at top 20 most recent. Group bybodypattern (orexception.typeif present); surface the top 3 distinct messages with counts. - Cross-reference: do the traces and logs point at the same downstream service, dependency, or code path? If so, that becomes the leading hypothesis.
See references/baseline-comparison.md for query templates that pair
fire-window and baseline-window calls cleanly.
Step 5: Structured output
Use this exact section order. Lead with the TL;DR (engineers under pressure scan the top and stop once they have what they need). Every claim cites the MCP query that produced it; no generic "check logs / verify connectivity" filler.
1. TL;DR — one or two sentences max: leading hypothesis, overall confidence, blast radius, single most useful next action. Example:
"checkoutservice error rate hit 12.4% (threshold 5%) for 8m at 14:32 UTC; most likely cause is payments-api timing out (high confidence). Open trace
7af3a09b…to see the failing call."
If no hypothesis reaches medium confidence, lead with "No clear root cause found." rather than a dressed-up low-confidence guess.
2. What fired — alert (id, name), fire window (absolute UTC + relative),
peak magnitude ("error rate hit 12.4% vs. 5% threshold, 148% over"), fire
duration, fire pattern (one-off/sustained/flapping/recurring/
marginal).
3. Investigation trail — scannable list of what was checked, ✅ for confirmed and ❌ for ruled out, each with a one-line finding, e.g.:
- ✅ Tier 1: peak error rate 12.4%, fire was real (not marginal).
- ✅ Tier 2: payments error rate +8900%, p99 +1180%; downstream cascade.
- ❌ CPU / memory pressure: flat through the fire window.
- ✅ Tier 3: 30 error traces all hit payments-api, same message.
4. Likely causes (ranked, max 3) — each has:
- Hypothesis: one specific sentence. Bad: "service is unhealthy". Good: "checkout is timing out on calls to payments-api".
- Evidence: supporting numbers from tiers 1/2/3 with the underlying query inline (neighbor signal, delta vs baseline, trace/log pattern) so the user can re-run it.
- Confidence:
highrequires ≥2 of {temporal precedence, topology / dependency edge, shared service or entity, correlated metric/log/trace evidence, recent deploy or config change}.mediumis one tier's evidence with ≥1 of those.lowis a single signal with no corroboration — label it a "co-occurring signal," not a cause.
If only Tier 1 ran (marginal / no neighbor anomalies), output fewer
hypotheses at low confidence and call out the limitation.
5. Ruled out — short but explicit: candidates the evidence eliminated and the one-line reason. Skip only if there is nothing meaningful; if you considered and dropped something, say so here.
6. Suggested next steps — concrete, SigNoz-native handles the user can act on immediately:
- Specific trace/dashboard/alert to open ("open trace
7af3a09b…in the SigNoz UI"). - Specific query to run with
signoz-generating-queries: paste the exact filter and time window. - "Tune this alert" if marginal: name the field (
matchType,target,recoveryTarget) and the change to make viasignoz_update_alert. - "Open an incident" / "page the owning team" if the cause is cross-service.
No generic filler ("verify connectivity", "check dashboards").
Mirror up to 3 of these next steps as host follow-up intents: the most actionable, alert-scoped ones. Keep the rest in the report prose (the chip surface is capped; the prose is not).
Out of scope (v1)
- Deploy / config-change correlation: SigNoz MCP exposes no deployments tool; do not fabricate one. Surface a user-mentioned deploy as context, but don't claim it caused the fire without signal evidence.
- Cross-service blast-radius walking (downstream callers): out of scope to keep context bounded.
- Long-horizon historical baselines: Tier 2 compares to one prior-day
window, not weekly/monthly seasonality. If asked "is this normal for a
Friday afternoon", suggest an anomaly alert (
signoz-creating-alertswithanomaly_rule).
Guardrails
- Early-stop gates are mandatory, not optional optimizations — skipping them explodes context.
- Anchor every claim to a real MCP query result; no speculation, no fabricated identifiers (trace IDs, span names, rule IDs, channel/deploy IDs must all come from real responses). If evidence is missing, lower confidence and say so.
- Correlation ≠ causation: only call something a cause with ≥2 converging signals (see Confidence in Step 5); otherwise it's a "co-occurring signal."
- Report uncertainty honestly: if nothing reaches medium confidence, the answer is "No clear root cause found" — false positives waste incident time more than false negatives.
- Keep it a triage card, not a postmortem — every section must add evidence the reader can't already see in the alert payload; drop generic advice.
- Prefer resource-attribute filters in every drill-down query (SigNoz MCP guideline; directly affects query speed at scale).
- Read-only: never call
signoz_update_alert; surface tuning as a next-step recommendation. - State fire windows in UTC + relative ("14:32 UTC, 2h ago") so autonomous and interactive consumers agree on the window.
Example (full 3-tier run)
User: "Why did the checkout error rate alert fire?"
Agent:
- Resolves alert: "High Error Rate - Checkout" (id 42).
signoz_get_alert_history→ most recent fire 2h ago at 14:32 UTC, sustained 8m, single fire (not flapping).- Tier 1: re-runs error-rate formula over
[14:02, 15:02]. Peak 12.4% (vs 5% threshold, 148% over), pre-fire baseline 0.3%. Real fire. - Tier 2 (
service.name = checkout): p99 4.1s vs 320ms (+1180%); throughput −42%; downstreampaymentserror rate 18% vs 0.2% (+8900%); CPU/memory flat. - Tier 3: error traces top op
POST /checkout/submit, message "context deadline exceeded calling payments-api", 30 traces same downstream URL; matching "payments client timeout" logs, 142 occurrences. Output:
TL;DR: checkoutservice error rate hit 12.4% (threshold 5%) for 8m at 14:32 UTC. Most likely cause: payments-api timing out (high confidence; converging trace + log + neighbor evidence). Open trace
7af3a09b….- What fired: alert 42 fired 2h ago at 14:32 UTC, sustained 8m; error rate peaked 12.4% (148% over threshold).
- Investigation trail:
- ✅ Tier 1: peak 12.4% vs 5%, pre-fire baseline 0.3%. Real fire.
- ✅ Tier 2: payments error rate +8900%, p99 +1180%, throughput −42%.
- ❌ CPU / memory on checkout: flat.
- ✅ Tier 3: 30 error traces all hit payments-api with
context deadline exceeded; 142 matching timeout logs.
- Likely causes (high): payments errors cascading into checkout. Evidence converges across topology (checkout → payments edge), temporal precedence (payments errors lead checkout p99), shared entity (every error trace targets the payments-api URL).
- Ruled out: checkout-side resource pressure (CPU/memory flat); upstream traffic spike (throughput dropped, didn't spike).
- Next steps: open trace
7af3a09b…; if payments has its own alert, runsignoz-explaining-alertson it, elsesignoz-generating-queriesfor payments error rate over the last 4h.
Same structure applies to other patterns, differing only in where the tiers
stop. A flapping / marginal fire (e.g. CPU hovering 5% over an 80%
threshold, matchType = at_least_once) early-stops after Tier 1 → output is
a low-confidence "threshold tuning, not an incident" with a matchType →
on_average / recoveryTarget fix. A log-volume fire (no service
filter, groupBy service.name) resolves the firing series from history, then
runs all three tiers on that service (e.g. Tier 2 shows collapsed CPU/memory
- pod restarts, Tier 3 shows "OOMKilled restarting" logs → high-confidence OOM cause, check container memory limits).
Additional resources
references/neighbor-signals.md: resource type (service / host / k8s) → neighbor signals to pull in Tier 2.references/baseline-comparison.md: query templates pairing fire-window and baseline-window calls, includingsignoz_execute_builder_queryformat.signoz-explaining-alerts: decode the rule before investigating.signoz-generating-queries: ad-hoc follow-up queries on the same scope.
In this repository20 other files it gives its agents.
- autonomous-maintainerSkill
- commitSkill
- competitive-ads-extractorSkill
- compress-skillsSkill
- extract-design-systemSkill
- fix-ciSkill
- flesch-kincaid-proofreaderSkill
- frontendSkill
- get-pr-commentsSkill
- gogSkill
- grillingSkill
- grill-meSkill
- hairline-createSkill
- image-generationSkill
- posthogSkill
- shipSkill
- teachSkill
- thermo-nuclear-code-quality-reviewSkill
- update-agents-mdSkill
- visualizeSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

