incident-response について
incident-responseは、本番障害に対応するエンジニア向けのスキルです。初動の優先度判定から調査、緩和、事後分析までを、手順や連絡テンプレート、レポート用スクリプトで支援します。
主な機能
- 01重大度によるインシデント分類
- 025分間の初動トリアージ
- 03アプリケーションやサービスの障害調査
- 04対応と状況更新の調整
- 05事後分析とランブックの作成
活用シーン
- 01本番停止やエラー急増の初動対応
- 02サービス性能低下の調査
- 03デプロイ失敗後のロールバック調整
- 04根本原因とフォローアップの記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hieutrtr/ ai1-skills --skill incident-responseインストール後、Claude Code で/incident-responseを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/escalation-contacts.mdpost-mortem-template.mdscripts/fetch-logs.shgenerate-incident-report.pyhealth-check-all-services.sh詳細
インシデント対応
使用する場面
次のような場合に、このスキルを使用してください。
- 本番サービスが停止している、またはユーザーにエラーを返している
- エラー率が通常のしきい値を超えて急上昇している
- パフォーマンスが大幅に低下している(レイテンシの増加、タイムアウト)
- 監視システムからアラートが発報された
- システム全体に及ぶ問題を示すユーザーからの報告がある
- デプロイに失敗し、調査と修復が必要である
- インシデント発生後にポストモーテムまたは根本原因分析を実施する
出力: 手順書を docs/runbooks/<service>-runbook.md に、ポストモーテムを postmortem-YYYY-MM-DD.md に作成します。
次の場合、このスキルは使用しないでください。
- 監視ルールやアラートルールを設定する場合(
monitoring-setupを使用) - 定期的なデプロイを実施する場合(
deployment-pipelineを使用) - Docker イメージまたはインフラストラクチャに関する問題の場合(
docker-best-practicesを使用) - 機能開発またはコード変更の場合(
python-backend-expertまたはreact-frontend-expertを使用)
手順
重大度の分類
すべてのインシデントを直ちに分類してください。重大度によって、対応の緊急度、コミュニケーションの頻度、エスカレーション経路が決まります。
| 重大度 | 影響 | 例 | 対応時間 | 更新頻度 |
|---|---|---|---|---|
| SEV1 (P1) | 完全な停止、全ユーザーに影響 | サービス停止、データ損失、セキュリティ侵害 | 即時(< 5 分) | 15 分ごと |
| SEV2 (P2) | 重大な機能低下、大半のユーザーに影響 | 中核機能の停止、深刻なレイテンシ | < 15 分 | 30 分ごと |
| SEV3 (P3) | 部分的な機能低下、一部のユーザーに影響 | 重要度の低い機能の停止、断続的なエラー | < 1 時間 | 2 時間ごと |
| SEV4 (P4) | 軽微な問題、影響を受けるユーザーは少数 | 外観上のバグ、特殊なケースでのエラー | < 4 時間 | 毎日 |
エスカレーションルール:
- SEV1:オンコールエンジニアとエンジニアリングマネージャーに直ちにページングする
- SEV2:オンコールエンジニアにページングし、エンジニアリングマネージャーに通知する
- SEV3:Slack 経由でオンコールエンジニアに通知する
- SEV4:チケットを作成し、通常の勤務時間内に対応する
連絡先一覧については、references/escalation-contacts.md を参照してください。
5 分間のトリアージワークフロー
インシデントを検知したら、最初の 5 分以内に次のトリアージワークフローを実施してください。
┌─────────────────────────────────────────────────────────┐
│ MINUTE 0-1: Acknowledge and Classify │
│ • Acknowledge the alert or report │
│ • Assign severity (SEV1-SEV4) │
│ • Designate incident commander │
├─────────────────────────────────────────────────────────┤
│ MINUTE 1-2: Assess Scope │
│ • Check health endpoints for all services │
│ • Check error rate and latency dashboards │
│ • Determine: which services are affected? │
├─────────────────────────────────────────────────────────┤
│ MINUTE 2-3: Identify Recent Changes │
│ • Check: was there a recent deployment? │
│ • Check: any infrastructure changes? │
│ • Check: any external dependency issues? │
├─────────────────────────────────────────────────────────┤
│ MINUTE 3-4: Initial Communication │
│ • Post in #incidents channel │
│ • Update status page if SEV1/SEV2 │
│ • Page additional responders if needed │
├─────────────────────────────────────────────────────────┤
│ MINUTE 4-5: Begin Investigation or Mitigate │
│ • If recent deploy: consider immediate rollback │
│ • If not deploy-related: begin diagnostic commands │
│ • Start incident timeline log │
└─────────────────────────────────────────────────────────┘
クイックヘルスチェックコマンド:
./skills/incident-response/scripts/health-check-all-services.sh \
--output-dir ./incident-triage/
インシデントコマンダーの役割
インシデントコマンダー(IC)は対応を調整します。IC は直接調査を行いません。
IC の責務:
- 調整 -- 対応者にタスクを割り当て、作業の重複を防ぐ
- コミュニケーション -- 関係者に定期的に状況を共有する
- 判断 -- ロールバック、エスカレーション、コミュニケーションについて、実行可否を判断する
- 記録 -- インシデントのタイムラインを管理する
- 終了 -- インシデントの解決を宣言し、ポストモーテムを予定する
IC のコミュニケーションテンプレート(初回):
INCIDENT DECLARED: [Title]
Severity: [SEV1/SEV2/SEV3/SEV4]
Commander: [Name]
Start time: [UTC timestamp]
Impact: [What users are experiencing]
Status: Investigating
Next update: [Time]
IC のコミュニケーションテンプレート(更新):
INCIDENT UPDATE: [Title]
Severity: [SEV level]
Duration: [Time since start]
Status: [Investigating/Identified/Mitigating/Resolved]
Current findings: [What we know]
Actions in progress: [What we are doing]
Next update: [Time]
調査手順
問題の種類に応じて、次の診断手順に従ってください。
アプリケーションエラー(FastAPI)
# 1. Check application logs for errors
./skills/incident-response/scripts/fetch-logs.sh \
--service backend \
--since "15 minutes ago" \
--output-dir ./incident-logs/
# 2. Check error rate from logs
docker logs app-backend --since 15m 2>&1 | grep -c "ERROR"
# 3. Check active connections and request patterns
curl -s http://localhost:8000/health/ready | jq .
# 4. Check if the issue is in a specific endpoint
docker logs app-backend --since 15m 2>&1 | \
grep "ERROR" | \
grep -oP '"path":"[^"]*"' | sort | uniq -c | sort -rn
# 5. Check Python process status
docker exec app-backend ps aux
docker exec app-backend python -c "import sys; print(sys.version)"
データベースの問題(PostgreSQL)
# 1. Check database connectivity
docker exec app-db pg_isready -U postgres
# 2. Check active connections (connection pool exhaustion?)
docker exec app-db psql -U postgres -d app_prod -c "
SELECT count(*), state FROM pg_stat_activity
GROUP BY state ORDER BY count DESC;
"
# 3. Check for long-running queries (locks, deadlocks?)
docker exec app-db psql -U postgres -d app_prod -c "
SELECT pid, now() - pg_stat_activity.query_start AS duration,
query, state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '30 seconds'
AND state != 'idle'
ORDER BY duration DESC;
"
# 4. Check for lock contention
docker exec app-db psql -U postgres -d app_prod -c "
SELECT blocked_locks.pid AS blocked_pid,
blocking_locks.pid AS blocking_pid,
blocked_activity.query AS blocked_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity
ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.relation = blocked_locks.relation
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity
ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;
"
# 5. Check disk space
docker exec app-db df -h /var/lib/postgresql/data
Redis の問題
# 1. Check Redis connectivity
docker exec app-redis redis-cli ping
# 2. Check memory usage
docker exec app-redis redis-cli info memory | grep used_memory_human
# 3. Check connected clients
docker exec app-redis redis-cli info clients | grep connected_clients
# 4. Check slow log
docker exec app-redis redis-cli slowlog get 10
# 5. Check keyspace
docker exec app-redis redis-cli info keyspace
ネットワークとインフラストラクチャ
# 1. Check DNS resolution
nslookup api.example.com
# 2. Check SSL certificate expiry
echo | openssl s_client -servername api.example.com -connect api.example.com:443 2>/dev/null | \
openssl x509 -noout -dates
# 3. Check container resource usage
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
# 4. Check disk space on host
df -h /
# 5. Check if dependent services are reachable
curl -sf https://external-api.example.com/health || echo "External API unreachable"
修復措置
即時の緩和策(数分以内に実施)
| 問題 | 緩和策 | コマンド |
|---|---|---|
| 問題のあるデプロイ | ロールバック | ./scripts/deploy.sh --rollback --env production --version $PREV_SHA --output-dir ./results/ |
| 接続プールの枯渇 | バックエンドを再起動する | docker restart app-backend |
| 長時間実行中のクエリ | クエリを終了する | SELECT pg_terminate_backend(<pid>); |
| メモリリーク | サービスを再起動する | docker restart app-backend |
| Redis の容量不足 | 重要度の低いキーをフラッシュする | redis-cli --scan --pattern "cache:*" | xargs redis-cli del |
| SSL 証明書の期限切れ | 新しい証明書を適用する | ロードバランサーの証明書を更新する |
| ディスク容量不足 | ログ/一時ファイルを削除する | docker system prune -f |
長期的な修正(安定化後に適用)
- コードの根本原因を修正する -- ブランチを作成し、修正してテストし、通常のパイプラインを通じてデプロイします
- 監視を追加する -- 既存のアラートで問題を検出できなかった場合は、新しいアラートルールを追加します
- テストを追加する -- 障害シナリオの回帰テストを作成します
- ランブックを更新する -- 新しい障害モードと対処手順を記録します
コミュニケーションプロトコル
内部コミュニケーション
チャンネル:
#incidents-- 進行中のインシデント対応(SEV1/SEV2)#incidents-low-- SEV3/SEV4の追跡#engineering-- インシデント後の概要
ルール:
- すべてのコミュニケーションは、指定されたインシデントチャンネルで行います
- 調査の詳細にはスレッドを使用し、メインチャンネルにはステータス更新のみを投稿します
- ICは定義された頻度で更新を投稿します(重大度の表を参照)
- 関係者には明示的にメンションし、見ていると決めつけないでください
- 重要な発見と対応にはすべてタイムスタンプを付けます
外部コミュニケーション(SEV1/SEV2)
ステータスページの更新テンプレート:
[Investigating] We are investigating reports of [issue description].
Users may experience [user-visible impact].
We will provide an update within [time].
[Identified] The issue has been identified as [brief description].
We are working on a fix. Estimated resolution: [time estimate].
[Resolved] The issue affecting [service] has been resolved.
The root cause was [brief description].
We apologize for the disruption and will publish a detailed post-mortem.
事後検証/RCAフレームワーク
すべてのSEV1/SEV2インシデントについて、48時間以内に非難のない事後検証を実施します。SEV3インシデントについては、簡易レビューを実施します。
完全なテンプレートについては、references/post-mortem-template.mdを参照してください。
事後検証の原則:
- 非難しない -- 個人ではなく、システムとプロセスに焦点を当てます
- 徹底する -- 引き金となった事象だけでなく、すべての要因を特定します
- 実行可能にする -- すべての発見事項から、担当者を明記した具体的なアクション項目を作成します
- 迅速に行う -- 詳細が新しいうちに、48時間以内に実施します
- 共有する -- エンジニアリングチーム全体に公開します
事後検証の構成:
- 概要 -- 何が、いつ起き、どのような影響があったか
- タイムライン -- 検出、調査、緩和対応を分単位で記録した経過
- 根本原因 -- インシデントが発生した根本的な理由
- 寄与要因 -- インシデントを悪化させたその他の条件
- うまくいった点 -- 対応において効果的だった部分
- 改善できる点 -- 検出、対応、またはツールにおける不足
- アクション項目 -- 担当者と期限を明記した具体的なタスク
根本原因分析のための「なぜなぜ分析」:
Why did users see 500 errors?
-> Because the backend service returned errors to the load balancer.
Why did the backend service return errors?
-> Because database connections timed out.
Why did database connections time out?
-> Because the connection pool was exhausted.
Why was the connection pool exhausted?
-> Because a new endpoint opened connections without releasing them.
Why were connections not released?
-> Because the endpoint was missing the async context manager for sessions.
Root cause: Missing async context manager for database sessions in new endpoint.
構造化されたインシデントレポートを生成する:
python skills/incident-response/scripts/generate-incident-report.py \
--title "Database connection pool exhaustion" \
--severity SEV2 \
--start-time "2024-01-15T14:30:00Z" \
--end-time "2024-01-15T15:15:00Z" \
--output-dir ./post-mortems/
インシデント対応スクリプト
| スクリプト | 目的 | 使用方法 |
|---|---|---|
scripts/fetch-logs.sh | サービスから最新のログを取得する | ./scripts/fetch-logs.sh --service backend --since "30m" --output-dir ./logs/ |
scripts/health-check-all-services.sh | すべてのサービスの健全性を確認する | ./scripts/health-check-all-services.sh --output-dir ./health/ |
scripts/generate-incident-report.py | 構造化されたインシデントレポートを生成する | python scripts/generate-incident-report.py --title "..." --severity SEV1 --output-dir ./reports/ |
クイックリファレンス:よくあるインシデントのパターン
| パターン | 症状 | 考えられる原因 | 最初の対応 |
|---|---|---|---|
| 502/503エラー | ユーザーにエラーページが表示される | バックエンドのクラッシュまたは過負荷 | docker psを確認し、必要に応じて再起動する |
| 応答の遅延 | 高レイテンシ、タイムアウト | DBクエリ、外部API | スロークエリログとDB接続を確認する |
| 部分的な障害 | 一部のエンドポイントが失敗する | 単一の依存先の停止 | 各サービスの健全性を確認する |
| メモリの増加 | OOMによる強制終了、再起動 | メモリリーク | docker statsを確認して再起動する |
| デプロイ後のエラー急増 | デプロイ時刻と同時にエラーが発生する | 新しいコードのバグ | 直ちにロールバックする |
| 徐々に悪化 | メトリクスが少しずつ悪化する | リソース枯渇、接続リーク | リソース使用状況の推移を確認する |
出力ファイル
ランブック: docs/runbooks/<service>-runbook.mdに書き込みます:
# Runbook: [Service Name]
## Service Overview
- Purpose, dependencies, critical paths
## Common Issues
### Issue 1: [Description]
- **Symptoms:** [What you see]
- **Diagnosis:** [Commands to run]
- **Resolution:** [Steps to fix]
## Escalation
- On-call: #ops-oncall
- Service owner: @team-name
事後検証: postmortem-YYYY-MM-DD.mdに書き込みます:
# Post-Mortem: [Incident Title]
## Summary
- **Date:** YYYY-MM-DD
- **Severity:** SEV1-4
- **Duration:** X hours
- **Impact:** [Users/revenue affected]
## Timeline
- HH:MM - [Event]
## Root Cause
[Technical explanation]
## Action Items
- [ ] [Preventive measure] - Owner: @name - Due: YYYY-MM-DD