Mackerelでカスタムメトリクスを式によって監視してデプロイ後のバグを早期発見出来る仕組みを作った

やった事 (3行)

  • Mackerel に 日々の予約数をカスタムメトリクスとしてプロットするようにした
  • 前日同時刻帯のメトリクスを比較してしきい値を下回っているようであればアラートを出すようにした
  • 曜日に対してしきい値を調整したかったのでダウンタイム設定を入れた

本題

今回は先日Mackerelにてデータのチェック監視をやったのでそれについてアウトプットしたいと思います。

先日(大分前ですが)、input value が間違ってコーディングされてしまった事が原因で 「Aを選択しても、Bを選択しても、どちらもAが選択された事になってしまう」というバグが発生しました。

弊社ではMackerelにてサービス監視をしていたりしますが、だいたいの場合 サービスが稼働している(これはページが開く)事の稼働は簡単でも正しいデータが入っているかの監視などは難しいものだと思います。 今回のケースでもどのように再発防止をしようか非常に頭を悩ませました。

という事で冒頭にあったように データをMackerelに集めてそれを監視する方法を取ることとしました。

データをMackerelに集める

弊社はデータストア層はRDBを使っているのでそれらのデータをMackerelにカスタムメトリクスとしてプロットする必要があります。

ここでは、 mackerel-plugin-json を使用しました。 mackerel-plugin-jsonに関しては以下記事が参考になるかと思います!

soudai.hatenablog.com

mackerel-plugin-json を活用する事で JSON さえ作れば、Mackerelにデータを定期的にプロットする事が出来ます。

JSON については 内部からのアクセスのみを許可したAPI を作成しました。 https://example.com/api/prot/reserve のような感じです。

アクセスするとこんな感じでJSONを吐き出すだけのエンドポイントです。

{"reserve_total": 9999}

これを用いて以下のように mackerel-agent.conf に記述を追加すると Mackerel に定期的にデータがプロットされるようになります。

[plugin.metrics.reserve]
command = "/path/to/mackerel-plugin-json -url=https://example.com/api/prot/reserve -prefix=reserve"

f:id:ikkitang1211:20200623133243p:plain

グラフで見るとこんな感じです。

データを比較する

データの比較については Mackerelにて提供された機能で実現します。 今回は 式による監視 で実現するようにしました。

f:id:ikkitang1211:20200623133609p:plain

mackerel.io

こちらはMackerelの有料ライセンスの機能として提供されてます。このリンク先にあるように特定のメトリクスに対して式を適用して算出した結果を監視対象として監視出来るようにする、という機能です。

f:id:ikkitang1211:20200705163902p:plain

式には以下の式が使えます。

mackerel.io

式を考えていく

移動平均とかきっと正しく使えば効果的な奴とかがあるのですが、ここは愚直に昨日との割合の比較を取る事にしました。

  • 割合は divide(metrics, metrics) で計算できます
  • 昨日の値は timeShift(metrics, duration) を使うことで計算できます
  • xxxx というホストのカスタムメトリクスは host(xxxx, custom.reserve.reserve_total) で取得出来ます
    • ホストID はURLから参照する事が可能です https://mackerel.io/orgs/{{ オーガニゼーション名 }}/hosts/{{ ホストID }}

諸々総合して式として記述するとこんな感じになります。 ( 1行で書いてOKです)

divide(
  host(xxxx, 'custom.reserve.reserve_total')
  ,
  timeShift(host(xxxx, 'custom.reserve.reserve_total'), 1d)
)

f:id:ikkitang1211:20200705163544p:plain

通知例

f:id:ikkitang1211:20200705202232p:plain

例えば、こんな感じで 予約数が一定割合を下回ると通知が来ます。

デプロイ後にこの通知が来た場合は 「ん?何かあるかな?」 って気にかける運用を想定しています。

運用してみて気付いた事

本当はもっと前にブログを書こうと思ったのですが、遅くなりまくり結果的に運用してから 4ヶ月程掛かっています。幸いにもこれが障害により通知された事は現状ありません。

が、まあ運用開始して不要不急な通知というのが結構来ました。以下です。

  • 0時前後に毎日通知が来る
  • 月曜日に常にWarning状態になる

1個目はまあ当然なんですが、00時付近は 当日の予約数は 0 なので予約が一定数入るまではWarning が来ます。

2個目は前日が日曜日という事で週末の予約数が活発である事により、日中ずっとしきい値を下回り続ける、という問題です。

どちらも当初は運用でカバー( 無視 )してたのですが、監視のアラートを無視する行為は本来すべきではありません。

オオカミ少年のように本当に重要な監視も軽視されるようになってしまうからです。監視アラートは本当に必要な時だけ通知されるべきであると思います。

ja.wikipedia.org

これを解決するのを悩んでたのですが、これをTwitterに雑につぶやいた所、 Mackerel の CRE の id:a-know さんに拾って頂きまして解決しました。

これにより運用を以下のように変えました。

  • 週末空け用監視ルール平常時監視ルール の2つを作成しそれぞれしきい値を調整する。
    • ダウンタイム設定により、月曜日は「週末空け用監視ルール」を有効化、その他の日は「平常時監視ルール」を使う
    • 監視時間を 00時20分〜23時59分 として 00時からの20分は無視する

監視時間については そもそものこの監視の目的として 「直前のデプロイによりバグが出たかを早期に発見する」 事を目的としていたので、遅くても17時以降はデプロイしない事を鑑みてこの時間を監視から除外する事にしました。

上記により問題点は全て解消 ( たまに 3連休の時に 火曜日に通知が発火されるとかはありつつも。。)したので、それなりに充実して運用しております。

(そもそも比較を1週間前とかにしても良かったかも。 何かの理由により却下した記憶があるような気がする。。)

まとめ

今回は アプリケーション監視として Mackerelを活用した事例についてお話させて頂きました。

この運用に載せるまでの苦悩が皆様のアプリケーションを安全に運用する為の一助になれば幸いです。

ご覧になって頂きありがとうございました。( ブログめちゃくちゃ遅くなっちゃってすみませんでしたっ)