Mackerelでログ監視によく使われるcheck-logプラグインは、毎分ごとにログを見て追記された中で、検出対象文字列を発見したときにアラートを発報し、発見されなくなったら正常に戻ったものと見て自動クローズする、というのがデフォルトの挙動となっている。つまり、ずっと出続けるメッセージのようなものでなければ、発報のだいたい1分後にそれがクローズされることになる。
これが困るというときには、prevent_alert_auto_close = true
をプラグイン設定に追加する方法がある(チェック監視項目を追加するを参照)。これは自動クローズをしないことを宣言するオプションで、クローズはユーザーの手動作業に委ねられる。
しかし、こうした手動対処すべきアラートが蓄積すると、アラートの表示が日常になって注意を払わなくなってしまう。
ということでシェル芸人として、prevent_alert_auto_close = true
が使われている環境向けに、発報から一定時間過ぎたアラートをばっさりクローズするLinux用シェルスクリプトを書いてみた。そんなに長くないので全文掲載。Gistにも置いている。
#!/bin/bash CLOSE_AFTER_MINUTES="60" CLOSE_CHECK_ONLY=true DRYRUN= if [ -z "$(mkr --version 2>/dev/null)" ]; then echo "ERROR: Missing mkr. Install mkr package." exit 1 fi if [ ! -f "/etc/mackerel-agent/mackerel-agent.conf" -a -z "$MACKEREL_APIKEY" ]; then echo "ERROR: Define MACKEREL_APIKEY." exit 1 fi if [ "$CLOSE_CHECK_ONLY" ]; then RESULT=$(mkr alerts -jq '.[] | select(.type == "check") | [.id, .openedAt] | @tsv') else RESULT=$(mkr alerts -jq '.[] | [.id, .openedAt] | @tsv') fi echo "$RESULT" | { CLOSES= while read line; do # alertID openedAt array=($line) # bash if [ "$(date +"%s")" -ge "$(expr ${array[1]} + $CLOSE_AFTER_MINUTES \* 60)" ]; then CLOSES="$CLOSES ${array[0]}" fi done if [ "$CLOSES" ]; then $DRYRUN mkr alerts close --reason "auto closed because more than ${CLOSE_AFTER_MINUTES} minutes passed." $CLOSES fi }
頭のほうで設定用の変数定義をしているので、必要に応じて適宜変更していただきたい(格好良くコマンドラインオプションにしてもよいだろう)。
CLOSE_AFTER_MINUTES="60"
: 単位は分。アラートがオープンされて以来この分数が過ぎていたらクローズする。1日なら1440。CLOSE_CHECK_ONLY=true
: チェック監視のアラートだけを対象にする。「CLOSE_CHECK_ONLY=
」とするとほかの監視ルールも含むすべてのアラートが対象になる。実際のところ、check-log以外のものはメトリック閾値なりチェック結果なりに問題があれば再発報されるはずなので、それでもよいのかもしれない。DRYRUN=
: ドライラン指定。実際にはクローズせず、実行内容を表示するだけにするには「DRYRUN=echo
」とする。
実際の実行にはmkr
コマンドを使っている。現在の環境のものではなく別のオーガニゼーションに対して実行するのであれば、MACKEREL_APIKEY
環境変数も事前に指定しておこう。
$ ./deferclose.sh
または(別のオーガニゼーションに対して実行する場合)
$ MACKEREL_APIKEY=〜 ./deferclose.sh
棚卸しタイミングに限らず、適当にcronで回してもよいだろう。
以下は余談というかコードの説明。中身としてはだいぶシンプルで、少しシェル芸を込めている。
mkr alerts
コマンドでオープン中のアラート一覧JSONを取得する。mkr
コマンドはgo-jqを内包しているので、jq記法でJSONを整形できる。アラートIDと日付を取り出し(チェック監視だけの場合はtypeがcheckのもののみにフィルタする)、TSV化して出力する。
echo "$RESULT"
のように""
で囲んでいるのは改行を再現するため。
クローズにはmkr alerts close
を利用できるが、複数のアラートを一度でクローズするためにCLOSES
という変数を作っている。パイプ(|
)でつないだ先がサブシェルになるので、CLOSES
を構成して利用する部分はすべてその中で完結するよう{ }
でグループ化している。この挙動はわりとハマリポイントだねぇ(結局bash依存になっているので、lastpipe
指定すれば済むだけだったかも)。
array=($line)
でtsvから受けたタブ区切り文字列を分解している。ここがbash専用様になってしまった。TSVもCSVも微妙に扱いづらい(mkr jqのCSVには""
が含まれる)。
時間は、頻出テクニックのdate +"%s"
によるUnixエポック秒と、expr
コマンドを使った計算結果で比較している。expr
にはCLOSE_AFTER_MINUTES
変数の内容をそのまま展開させているので、実は式を変数内に含めてしまうこともできる(エスケープも考えないといけないが)。
シェル芸いろいろ便利だね。