Fluentd において特定パターンのデータをもっているメッセージ数をカウントする、およびメッセージ数に対してパターンごとの割合を算出する fluent-plugin-datacounter をリリースしました。また fluent-plugin-datacounter のようにメッセージの傾向を算出するためのプラグインに入れるデータを作るため、全メッセージからサンプリングを行う fluent-plugin-sampling-filter もリリースしました。
fluent-plugin-datacounter | RubyGems.org | your community gem host
fluent-plugin-sampling-filter | RubyGems.org | your community gem host
fluent-plugin-sampling-filter
リアルタイムに各種の統計情報を時系列で取りたいという用途はいろいろとありますが、そのような場合の多くは全メッセージを対象とする必要はありません。というかメッセージ流量が多い場合は統計処理の負荷(やそのためのノードへの転送負荷)が馬鹿にならず、適当な割合にサンプリングしたメッセージに対して処理をすればいいや、というケースが多いと思います。
これはそのためのものです。全メッセージの処理を行っている fluentd の設定のどこか(メッセージがきちんとparseされたあと)に out_copy と組合せてこれを突っ込んで、1/10 とか 1/100 とかだけを統計処理用に別タグとして出力してやるような使いかたを想定しています。
fluent-plugin-datacounter
メッセージのもつデータに対して正規表現でマッチングをかけ、該当するメッセージの件数、秒あたり件数、全メッセージに対する割合をそれぞれ計測します。分ごと、時間ごと、日ごとでカウントできるようにしてあります。また match した全メッセージに対してカウントすることも、matchしたうちからタグごとにカウントすることもできます。
正規表現ですが、値を文字列化(to_s)してからマッチングを実施するため、数値に対してもいちおう対応が可能です。自分の手元ではHTTPステータスコードを種類ごとに分類したりしています。 (2xx: ^2\d\d$ のように。)
ということで
組合せると、膨大な量のデータが流れるfluentdクラスタから適度な量だけをサンプリングし、HTTPステータスコードごとの割合を半リアルタイムに集計し、out_growthforecast と組合せることでこのようなグラフが出てくるわけですよ!
これをやるための設定例はこんな感じ。(accesslog.hoge みたいなタグのついたparse済みログが流れてくると思いねえ。)
<source> type forward </source> # out_sampling_filter strongly recommended <match accesslog.**> type sampling_filter interval 10 remove_prefix accesslog add_prefix sampled </match> <match sampled.**> type datacounter tag httpstatus aggregate tag count_key status pattern1 2xx ^2\d\d$ pattern2 3xx ^3\d\d$ pattern3 4xx ^4\d\d$ pattern4 5xx ^5\d\d$ </match> <match httpstatus> type stdout </match>
あとは GrowthForecastに最近加わったJSON出力 と組合せ、その出力をNagiosか何かで監視してやれば、唐突に HTTP STATUS 500 が25%を超えたり HTTP STATUS 4xx が90%を超えたりしたときにアラートを鳴らすことも簡単にできるというわけですね!