🙇

申し訳ございません、障害が発生致しました (原因分析)

2025/02/02に公開

先日、担当チームから本番障害を発生させてしまいました。ご利用中のお客様には、大変ご迷惑をおかけしました。

🎯 本記事の目的

障害発生は学びや成長の機会

障害や事故は、どんなに完璧なチームや環境でも発生する可能性があります(障害を肯定する意図ではありません)。重要なのは、発生した事実を悔やむのではなく、それを改善の機会として活かすことです。
この考えに基づき、既存の障害レポートのフォーマットを見直し、新しい原因分析フレームワークを作成しました。
本記事では、その詳細についてご紹介させていただきます。

🧐 原因分析フレームワーク

原因分析をフレームワーク化した背景

エンジニアリング組織が成長するにつれ、以下の課題が顕在化してきました:

  • 障害分析の方法が担当者によってバラバラ、担当者に依存した属人的なプロセス
  • 表面的な原因分析で終わってしまう、分析の深度が浅くなる
  • 再発防止策が具体的でない、場当たり的なものになってしまう

そこで、より体系的かつ効果的な再発防止に向けた分析を実現するために、新しい原因分析フレームワークをテンプレートにして、開発チームに展開しました。

フレームワークの特徴

フレームワークの使用上の注意

🔎 原因分析フレームワーク - Template

以下を事象ごとにコピーして使用してください。

事象整理

今回のインシデントに関する情報を記載してください。別途、インシデントレポートを作成している場合は、そのリンクを記載してください。

  • 該当PR Ticket (Github) / IaC (Infrastructure as Code) / 具体的な作業箇所が分かる情報

  • 該当Epic / Jira ticket / Request Ticket

  • 発生〜検知〜対応完了までの時系列

  • 影響範囲 (対外影響 / 対内影響 / ステークホルダー / レポート先 etc)

1. 直接原因分析:問題の発生箇所を特定する

インシデントが発生した箇所についての原因を分析します。一般的には、直接原因はヒューマンエラー(不注意や勘違いなど)や偶発性が多く検出されます。

項目 分析ポイント 具体的な質問 記載例
Where(どこで) 障害が発生した具体的な箇所 - どのモジュール/クラス/関数で発生したのか?
- 新規開発部分か、既存コードか?
- BackendのPython処理関数calculate_price内で例外が発生。
- 既存コードの価格計算ロジック修正時に発生。
How(どうやって) 作業手順と方法 - どのような手順で開発/作業を行ったのか?
- 手動作業と自動化部分の区別は?
- リクエスト処理を逆引きして修正箇所を特定。
- テスト環境で動作確認後、本番環境にデプロイ。
Why(どうして) その作業方法を選択した理由 - なぜその開発/作業方法を選んだのか?
- ルールやガイドラインは存在したか?
- 緊急対応のため、ピンポイントでの修正を選択。
- 修正箇所はリーダーに口頭で確認。過去のガイドラインは参照せず。

2. 間接原因分析:潜む要因を洗い出す

特定の要因があるかどうかを確認します。一般的には、属人性や機能性、習熟難易度、環境やロケーションなどが該当します。以下の質問へ回答を入れてください。

チェックポイント 具体的な質問 記載例
チーム構成と経験値 - 担当者はチームにアサインされてから6ヶ月未満か?
- 担当者は類似の機能開発経験があるか?
- 担当者はチーム配属3ヶ月目。
- 類似機能の開発経験はなく、今回が初めて。
機能の複雑性 - 複雑な条件分岐や依存関係が存在するか?
- 特殊な技術やドメイン知識が必要か?
- グローバル変数を参照しており、影響範囲が広い。
- 決済処理に関わるため、セキュリティに関する専門知識が必要。
外部要因の有無 - 外部システムとの連携に問題があったか?
- スケジュール圧縮やリソース不足の影響は?
- 外部APIのレスポンス遅延が発生していた。
- リリース期限に間に合わせるため、テスト工程が短縮された。

3. 流出原因分析:なぜ未然に防げなかったのか

本番リリース前に検知できなかった原因を分析します。一般的には、レビューやテストで検知することが期待されていますので、そこが機能していたのかどうか、現状の仕組みや工程で足りていたのかどうかを確認します。

