TT Lab
ブログ はじめる
学ぶ 学習パス コース

インシデントコマンドとポストモーテム

ブレームレスなポストモーテム — 今は失敗し、直せば通る対策

TT Labで続きを見る

目標

決済インシデントの記録から、トリガーとなったデプロイ・根本原因・寄与要因を実際の行とともに分け、対策ごとに「今は失敗し、直せば通る」 検証コマンドを書きます。人の名前のないポストモーテムを書き、本番設定を実際に直し、検証が嘘をついていた前四半期の対策を正します。

なぜ重要か

ポストモーテムが約束するのは「二度と起きない」ことで、その約束を守るのは文章ではなく対策です。対策が「完了」で閉じられても、 検証が欠陥を捕まえられなければ一度も完了していないのと同じです。このラボの採点ツールは、皆さんの検証コマンドをインシデント当時のコピー、直したコピー二つ、 要因を一つだけ残したコピーに実際に実行してみます。現場で検証が嘘をつくあらゆるやり方(キーだけを見る、終了コードを覆う、古いコピー・別のキーを 見る、値一つを決め打ちする)がここで引っかかります。このラボは60分に設定されていて基本のセッション時間と同じなので、開始時にあらかじめ時間を延長しておいてください。

ステップ

  1. python3 /opt/fixtures/ic/ickit.py open postmortem で素材を展開し、/root/ic/postmortem/README.txt を読んでください。app.log の最初の ERROR の直前に入ったデプロイのコミット sha(先頭7文字)と、そのデプロイが変えた設定ファイルを /root/ic/postmortem/answers/trigger.txt に deploy=<sha>、changed=<etc/...file> の二行で書きます。
  2. /root/ic/postmortem/answers/evidence.txt に三行を書きます: trigger: <trigger-line>(きっかけとなったデプロイを指す deploys.log の commit の行かタイトルの行)、first_error: <first-error-line>(app.log の最初の ERROR 行)、recovery: <resolved-line>(このインシデントのアラートが解除された alerts.csv の行)。各行は素材にあるとおりでなければなりません。
  3. README のチームの基準と /srv/shop/etc/ の設定、デプロイ記録を突き合わせ、根本原因一つ(トリガーとなったデプロイが基準外に変えたもの)と寄与要因二つ(もともと基準外だったもの)を /root/ic/postmortem/answers/factors.txt に書きます。原因の行(root_cause: <code> または contributing: <code>)のすぐ下に evidence: <line> を付けます。コード: alert-threshold-high(アラートしきい値が高い)、cache-ttl-zero(キャッシュ TTL が0)、deploy-no-healthgate(デプロイのヘルスチェックが無効)、pool-too-small(コネクションプールが小さい)、retry-no-backoff(リトライに待機がない)、timeout-too-long(ゲートウェイのタイムアウトが長い)。
  4. 根本原因と寄与要因ごとにアクションアイテムを一つずつ /root/ic/postmortem/answers/actions.txt に書きます。対策ごとに action: <what>、owner: <team>、factor: <factor-code>、verify: <shell-command> の四行です。verify は設定ツリーを環境変数 $ROOT で受け取り(例: "$ROOT/etc/pool.conf")、その要因がチームの基準外なら0以外のコードで、基準内なら0で終わらなければなりません。採点ツールはインシデント当時のコピー(失敗すべき)、直したコピー二つ(値が違っても通るべき)、その要因だけを残したコピー(失敗すべき)に実際に実行してみます。
  5. /root/ic/postmortem/answers/postmortem.md にポストモーテムを書きます。## Summary(要約)、## Impact(影響)、## Root cause(原因)、## Actions(対策)の四つの節が必要で(節の名前は韓国語の ## 요약・## 영향・## 원인・## 조치 も受け付けます)、影響の節には duration: <N>m(最初の ERROR からアラート解除までの分、切り捨て)と failed_requests: <M>(app.log の ERROR 行数)、原因の節には根本原因・寄与要因のコード、対策の節には対策ごとに verify: の行を書きます。どの行にも人の名前(チャンネルハンドル)を書きません。素材を引用する行だけは evidence: で始めれば例外です。
  6. 本番設定 /srv/shop/etc/ を直して、三つの欠陥をチームの基準内に収めてください(基準内だった設定は壊しません)。その後、ステップ04の verify が ROOT=/srv/shop ですべて通るか確認します。
  7. incident ic-unverifiable を実行するとインシデントが発生します。/srv/billing/postmortems/2026-q3.md の対策 A1・A2・A3 はすべて done で、/srv/billing/bin/verify-actions も三つとも PASS を出しますが、/srv/billing/etc/ の設定は三つともチームの基準(/srv/billing/README.txt)の外です。(1) 対策ごとに verify を直し、欠陥が残っていれば失敗し、直れば通るようにし(factor と対策の順序はそのまま)、(2) 設定を実際に直して verify-actions が正直に PASS を出すようにしてください。採点ツールは直した verify を、インシデント当時のコピー(古いコピー etc/old/ を含む)・直したコピー二つ・その要因だけを残したコピーに実行してみます。/root/incident/ic-unverifiable/report.txt に A1: <code>、A2: <code>、A3: <code> の三行と evidence: <original-verify-line> を書きます。コードは対策ごとに次のいずれかです: always-passes(値を見ずにキーの存在だけを見る)、exit-masked(失敗した終了コードを後ろで覆い隠す)、flaky-timing(時刻によって結果が変わる)、wrong-file(サービスが読まないファイルを見る)、wrong-key(名前の似た別のキーを見る)。

