グラフは「いつ」までしか答えない
一言でいうと
グラフは「いつ」までしか答えません。「なぜ」は指標の外にある出来事で、アノテーションはその出来事を同じ時間軸の上に載せて、次の人が自力で答えを見つけられるようにしてくれます。
なぜ必要なのか
午前3時にページを受けた人が、ダッシュボードを開きます。エラー率が02:10から折れ曲がって上がっています。ここまではグラフが答えてくれます。次の質問、「その時刻に何があったのか」には、グラフは答えられません。そこで人は、別の画面を開きます。デプロイパイプラインの記録、チャットルームのスクロール、設定リポジトリのコミット一覧です。3か所の時計は互いに違い、タイムゾーンも違います。原因探しにかかった20分のうち15分が、この行き来に費やされます。
アノテーションは、その行き来をなくします。デプロイが終わるときにパイプラインが1行をグラフに残しておけば、次の人は、エラー率が折れた位置のすぐ下に縦線が1本あるのを見ることになります。その線に、バージョンと担当者と元に戻す方法が書いてあれば、調査ではなくすぐに対処へ進めます。
大事なのは、これがあとから作れない記録だという点です。デプロイがいつ終わったかは、そのときに記録しなければ残りません。1か月後に「あのときデプロイはあったのか」をたどろうとすると、結局パイプラインのログを掘ることになり、そのログはたいてい保存期間を過ぎています。
どう動くのか
Grafanaのアノテーションは、時間上の出来事1つです。点の場合もあれば(timeだけ)、区間の場合もあります(timeとtimeEnd)。作る方法は3つあります。パネル上で直接付ける、HTTP APIで入れる、そして、ほかの場所にすでにある出来事をクエリで取得してくる方法です。
APIで作るときに使うのはPOST /api/annotationsです。公式ドキュメントは、必須フィールドはtextの1つだけで、dashboardUIDとpanelIdは任意であり、書かなければ組織全体のアノテーションになると書いています。時刻はミリ秒単位のエポック整数で、区間アノテーションを作るときはtimeEndを一緒に入れます。作ったあとは応答にidが返り、それ以降はGET /api/annotationsで読み直せます。読むときはdashboardUIDやtagsで絞り込めて、タグを複数回指定すると、そのすべてを持つもの(AND)だけが絞り込まれます。
ダッシュボード側にはアノテーションクエリがあります。ダッシュボードJSONのannotations.listに項目を置いてタグを指定しておくと、そのダッシュボードを開くときに、Grafanaがそのタグの付いたアノテーションを取得してパネルの上に載せます。項目ごとに名前と色とオン・オフがあるので、画面上部のトグルで「デプロイだけを見る」や「障害区間だけを見る」をオン・オフできます。アノテーションをタグで分類しておく価値は、ここから生まれます。種類が混ざっていると、トグルは何の役にも立ちません。
ただし、アノテーションがすべてのパネルに描かれるわけではありません。公式ドキュメントは、アノテーションに対応する可視化はTime series、State timeline、Candlestickだと書いています。統計1マスだけのパネルには、載せる場所がありません。アノテーションを使うために作るダッシュボードなら、少なくとも1つは時間軸のあるパネルでなければなりません。
人が手で付けるアノテーションと、パイプラインが自動で付けるアノテーションは、性格が違います。手で付けるものは、調査中にわかったことをその場に貼っておく用途なので、文章は自由です。自動で付けるものは、漏れなく残ることがすべてなので、形式が固定されている必要があります。自動の記録を人の手に任せると、忙しい日に抜けてしまい、よりによってその日が原因を探さなければならない日です。
そのため、自動記録ツールを作るときは、2つを決めておきます。1つは何を書くかです。バージョン、デプロイした人(またはパイプライン)、元に戻すコマンド1行です。この3つがないと、アノテーションを見た人は結局ほかの画面を開くことになります。もう1つは送信する前に出力して確認できるかです。パイプラインの中でしか動かないスクリプトは、壊れたときに確認しにくくなります。送る本文をそのまま出力するモードを用意しておけば、人が目で検査でき、テストも副作用なしで動かせます。
この環境で確認できることとできないことを書いておきます。確認できるもの: アノテーションが実際に記録されたか(POSTの応答のidをGETで読み直して照合)、時刻と区間が合っているか、タグが付いているか、ダッシュボードのannotations.listにそのタグを取得するクエリが宣言されているか、自動記録ツールが送ろうとしている本文がどんな形か。確認できないもの: アノテーションが画面に本当に縦線として描かれるか。パネルはブラウザーが描き、このPodには画像レンダラープラグインがありません。そのため、このラボの採点はすべてAPIとダッシュボードモデルだけで行い、絵そのものは、Webプレビューで開いて目で確認する必要があります。クエリが宣言されていて、そのタグでアノテーションが実際に取得できるなら、描かれる条件は整っていますが、それと「描かれた」とは同じ意味ではありません。
現場での姿
デプロイのアノテーションをオンにしているチームでいちばんよく聞く言葉は、「縦線の直後に折れていますね」です。その1文が、調査の最初の30分をなくします。逆に、アノテーションをオンにしていないチームでは、同じ障害について、「デプロイのせいではないか」と「あのときデプロイはなかった」が20分間行き交います。
アノテーションをオンにしていても使えない場合もあります。あるチームは、デプロイのアノテーションの本文が、コミットハッシュ1つだけでした。明け方にそのハッシュを受け取った人にできるのは、リポジトリを開くことだけで、元に戻すコマンドは、結局ほかの人を起こして聞きました。アノテーションは、次の人がその場で行動できるかで内容を決める必要があります。
区間アノテーションが特に価値を発揮するのは、事後の振り返りです。障害の開始と終了を区間として残しておけば、その区間を基準にエラーバジェットの消費を計算し直せますし、翌月に「あの障害は何分だったのか」をめぐって争わずに済みます。
次のラボですること
まず、エラー率のパネル1つだけのダッシュボードを作り、グラフだけでは原因がわからないことを確認します。次に、デプロイをアノテーションとして残してAPIで読み直して照合し、開始と終了のある区間アノテーションで障害の時間を示します。タグで2つを分けて、ダッシュボードのアノテーションクエリがそれぞれを取得するようにし、デプロイパイプラインが呼び出す自動記録ツールを作ります(送る本文を出力して確認するモードを含みます)。最後に、アノテーションに何を書けば次の人が使えるのかを形式として決めて守り、残ったアノテーションを時系列順に読み直して、調査記録と結論を残します。