項目 チェック項目 具体的な質問 記載例
テスト テストの網羅性 - ユニットテスト、結合テスト、E2Eテストは十分に実施されていたか?
- テストケースは網羅的で、 edge case もカバーしていたか?
- ユニットテストは実施していたが、結合テストは実施していなかった。
- テストデータが不十分で、一部のケースをカバーできていなかった。
レビュー レビューの質と量 - コードレビューは適切な人数で実施され、フィードバックは反映されたか?
- 設計レビューは実施され、関係者間で認識齟齬はなかったか?
- コードレビューは実施したが、レビュアーが1名しかおらず、十分なチェックができていなかった。
- 設計レビューは実施したが、時間不足で重要なポイントが議論されなかった。
自動化 自動化による予防 - 静的解析ツールは導入されており、適切なルール設定がなされていたか?
- CI/CDパイプラインは整備されており、自動テストが組み込まれていたか?
- 静的解析ツールは導入されていたが、ルール設定が古く、最新のコード規約に対応していなかった。
- CI/CDパイプラインは構築中であり、自動テストは部分的にしか実装されていなかった。

4. 根本原因分析:問題の真因を突き止める

対策を検討するために必要な発生原因を分析します。

項目 分析ポイント 具体的な質問 記載例
タスク/体制 - タスクの割り当ては適切だったか?
- チーム体制に問題はなかったか?
- 経験の浅い担当者に難易度の高いタスクが割り当てられていた。
- チーム全体で情報共有が不足していた。
- 新人研修が不十分で、担当者は必要な知識を習得できていなかった。
- チームメンバー間のコミュニケーション不足により、レビューが形骸化していた。
開発ルール/環境 - 開発ルールは遵守されていたか?
- 開発環境に問題はなかったか?
- コーディング規約が守られていなかった。
- テスト環境と本番環境で差異があった。
- コーディング規約の周知徹底が不足していた。
- インフラ構成管理が適切に行われていなかった。
バックアップ/サポート - バックアップ体制は整っていたか?
- サポート体制は適切だったか?
- データベースのバックアップが取得されていなかった。
- 障害発生時の連絡体制が整っていなかった。
- バックアップ取得の重要性に対する認識が不足していた。
- 緊急時の対応マニュアルが整備されていなかった。

5. 再発防止策:具体的なアクションプラン

防止策の検討

各原因から、是正効果のある対策を組み立てましょう。一般的には、対応効率やコストの面でも大元となる原因に対策を行う事が、再発防止効果が高いと言われています。

一般的な施策例

原因 短期施策(1ヶ月以内) 中期施策(3ヶ月以内) 長期施策(半年〜1年)
ユニットテストの不足 - テストコードの追加
- テストカバレッジ基準の設定
- テスト自動化フレームワークの導入 - テスト駆動開発(TDD)の導入検討
レビュー体制の不備 - 複数人によるレビューの義務化
- レビューチェックリストの作成
- レビューガイドラインの策定
- レビュー担当者のスキルアップ
- レビュープロセス改善のためのワークショップ開催
環境差異による不具合 - 開発環境・ステージング環境の標準化 - インフラ構成管理ツールの導入 - Infrastructure as Code (IaC) の導入

即効性のある施策例

施策 効果 状況
静的解析強化 コード品質の向上 導入済み
レビューガイドライン策定 レビュー品質の統一 運用中
テストカバレッジ基準設定 バグの早期発見 展開中

実行計画

実際のスケジュールとロードマップを作成しましょう。

中長期的な施策例
タイムライン別の対策例

6. クロージング チェックリスト

全てを確認した場合に、当該障害をクローズすることが出来ます。

  • 分析結果は第三者から見て、十分な内容になっているか?(当事者 / 当該チーム以外とレビューしたか)

  • 再発防止策は、妥当な範囲内 / 妥当な施策 になっているか?

  • 障害発生から3ヶ月後に、再発防止の効果確認をしているか?

📝 おわりに

この障害を貴重な学びの機会として捉え、より良いサービスを提供するために以下の取り組みを継続します:

  • 定期的な振り返りと効果測定
  • 具体的な改善施策の立案
  • 効果測定に基づく継続的改善

今後とも、安定したサービスの提供に努めてまいります。引き続きのご支援を、よろしくお願い申し上げます。

Discussion