はじめに

Site Reliability Engineering チームの Engineering Manager 尾形(@nobu666)です。考えてみたら SRE チームに関してこの Blog でネタにしたことがなかったことに今更気づいてしまいました。UZABASE さん主催の SRE Lounge #3 でも少し触れたのですが、今回は Incident への対応から、Report の書き方、そしてその Review について紹介しようと思います。

Incident

Incident Review は障害の振り返り会のことを指します。ポストモーテムということもあります。その前に、そもそも Incident とはなんでしょうか。会社によって定義は様々だと思いますが、弊社においては「ユーザ、あるいは顧客(広告主であったり媒体社であったり)に直接的な影響が出た障害」を Incident と定義しています。

障害対応は原則的に2人以上で行うことにしています。これは何故かと言うと、実際に対応を行う人とは別に、状況をまとめて周囲に伝える人を確保するためです。例えば SmartNews において特定のチャンネルだけ記事が表示されない障害が起きたとすると、今何が起きていてどうなっているのかを、エンジニア以外にも共有する必要があります。カスタマーサポートの担当者・そのチャンネルの媒体社の担当者など、ステークホルダーに正しく状況を伝える必要が出てきます。実際に対応を行いながら、逐一連絡も漏れなく行うことはかなり難しいため、作業を行わずに連絡に徹する人がいることが望ましいのです。

弊社はチャットツールに Slack を利用していますが、障害発生時は #incident というチャンネルで情報をやり取りしています。「いまからこのサーバでこのコマンド実行します」「ここのログ確認します」「バージョンを一つロールバックします」など、誰が何をしようとしているか、その結果どうなったかということはすべてこのチャンネルに集約します。しかしその内容は雑多すぎ、エンジニアではない人がそこから状況を把握するのはコストが高すぎます。そこで、別途 #status というチャンネルを用意してあります。ここは障害のサマリーだけを通知するチャンネルで、ここに先程の連絡係が「今この機能が動いていないので調査中」ということを書き込んで周知するように運用しています。

日中のオフィスにいる時間帯に起きた障害の場合、一箇所に集まって口頭で情報をやり取りしながら障害の対応を行うこともよくあります。しかしその場合も #incident への書き込みは、都度行いながら対応しています。ここのやり取りをベースにして、Incident Report を書くためです。

Incident Report

所謂内部向けの障害報告書です。すべての障害について Incident Report を書くわけでもないのですが、書くべきかどうか、誰が書くかということは各チームの Engineering Manager が決定権を持っています。

Incident Report はガイドラインとテンプレートが存在しており、書くべきことは決まっています。Incident Report をなぜ書くのか、ということはガイドラインで次のように定義してあります。

  • 同様の障害が起きた時に、どのように対処したのか Incident Report を見ればわかるようにするため
  • 障害の対応方法を共有することで、学習する機会を作るため
  • Incident Review を行う材料にするため

この目的を満たすように Incident Report を書いてもらう必要があります。具体的は以下のようなテンプレートになっています。

# Description // 障害概要

[***MUST***]
簡潔に、何がどのくらいの間動かなかったのかを書く // Briefly, write what did not operate and how long

# Area of Influence // 影響範囲

[***MUST***]
影響を受けたユーザ数やリクエスト数、お問い合わせの数 // Write the number of affected users, the number of requests, and the number of inquiries

ex.)
|Affected people|Segments|Rough number|
|---|---|---|
|SmartNews users|All / iOS/Android. specific app version, JP/US)|3,000,000|
|Publishers|||
|SmartNews staff|All|100|

# Operation // 対応内容

## Timeline // 流れ

[***MUST***]
障害発生と終了、対応開始と終了がわかるように。また、実際の Operation Log を記入する // Note the distinction between when the `OUTAGE BEGINS` and when the `INCIDENT BEGINS`. `INCIDENT BEGINS` corresponds to when someone has actually started addressing/responding to the issue.

Datadog や PD の URL も書く。もしくは誰がどこで報告してくれた、でもよい // Write the URL of Datadog or PD