参考

素材の展開 — トリガーとなったデプロイを探す

python3 /opt/fixtures/ic/ickit.py open postmortem で素材を展開し、/root/ic/postmortem/README.txt を読んでください。app.log の最初の ERROR の直前に入ったデプロイのコミット sha(先頭7文字)と、そのデプロイが変えた設定ファイルを /root/ic/postmortem/answers/trigger.txt に deploy=<sha>、changed=<etc/...file> の二行で書きます。

app.log は UTC、git の Date はコミットした人のタイムゾーンです。「最新のデプロイ」ではなく「最初のエラーの直前のデプロイ」です。デプロイのコミット本文の change: 行が、変更したファイルを教えてくれます。

タイムラインの三本柱を実際の行で

/root/ic/postmortem/answers/evidence.txt に三行を書きます: trigger: <trigger-line>(きっかけとなったデプロイを指す deploys.log の commit の行かタイトルの行)、first_error: <first-error-line>(app.log の最初の ERROR 行)、recovery: <resolved-line>(このインシデントのアラートが解除された alerts.csv の行)。各行は素材にあるとおりでなければなりません。

grep で見つけた行をそのまま貼ってください(grep -n の行番号の接頭辞は付いていても構いません)。似た別の行や手で直した行は不合格になります。

根本原因と寄与要因

README のチームの基準と /srv/shop/etc/ の設定、デプロイ記録を突き合わせ、根本原因一つ(トリガーとなったデプロイが基準外に変えたもの)と寄与要因二つ(もともと基準外だったもの)を /root/ic/postmortem/answers/factors.txt に書きます。原因の行(root_cause: <code> または contributing: <code>)のすぐ下に evidence: <line> を付けます。コード: alert-threshold-high(アラートしきい値が高い)、cache-ttl-zero(キャッシュ TTL が0)、deploy-no-healthgate(デプロイのヘルスチェックが無効)、pool-too-small(コネクションプールが小さい)、retry-no-backoff(リトライに待機がない)、timeout-too-long(ゲートウェイのタイムアウトが長い)。

基準内にある設定は欠陥ではありません(おとり)。証拠はその要因を示すログ・デプロイ記録・アラートの行から選んでください。設定ファイルの一行は短すぎて証拠になりません。

検証できる対策

