协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
devops-incident-response【开发与工程】Use this skill when the user says 'incident response', 'on-call', 'PagerDuty', 'OpsGenie', 'incident management', 'postmortem', 'runbook', 'severity', 'escalation', 'SEV', 'incident command', 'SEV1', 'SEV2', 'incident timeline'. This skill enforces: severity classification with clear definitions (SEV1-4), structured incident lifecycle from detection …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Establish a structured incident response framework with clear severity levels, defined roles, documented runbooks, and a blameless postmortem culture to minimize recovery time and prevent recurrence.
"incident response", "on-call", "PagerDuty", "OpsGenie", "incident management", "postmortem", "runbook", "severity", "escalation", "SEV", "SEV1", "SEV2", "SEV3", "incident command", "IC role", "incident timeline", "blameless postmortem", "incident lifecycle", "incident detection", "incident mitigation", "MTTD", "MTTR".
Incident response framework with severity matrix, lifecycle workflow, runbook template, on-call schedule, and postmortem process. For active incidents: structured timeline with IC assignments, action items, and communication updates.
Incident: {ID or name}
Severity: {SEV1-4}
Status: {detected/investigating/mitigated/resolved}
IC: {name}
Scribe: {name}
Timeline:
T+0: Detection [{method}]
T+{n}: Investigation [{current status}]
T+{n}: Mitigation [{action}]
T+{n}: Resolution [{target}]
Action Items: [{n} open, {n} completed]
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
500 lines
| Severity | Definition | Response Time | Escalation | Page |
|---|---|---|---|---|
| SEV1 | Complete outage, data loss, security breach, SLA-impacting | 5 min | Full team + management + exec | PagerDuty high-urgency |
| SEV2 | Major feature degraded, partial outage, >5% errors | 15 min | Primary + secondary on-call | PagerDuty high-urgency |
| SEV3 | Minor feature issue, single-user impact, non-critical bug | 1 business hour | Slack + ticket | PagerDuty low-urgency |
| SEV4 | Cosmetic, docs, enhancement, tech debt | Next sprint | Ticket queue | None |
IC (Incident Commander): owns incident end-to-end, delegates tasks, communicates with stakeholders, does NOT debug. Scribe: real-time timeline documentation — every action, decision, timestamp. SME: technical investigation and mitigation — one per subsystem, reports to IC. Comms: stakeholder status updates, status page updates, external notifications, regulatory reporting if needed. Role transitions: handoff documented in timeline with verbal 2-min summary.
Primary on-call: first responder, acknowledges within SLA. Secondary: backup for overflow and deep investigation. Escalation path: primary -> secondary -> engineering manager -> VP. Tools: PagerDuty/OpsGenie for schedules, alert routing, escalation policies, incident tracking. Rotation: weekly shifts, max 7 consecutive days. Follow-the-sun for global teams. Handoff: Friday overlap, written summary of ongoing issues.
MTTD (Mean Time to Detect): time from incident start to first alert. Target: SEV1 <5min, SEV2 <15min. MTTR (Mean Time to Resolve): time from detection to resolution. Target: SEV1 <1hr, SEV2 <4hrs. Track weekly trends, set improvement targets. Metrics drive investment in detection tooling, runbook quality, and on-call training.
Detection sources: monitoring alerts (Prometheus AlertManager, Datadog, CloudWatch), synthetic checks (Playwright/Cypress browser tests, uptime monitors), user reports (support tickets via Zendesk/Intercom, social media mentions), security scanning (Snyk, Trivy, WAF alerts), automated rollback triggers (deploy health check failure, error rate threshold). Validate alert is not a false positive before declaring incident.
Validate alert, classify severity using matrix, assign IC, open dedicated incident channel in Slack/Teams. Initial stakeholder notification via PagerDuty status update. Decision: severity upgrade/downgrade. If outside on-call expertise, escalate immediately without attempting deep investigation.
IC delegates investigation to SMEs. Check dashboards (Grafana, Datadog), logs (Loki, ELK, Cloud Logging), traces (Jaeger, Zipkin). Identify blast radius: users affected, services impacted, regions involved. Reproduce in staging or isolated environment. Scribe records every action with precise timestamp.
Stop the bleed first: feature flag toggle, rollback to last known good, reroute traffic to healthy region, scale up, block malicious IPs. Deploy permanent fix to non-production first, test, then deploy to production with canary. Communicate ETA to stakeholders via Comms at defined cadence. Scribe documents all mitigation steps and outcomes.
Verify metrics return to baseline (p99 latency, error rate, throughput). Run end-to-end validation tests. Post resolution to incident channel. Update status page. Schedule postmortem within SLA window. Archive incident channel. Send post-incident summary to stakeholders.
Schedule postmortem meeting: SEV1 within 48h, SEV2 within 1 week, SEV3 in next sprint. Write blameless timeline. Conduct 5 Whys root cause analysis. Create action items with single owner and due date. Share postmortem internally — every incident is a learning opportunity. Track action items to completion.
# Runbook: [Service Name]
## Symptoms
- Alert: [Alert name] firing — [description]
- User impact: [what users experience]
- Error messages: [relevant error patterns]
## Triage (First 5 Minutes)
1. Check [dashboard link] for current state
2. Run: `kubectl get pods -n [namespace] -o wide`
3. Check logs: `kubectl logs -n [namespace] [pod] --tail=100`
4. Check metric: [query in Prometheus/Grafana]
## Escalation
| Condition | Action |
|-----------|--------|
| Pods crash-looping | Page secondary on-call |
| Data inconsistency | Page DBA team |
| Security concern | Page security team |
## Remediation
### Option A: Rollback
```bash
kubectl rollout undo deployment/[name] -n [namespace]
kubectl scale deployment/[name] --replicas=5 -n [namespace]
Disable feature [name] via [flag management tool]
## Postmortem Template
```markdown
# Postmortem: [Title]
## Incident Summary
- Date: YYYY-MM-DD
- Duration: [start] to [end] (X hours)
- Severity: SEV[X]
- Services affected: [list]
## Timeline
| Time (UTC) | Event |
|---|---|
| T+0 | [Detection] |
| T+X | [Action taken] |
| T+Y | [Mitigation applied] |
| T+Z | [Resolution confirmed] |
## Impact
- Users affected: [count or percentage]
- Revenue impact: [amount if measurable]
- Data loss: [yes/no, extent]
## Root Cause (5 Whys)
1. Why did it happen? [answer]
2. Why? [deeper answer]
3. Why? [deeper answer]
4. Why? [deeper answer]
5. Why? [root cause]
## Contributing Factors
- [Factor 1]: [explanation]
- [Factor 2]: [explanation]
## Action Items
| # | Action | Owner | Due Date | Status |
|---|---|---|---|---|
| 1 | [action] | [name] | YYYY-MM-DD | [open/closed] |
| 2 | [action] | [name] | YYYY-MM-DD | [open/closed] |
## Prevention
- [System change to prevent recurrence]
- [Monitoring gap identified and filled]
- [Runbook updated with new findings]
## Lessons Learned
- What went well: [1], [2], [3]
- What went wrong: [1], [2], [3]
- What to improve: [1], [2], [3]
resource "pagerduty_service" "critical" {
name = "Production Critical"
description = "SEV1/SEV2 production incidents"
alert_creation = "create_incidents"
}
resource "pagerduty_escalation_policy" "primary" {
name = "Primary On-Call"
rule {
escalation_delay_in_minutes = 10
target {
type = "schedule_reference"
id = pagerduty_schedule.primary.id
}
}
rule {
escalation_delay_in_minutes = 15
target {
type = "schedule_reference"
id = pagerduty_schedule.secondary.id
}
}
rule {
escalation_delay_in_minutes = 5
target {
type = "user_reference"
id = pagerduty_user.manager.id
}
}
}
resource "pagerduty_schedule" "primary" {
name = "Primary Weekday"
time_zone = "UTC"
layer {
name = "Weekly Rotation"
start = "2026-01-05T08:00:00Z"
rotation_virtual_start = "2026-01-05T08:00:00Z"
rotation_turn_length_seconds = 604800
users = [for u in pagerduty_user.oncall : u.id]
}
}
:rotating_light: *INCIDENT DECLARED* :rotating_light:
*Incident ID*: INC-{date}-{number}
*Severity*: SEV{1-4}
*Service*: {service name}
*Detected*: {time} via {method}
*IC*: @{name}
*Scribe*: @{name}
*Status*: Investigating / Mitigating / Resolved
*Current Impact*: {description}
*Timeline*: https://link.to/timeline
*Runbook*: https://link.to/runbook
Next update: {time}
#inc-{date}-{severity}#inc-{id}-debug# Tabletop Exercise: [Scenario]
## Scenario
[Description of incident scenario, e.g., "Database primary fails, read replicas are 5 min behind"]
## Participants
- IC: [name]
- Scribe: [name]
- SME: [name]
- Comms: [name]
- Observer: [name]
## Timeline (Facilitator)
| Time | Event | Expected Response |
|---|---|---|
| T+0 | Alert fires: database connection pool exhausted | IC declares incident |
| T+5 | Pagers fire | On-call acknowledges |
| T+10 | [New info] | Team investigates |
| T+20 | [Escalation needed] | IC escalates |
| T+30 | [Mitigation option] | Team decides action |
## Debrief
- What went well:
- Gaps identified:
- Runbook updates needed:
- Training needs:
# Initial
We are investigating reports of [issue] affecting [service]. Users may experience [symptom]. We will provide updates every [cadence].
# Investigating
We have identified the issue as [root cause] and are working on mitigation. [Progress update].
# Monitoring
[Fix] has been deployed. We are monitoring metrics closely for the next [time period].
# Resolved
The issue has been resolved. [Service] is operating normally. A postmortem will be published within [timeline].
| Feature | PagerDuty | OpsGenie | incident.io | Grafana OnCall |
|---|---|---|---|---|
| Alert routing | Yes (intelligent) | Yes (team-based) | Yes | Yes |
| On-call scheduling | Yes (advanced) | Yes | Yes | Yes |
| Incident tracking | Via integrations | Yes (built-in) | Yes (native) | Yes (native) |
| Status page | Via integrations | Via integrations | Built-in | Via Grafana |
| Postmortem tool | No (add-on) | No | Built-in | No |
| War room | No (Slack add-on) | No | Yes (Slack-native) | No |
| Runbook automation | Yes (via Actions) | Yes (via Rules) | Yes (via Playbooks) | Yes (via webhooks) |
| Pricing | $$ | $ | $$ | Free (OSS) |
| Best for | Large orgs, complex routing | Mid-size, Atlassian stack | Modern incident platform | Grafana ecosystem |
| Severity | Definition | Examples | Response |
|---|---|---|---|
| SEV1-SEC | Active breach, data exfiltration, ransomware | Unauthorized access, crypto mining, CVE exploitation | Full security team + legal + exec within 5 min |
| SEV2-SEC | Vulnerability with exploitation evidence | XSS found in production, exposed secrets | Security team within 15 min |
| SEV3-SEC | Vulnerability without exploitation | Dependency CVE, misconfigured S3 bucket | Patch within SLA (72h) |
| SEV4-SEC | Best practice gap | Over-permissioned IAM role, missing WAF rule | Next sprint |
# runbook_automation/auto_responder.py
"""Automated incident response actions."""
import boto3
import requests
import json
from datetime import datetime
class IncidentAutoResponder:
def __init__(self, pagerduty_token, slack_webhook):
self.pd_token = pagerduty_token
self.slack_webhook = slack_webhook
def create_pagerduty_incident(self, title, severity, service_id, escalation_policy_id):
headers = {
"Authorization": f"Token token={self.pd_token}",
"Content-Type": "application/json",
}
payload = {
"incident": {
"type": "incident",
"title": title,
"service": {"id": service_id, "type": "service_reference"},
"escalation_policy": {"id": escalation_policy_id, "type": "escalation_policy_reference"},
"urgency": "high" if severity in ("SEV1", "SEV2") else "low",
"body": {
"type": "incident_body",
"details": f"Auto-created by {self.__class__.__name__} at {datetime.utcnow().isoformat()}",
},
}
}
resp = requests.post(
"https://api.pagerduty.com/incidents",
headers=headers,
json=payload,
)
resp.raise_for_status()
return resp.json()["incident"]
def notify_slack_channel(self, channel, message):
payload = {"channel": channel, "text": message, "mrkdwn": True}
resp = requests.post(self.slack_webhook, json=payload)
resp.raise_for_status()
def stop_unhealthy_deployment(self, namespace, deployment):
"""Auto-rollback deployment if health check fails."""
# This would use kubernetes client in practice
print(f"[{datetime.utcnow().isoformat()}] Rolling back {namespace}/{deployment}")
def tag_instance_for_forensics(self, instance_id):
"""Tag EC2 instance for forensic preservation."""
ec2 = boto3.client("ec2")
ec2.create_tags(
Resources=[instance_id],
Tags=[{"Key": "IncidentForensics", "Value": "Preserve"},
{"Key": "PreservedAt", "Value": datetime.utcnow().isoformat()}],
)
# metrics/collect_incident_metrics.py
"""Collect and report incident response metrics."""
from datetime import datetime, timedelta
def calculate_mttd(detection_time, incident_start_time):
"""Mean Time to Detect in minutes."""
delta = detection_time - incident_start_time
return delta.total_seconds() / 60
def calculate_mttr(resolution_time, detection_time):
"""Mean Time to Resolve in minutes."""
delta = resolution_time - detection_time
return delta.total_seconds() / 60
def track_weekly_metrics(incidents):
"""Aggregate incident metrics for weekly review."""
total = len(incidents)
if total == 0:
return {"total": 0, "avg_mttd": 0, "avg_mttr": 0, "by_severity": {}}
avg_mttd = sum(i["mttd_min"] for i in incidents) / total
avg_mttr = sum(i["mttr_min"] for i in incidents) / total
by_severity = {}
for incident in incidents:
sev = incident["severity"]
if sev not in by_severity:
by_severity[sev] = {"count": 0, "total_mttr": 0}
by_severity[sev]["count"] += 1
by_severity[sev]["total_mttr"] += incident["mttr_min"]
for sev in by_severity:
count = by_severity[sev]["count"]
by_severity[sev]["avg_mttr"] = by_severity[sev]["total_mttr"] / count
return {
"total": total,
"avg_mttd_min": round(avg_mttd, 1),
"avg_mttr_min": round(avg_mttr, 1),
"by_severity": by_severity,
}
dev-loop/tech-debt-tracker for action items from postmortem
planning/create-roadmap for incident-driven roadmap changes