- 09:00 **OUTAGE BEGINS** @someone deployed new JARS into production
- 09:01 Datadog triggered the alert https://app.datadoghq.com/monitors#xxxxx?to_ts=1509219060000&group=name%3Axxxxxxxx&from_ts=1509218460000
- 09:03 Ack @someone
- 09:05 **INCIDENT BEGINS** @someone
    - ![image.png](https://example.com/hogehoge.png)
- 09:30 @someone started to revert the latest changes in staging

```
$ deploy_command deploy:application=xxx,group=staging,rev=hotfix_branch
```

- 09:40 @someone validated staging is recovered
- 09:40 @someone started to revert the latest changes in production

```
$ deploy_command deploy:application=xxx,group=sproduction,rev=hotfix_branch
```

- 09:45 **OUTAGE ENDS** @someone validated production is recovered
    - ![image.png](https://example.com/fugafuga.png)
    - https://app.datadoghq.com/monitors#xxxxxx?to_ts=1509219840000&group=name%3Axxxxxxxxx&from_ts=1509219240000
- 09:45 **INCIDENT ENDS** @someone closed the incident

-----

ここから下は Incident Review 時に追記するでも可

-----

# Cause // 発生原因

## Root Causes // 根本原因

障害発生の根本的な原因を書く。たとえば「デプロイしたコードに考慮漏れがあった」というのは直接原因であり根本原因ではない // Write the root cause. For example, "It is not possible to consider the deployed code" is a direct cause and not a root cause

あわせて改善すべき点を列挙する。検知が遅れた・できなかった、対応できる出来る人がいなかった、連絡先がわからなかった、など。これは Action items と対応する // List points to be improved. Detection was delayed, No one can respond, I did not know the contact information, etc.

# Responders // 対応者

@someone

# Recurrence Prevention Measure // 再発防止策

## Action Items

Done  | Action Item | Type | Owner | Issue
:-----|:------------|:-----|:------|:------
✅ | schedule incident review | incident review | @someone | JIRA Link (make sure to assign the `incident` label to these JIRA issues)

### Types for Action Items

|Name|Description in English|Description in Japanese|
|---|---|---|
|Fix|Fix on code or infrastructure|コード・インフラ設定等の修正対応|
|RCA|Root Cause Analysis|根本原因の調査|
|Detection|Detecting the situation|検知に関すること|
|Dev Process|Development process|開発手順に関すること|
|Ops Process|Operation process|運用手順に関すること|

# Supporting information // 補足

一部修正・削除してありますが、ほぼ使っているものそのままです。ポイントは

  • 日本語と英語の併記を推奨する。あるいは英語のみで書く
  • 何をどう書くべきかを、具体的にテンプレートに例として挙げておく
  • 書く人の負荷をなるべく下げるため、根本原因と再発防止策については Incident Review 後に書いてもよいようにする
  • 対応完了後、1-2営業日以内に書き上げることが望ましい

Incident Review

上述した Incident Report をベースに、関係者が集まって Incident Review を行います。書き上げてから1-2営業日以内に実施されることが望ましいです。ポイントは SRE 本にも書いてあるとおりですが、改めて列挙します。

  • 人間のミスを決して責めない
    • あくまでプロセスや仕組みでの改善を図る
  • 発生原因を根本まで掘り下げる
    • 「ちゃんとレビューする」「気をつける」などという表面的なところで解決した気にならないこと
  • 根本原因が判明したら、二度と起こさないためになにをするべきか明確にし、担当者と期限を決める
    • 完全解決が現実的に不可能な場合もあるが、その場合は次起きたときに被害を最小限に抑えるためにはどうすればいいかを考える

おわかりの通り、レビューというよりは議論が必要になります。場合によってはエンジニアだけでなく、プロダクトマネージャ・オペレータのような人も議論に参加してもらって再発防止策を議論することもあります。また障害の検知方法についても、障害が起きる前に検知することはできないのか? もっと良い方法はないのか? といったことも議論します。

再発防止策のトラッキング

せっかく再発防止策をアクションアイテムとして挙げても、実際に実施されなければなんの意味もありません。「やらなきゃいけないことはわかってるんだけど……」という状態が続くことは、問題を放置していることとなんら変わりありません。

弊社では JIRA を使用し、再発防止策が実施されたのかどうかをトラッキングできる Dashboard を作ってあります。期限を過ぎて終わっていないタスクは、週次で行っている SRE と各チームとの Sync Meeting にて進捗状況の確認・期限の切り直し・担当者の見直しなどを行っています。

まとめ

3つ言わせてください。

  1. 人を責めずにプロセスで改善しよう
  2. 理詰めで議論して根本原因を探り当てよう
  3. 特にありません

以上です