デバッグ は何をしますか?
最初の可能性のある原因を修正するのは高くつく。最初の数分はパッチを当てるのではなく絞り込むために使う。
方法
- 正確な障害を取得する。 完全なエラーテキスト、スタックトレース、終了コード、タイムスタンプ、リクエストID、実行したコマンド。コードブロックに入れる。要約されたエラーは、重要なトークンを失う。
- 再現する。 オンデマンドでトリガーする、最も小さくて速い方法を見つける。再現できない場合は、その旨を伝えてログから作業する。黙って推測してはいけない。
- 何が変わったかを特定する。
git log --since、最近のデプロイ、依存関係のバンプ、設定やIAMの変更、プロバイダーのアップグレード、証明書の期限切れ。ほとんどのインシデントは変更が原因である。 - 2~3つの仮説を立てる それらを可能性と確認コストの安さでランク付けする。テストする前に書き留めておく。
- 一度に1つの仮説をテストする その仮説が真の場合にのみ意味を持つ変更でテストする。役に立たなかった変更は元に戻す。推測による編集を蓄積してはいけない。
- 原因を修正する。 次に、修正なしでは失敗する回帰テストを書く(
tddスキルを参照)。 - 再現した方法と同じ方法で検証し、より広範なスイートを実行する。
症状別の調査箇所
| 症状 | 最初の確認項目 |
|---|---|
| ローカルで動くがCIで失敗 | 環境変数、シークレット、OS/アーキテクチャ、Node/Pythonバージョン、キャッシュされた依存関係、タイムゾーン、作業ディレクトリ |
| 断続的/不安定 | テスト間の共有状態、時間、順序、ネットワーク、実際の障害を隠すリトライ |
| AWS AccessDenied | どのプリンシパルか(aws sts get-caller-identity)、リソースポリシーとIDポリシー、SCP、許可境界、KMSキーポリシー、リージョン |
| Lambda タイムアウト / コールドスタート | VPCアタッチメント、DNS、ハンドラ外の初期化、メモリサイズ、X-Rayでのダウンストリームレイテンシ |
| Terraform エラー | プロバイダーバージョン、ステートのドリフト(terraform plan -refresh-only)、-targetの残骸、ロックファイル |
| Kubernetes ポッドが準備完了にならない | kubectl describe pod、イベント、プローブ、リソース制限、イメージプル、シークレット/ConfigMapマウント |
| デプロイ後の5xx | 前のイメージ/コミットとの比較、ヘルスチェックパス、環境設定/コンフィグ差分、DBマイグレーションの順序 |
ルール
- コードを読む前にログを読む。ログはどこでか、コードはなぜかを教えてくれる。
- 必要に応じて一時的なログを追加し、コミットする前に削除する。
- 権限を広げる、TLS検証を無効にする、例外をキャッチして飲み込む、何がリトライされているかを理解せずにリトライを追加する、といった「修正」を決してしてはいけない。
- 修正したら、原因、なぜ捕捉されなかったか、次回それを防ぐために何をするか、を1段落にまとめる。その段落をPRまたはコミットボディに記載する。