Observability & SLOs
Design SLIs, SLOs and multi-window burn-rate alerts, write and review PromQL, and audit noisy alerting.
3 skillsMITCódigo-fonte
Instalar
/plugin install observability@pieroazambujaAinda não adicionou o marketplace? Rode antes /plugin marketplace add piazambuja/piazambuja.github.io.
npx skills add piazambuja/piazambuja.github.io --skill alert-review promql slo-design -a codexInstala as 3 skills deste plugin no projeto. Acrescente -g para todos os projetos.
npx skills add piazambuja/piazambuja.github.io --skill alert-review promql slo-design -a gemini-cliInstala as 3 skills deste plugin no projeto. Acrescente -g para todos os projetos.
npx skills add piazambuja/piazambuja.github.io --skill alert-review promql slo-design -a github-copilotInstala as 3 skills deste plugin no projeto. Acrescente -g para todos os projetos.
npx skills add piazambuja/piazambuja.github.io --skill alert-review promql slo-design -a cursorInstala as 3 skills deste plugin no projeto. Acrescente -g para todos os projetos.
npx skills add piazambuja/piazambuja.github.io --skill alert-review promql slo-design -a kiro-cliInstala as 3 skills deste plugin no projeto. Acrescente -g para todos os projetos.
Skills
O agente carrega uma skill quando o pedido combina com a descrição dela. No Claude Code, você também pode chamar direto com /observability:<skill>. Abra cada uma para ler as instruções completas.
alert-review Audit an alerting setup (Prometheus rules, Alertmanager, Grafana, Datadog or CloudWatch alarms) for noise, missing coverage and missing runbooks. Use when on-call is noisy, alerts are ignored, or the user asks to review their alerts.
Alert review
Goal: every page is urgent, actionable and needs a human. Everything else is a ticket, a dashboard or deleted.
Inputs
Read the alert definitions in the repo. If available, also get firing history (Alertmanager/PagerDuty/Opsgenie export) for the last 30 days. Without history, review definitions only and say so.
For each alert, decide
| Question | If "no" |
|---|---|
| Does it describe user-facing impact or imminent impact? | Downgrade to ticket or remove |
| Is there a clear action for the responder? | Add a runbook or remove |
| Did it fire and lead to action in the last 30 days? | Candidate for removal |
Does it have for: long enough to skip blips? | Add for: |
| Is the threshold based on data, not a guess? | Re-derive from history |
| Does it duplicate another alert for the same cause? | Merge or add inhibition |
Symptom alerts (error rate, latency, SLO burn) should page. Cause alerts (CPU high, pod restarted, disk 80%) usually should not, except saturation that will cause an outage soon (disk full in < 4h via predict_linear).
Alertmanager hygiene
- Grouping by
alertname, cluster, namespace/serviceso one incident is one notification. - Inhibition: cluster or node down inhibits the per-pod alerts below it.
- Routing: severity
pageto the on-call tool,ticketto a channel or queue, never both. - Every alert has
summary,descriptionwith the values,runbook_urland an owner label.
Output
- Summary numbers: total alerts, pages, proposed removals/downgrades.
- A table: alert, current severity, verdict (keep / tune / downgrade / delete / merge), reason.
- Missing coverage: user journeys with no symptom alert.
- Patches for the changes.
promql Write, explain and fix PromQL queries and recording rules, and review them for correctness and cardinality. Use when the user asks for a Prometheus/Grafana/Mimir/Thanos query or a query gives unexpected results.
PromQL helper
Writing queries
- Find the metric type first. Counters (
_total) always go throughrate()/increase(); neversum()a raw counter. rate()beforesum():sum by (svc) (rate(x_total[5m])), neverrate(sum(x_total)[5m]).- The range should be at least 4× the scrape interval (with 30s scrapes, use
[2m]or more). - Percentiles from histograms keep the
lelabel:
histogram_quantile(0.99, sum by (le, route) (rate(http_request_duration_seconds_bucket[5m])))
Native histograms: histogram_quantile(0.99, sum by (route) (rate(http_request_duration_seconds[5m]))).
- Ratios: aggregate numerator and denominator with the same
byclause. - Joins: use
on()/ignoring()withgroup_leftto pull labels from info metrics likekube_pod_info. - Absent data:
absent()orabsent_over_time()for "is the target dead" alerts.
Review checklist
- Counter used without
rate? Gauge used withrate? - Aggregation drops a label the alert or dashboard needs?
histogram_quantilewithoutlein theby? Averaging percentiles across instances (wrong)?- Regex matchers on high-cardinality labels in hot dashboards?
- Range too short for the scrape interval?
- Should this be a recording rule (used in several panels/alerts, or expensive)?
Cardinality
When the user suspects a cardinality problem:
topk(10, count by (__name__) ({__name__=~".+"}))
topk(10, count by (le) (http_request_duration_seconds_bucket))
Look for labels carrying user ids, full URLs, request ids or timestamps. Recommend dropping them with metric_relabel_configs or fixing the instrumentation.
Always explain what the final query returns in one sentence, including the unit.
slo-design Define SLIs and SLOs for a service and generate multi-window, multi-burn-rate alerts (Prometheus rules). Use when the user wants to create or review SLOs, error budgets, or replace threshold alerts with SLO-based alerting.
SLO design
1. Start from the user journey
Ask (or infer from the code/config) what the service's users actually do: e.g. "authorize a payment", "load the statement page". Pick 1–3 journeys. An SLO per journey beats an SLO per microservice.
2. Choose SLIs
Express every SLI as good events / valid events:
| Type | Good event | Typical source |
|---|---|---|
| Availability | request not answered with 5xx (and not timed out) | ingress/ALB, service mesh, app metrics |
| Latency | request served under a threshold, e.g. 300 ms | histogram buckets |
| Freshness | data updated within N minutes | pipeline timestamps |
| Correctness | output matches expectation | probes / reconciliation jobs |
Measure as close to the user as possible (load balancer or mesh beats app-internal). Exclude 4xx from "bad" unless the service caused them.
3. Set the objective
- Base it on what users tolerate and on historical performance, not on "five nines".
- Window: 28 or 30 days rolling.
- Error budget = 1 − SLO. At 99.9% over 30 days that is ~43 minutes of full outage.
- Write down the error-budget policy: what happens when it is spent (feature freeze, reliability work prioritised).
4. Alerts: multi-window, multi-burn-rate
Use the standard pairs (for a 30-day window):
| Severity | Burn rate | Long window | Short window | Budget consumed |
|---|---|---|---|---|
| page | 14.4 | 1h | 5m | 2% |
| page | 6 | 6h | 30m | 5% |
| ticket | 3 | 1d | 2h | 10% |
| ticket | 1 | 3d | 6h | 10% |
Template (availability, SLO 99.9%):
groups:
- name: slo-checkout
rules:
- record: slo:sli_error:ratio_rate5m
expr: |
sum(rate(http_requests_total{job="checkout",code=~"5.."}[5m]))
/ sum(rate(http_requests_total{job="checkout"}[5m]))
# repeat the recording rule for 30m, 1h, 2h, 6h, 1d, 3d
- alert: CheckoutErrorBudgetBurnFast
expr: |
slo:sli_error:ratio_rate1h > (14.4 * 0.001)
and slo:sli_error:ratio_rate5m > (14.4 * 0.001)
labels: {severity: page}
annotations:
summary: "Checkout is burning its error budget 14x too fast"
runbook_url: "<link>"
If the stack uses Sloth or Pyrra, generate their spec instead of raw rules.
5. Output
Deliver: the journeys, SLI definitions with the exact query, the objective and its justification, the alert rules, and a dashboard outline (SLI over time, budget remaining, burn rate). Point out SLIs that can't be measured yet and what instrumentation is missing.