たごもりすメモ

コードとかその他の話とか。

fluent-plugin-notifier と fluent-plugin-ikachan の話

リリースしてはいたものの手元でちゃんと使っていなかったプラグインふたつ、をいよいよちゃんと使いはじめた。そのついで(?)にちゃんとテストを書いたりREADMEを書いたりしたので、せっかくだからここにも書いておく。

fluent-plugin-notifier

Fluentdで流通するメッセージを相手に数値範囲や文字列検査(正規表現)により異常を検出しアラート(を示すメッセージ)を出してやろう、というプラグイン

tagomoris/fluent-plugin-notifier · GitHub
fluent-plugin-notifier | RubyGems.org | your community gem host

使いかたはたぶん例を見ればわかる……んじゃないかなー。こんな。

<match apache.log.**>
  type notifier
  <def>
    pattern apache_duration
    check numeric_upward
    warn_threshold  800000
    crit_threshold 1000000
    target_keys duration
  </def>
  <def>
    pattern status_500
    check string_find
    warn_regexp 5\d\d
    crit_regexp 500
    target_key_pattern ^status.*$
    exclude_key_pattern ^status_ignore_.*$  # key name not to notify about...
  </def>
</match>

'numeric_upward' は閾値(warn/critそれぞれについて指定する)を超えたらアラートメッセージを出す。'numeric_downward'はその逆。'string_find' は正規表現にマッチするか検査してアラートを出す。検査の定義は任意個数書けるので match 節でがばっと多めのメッセージを対象にしておいて def 内での target_keys *1で相手を絞る、というようにしてもいいと思う。
上の例には出してないけど、連続する同じアラートメッセージ*2は任意の間隔・回数で抑制する方法を持っていて、デフォルトは以下のようになっている。

  • 1分毎に5回まで送出
  • 5分毎に5回まで送出
  • 以後は30分毎

この間隔(intervals)と回数(repetitions)は全体でも def 毎でも指定できるので、細かく指定したい人にも不満はあまりないんじゃないかなー。あったらぜひ教えてほしい。

fluent-plugin-ikachan

全世界のWebサービス開発が依存しているという噂のIRCはもちろんみんな使っていると思うが、IRCの任意のチャンネルにあちこちのシステムから発言をポストするのは意外に面倒で、そのためのモジュールみたいなのは各言語にあるんだけど、それをいちいち組み込んでまわるのはできれば避けたい。
そのように当然思う人達のためにYappoさんが書いた ikachan というツールがある。要はHTTPで簡単に発言をポストできる IRC Proxy Server ですね。今やCPANにもあります。

ikachan - IRC message delivery by HTTP - metacpan.org

で fluent-plugin-notifier でアラートメッセージを生成したらどこに投げるかというと当然IRCに投げたいので ikachan 経由になるわけですよ。そのようなプラグインも作りました。……だいぶ前に。

tagomoris/fluent-plugin-ikachan · GitHub
fluent-plugin-ikachan | RubyGems.org | your community gem host

ikachanのサーバ、対象チャンネル、出力するフィールド名のリスト、およびどうフォーマットするかを以下のように与えてやれば、目的のチャンネルに notice でポストしてくれます。

<match message.*>
  type ikachan
  host ikachan.local
  port 4979
  channel watching
  out_keys target_host,num_value,message
  message %s(%s): %s
</match>

このようにしておけば {'target_host' => 'hoge.local', 'num_value' => 100, 'message' => 'fluentd message\' message...'} というメッセージを受け取ったとき、以下のようにIRCに出力されるわけですね。

11:48 ikachan: hoge.local(100): fluentd message's message...

便利!

組合せて実現するFluentdでの監視システム

たとえば以下のようにします。

  • fluent-plugin-datacounter でHTTPステータス 5xx の数および全リクエスト中のパーセンテージをカウント
    • 後述する処理の他に fluent-plugin-growthforecast でグラフにも出力しておく
  • fluent-plugin-notifier で 5xx_percentage の数値を検査、10以上でwarn、30以上でcritとする
  • notifier の出力を fluent-plugin-ikachan で受けIRCにポスト

こうするだけで、いい感じに頻度調整も行われつつ、5xxステータスの量が跳ね上がった場合に以下のようなメッセージがIRCにポストされるわけですよ。

11:48 ikachan: HTTP Status warn [2012-07-20 11:48:04 +0900] serviceX_5xx_percentage: 10.0 (threshold 10.0) http://gf.devops.local/view_graph/accesslog/httpstatus/serviceX_5xx_percentage

我々はIRCにポストされてくるGrowthForecastのURLをぽちっとクリックするだけで、時系列での5xxステータスコードの割合の推移を確認し、これが即座に対処すべきなのか、アプリケーション担当者をつついてみるべきなのか、とりあえず放っておいていいものなのか、そういったことを考えることができるようになるというわけですね!

ちなみに上記メッセージは以下のような fluent-plugin-ikachan の設定で出してます。fluent-plugin-notifier はイベントを検出した日時を message_time というフィールドに可読文字列で入れるため、それを出力しておけばIRCに出てくるというわけですね。検出閾値も threshold というフィールドに入っているため、いちいち設定を確認する必要はありません。
GrowthForecastのグラフURLは fluent-plugin-growthforecast の設定と合わせておけばよいでしょう。

<match notification.*>
  type ikachan
  host ikachan.devops.local
  channel foobar
  out_keys level,message_time,target_key,value,threshold,target_key
  message HTTP Status %s [%s] %s: %s (threshold %s) http://gf.devops.local/view_graph/accesslog/httpstatus/%s
</match>

どうよこれ! べんり! 改めて見てみるとぽんぽん細かくエラー率が跳ね上がってるサービスあるもんですね!

……と思ったんだけど、リクエスト数の少ないサービスだと特に夜間にGooglebotなどの襲来により4xxが跳ね上がって検出してしまうなど、ちょっと微妙な点が見えてないこともないです。どうしよっかなー。

*1:もしくは target_key_pattern + exclude_key_pattern

*2:検査対象の tag + key_name と警告レベル(warn/crit)の組合せで判定