根本原因と寄与要因ごとにアクションアイテムを一つずつ /root/ic/postmortem/answers/actions.txt に書きます。対策ごとに action: <what>、owner: <team>、factor: <factor-code>、verify: <shell-command> の四行です。verify は設定ツリーを環境変数 $ROOT で受け取り(例: "$ROOT/etc/pool.conf")、その要因がチームの基準外なら0以外のコードで、基準内なら0で終わらなければなりません。採点ツールはインシデント当時のコピー(失敗すべき)、直したコピー二つ(値が違っても通るべき)、その要因だけを残したコピー(失敗すべき)に実際に実行してみます。

設定は key=value で、同じキーがまた出てくると下の行が勝ちます。キーの存在だけを見たり、値一つを文字どおり決め打ちしたり、終了コードを || で覆ったりすると不合格になります。awk -F= で最後の値を保持しておき、END で基準と比較して exit する形が便利です。自分で ROOT=/srv/shop bash -c '<command>'; echo $? で実行してみてください。

ブレームレスなポストモーテムを書く

/root/ic/postmortem/answers/postmortem.md にポストモーテムを書きます。## Summary(要約)、## Impact(影響)、## Root cause(原因)、## Actions(対策)の四つの節が必要で(節の名前は韓国語の ## 요약・## 영향・## 원인・## 조치 も受け付けます)、影響の節には duration: <N>m(最初の ERROR からアラート解除までの分、切り捨て)と failed_requests: <M>(app.log の ERROR 行数)、原因の節には根本原因・寄与要因のコード、対策の節には対策ごとに verify: の行を書きます。どの行にも人の名前(チャンネルハンドル)を書きません。素材を引用する行だけは evidence: で始めれば例外です。

原因は「誰が」ではなく「何が」(設定・手順・検査の不在)で書きます。数値は素材から数え直します。オーナーはチーム名で書きます。

対策を実際に行う

本番設定 /srv/shop/etc/ を直して、三つの欠陥をチームの基準内に収めてください(基準内だった設定は壊しません)。その後、ステップ04の verify が ROOT=/srv/shop ですべて通るか確認します。

サービスは同じキーが何度も出てくると下の行を使います。行を直しても末尾に追記しても、最後の値が基準内であれば構いません。直した後、verify を自分で実行して終了コードを見てください。

インシデント — 「検証通過」なのに同じインシデントがまた起きた

incident ic-unverifiable を実行するとインシデントが発生します。/srv/billing/postmortems/2026-q3.md の対策 A1・A2・A3 はすべて done で、/srv/billing/bin/verify-actions も三つとも PASS を出しますが、/srv/billing/etc/ の設定は三つともチームの基準(/srv/billing/README.txt)の外です。(1) 対策ごとに verify を直し、欠陥が残っていれば失敗し、直れば通るようにし(factor と対策の順序はそのまま)、(2) 設定を実際に直して verify-actions が正直に PASS を出すようにしてください。採点ツールは直した verify を、インシデント当時のコピー(古いコピー etc/old/ を含む)・直したコピー二つ・その要因だけを残したコピーに実行してみます。/root/incident/ic-unverifiable/report.txt に A1: <code>、A2: <code>、A3: <code> の三行と evidence: <original-verify-line> を書きます。コードは対策ごとに次のいずれかです: always-passes(値を見ずにキーの存在だけを見る)、exit-masked(失敗した終了コードを後ろで覆い隠す)、flaky-timing(時刻によって結果が変わる)、wrong-file(サービスが読まないファイルを見る)、wrong-key(名前の似た別のキーを見る)。

方向: 検証が嘘をつく道はいくつもあります。何を読むか(ファイル・キー)、何と比較するか(値を見てはいるか)、終了コードが最後まで生き残るか。対策ごとに三つのうちどこがずれているかを見ます。 ツール: 元の verify を ROOT=/srv/billing bash -c '<command>'; echo $? で自分で実行する、README の基準、grep -n。 具体: まず verify を直して今の設定で失敗するのを目で確かめ、その次に設定を直して通るようにしてください。順序を逆にすると、検証が欠陥を捕まえるかどうかがわかりません。