fluent-plugin-uniqcountを公開しました
概要
fluent-plugin-uniqcountは、指定期間範囲において、設定で指定した属性ごとにイベント発生件数をユニークにカウントし、結果の上位N件を定期出力するfluentdプラグインです。SQLでいうところの:
SELECT key1, COUNT(key2) AS key2_count, COUNT(DISTINCT(key2)) AS key2_uniq_count FROM records WHERE time BETWEEN T1 AND T2 GROUP BY key1 ORDER BY key2_count DESC LIMIT 0, N;
に相当します。
fluent-plugin-uniqcountを使うと、
などが集計可能です。
特徴
fluent-plugin-uniqcountは、単位時間あたりのトラフィック量をN、集計対象区間長(設定項目: list*_span)をTとしたときに、以下のような特徴を備えています。
- イベント1件あたりのプラグインへの入力コストは O(logNT)。単位時間あたりだと O(N logNT)。
- プラグインの出力コストは O(logNT)。
- 消費メモリは O(NT)。
- ユニークカウントである(F5リロードなどでランキングが跳ね上がらない)。
- 直近(T秒前〜現在)の集計結果が可能である(集計対象区間が時間経過とともにスライドする)。
- 一つの集計単位を「リスト」と呼び、独立した設定を持つ任意の数のリストを保持することができる(最大10個まで)。
- fluentdのイベント受信時刻ではなく、レコード内のタイムスタンプを基に集計を行うことができる(未設定時はイベント受信時刻を用いる)。
- appサーバからfluentdにイベントが到達する時間のゆらぎを吸収するため、集計対象区間の終点を現在時刻から過去へオフセットすることができる(list*_offset: 転送に関与したfluentdのflush_interval値を考慮して設定する)
設定
項目
- list*_label : 出力レコードに付与されるラベル文字列
- list*_time : イベント時刻フィールド名(UNIXタイムスタンプ形式 - 省略時はfluentdにおけるイベント受信時刻が使われる)
- list*_key1 : グルーピングに用いるフィールド名
- list*_key2 : カウント対象フィールド名
- list*_span : 集計対象区間長(秒)
- list*_offset : 集計対象区間終点のオフセット値(秒)
- list*_out_tag : 出力レコードに付与されるタグ
- list*-out_num : 出力件数(上位N件)
- list*_out_interval : 出力間隔(秒)
設定例
入力イベントが以下のようなフォーマットを持っているとき、
site.access_log: {"at":1367820029,"uri":"http://www.careerlink.vn/","remote_ip":168364289} ...
次のような設定で、各spanにおけるURLランキングを得ることができます。
<match site.access_log> type uniq_count list1_label min list1_time at list1_key1 uri list1_key2 remote_ip list1_span 60 list1_offset 3 list1_out_tag trends.min list1_out_num 5 list1_out_interval 1 list2_label day list2_time at list2_key1 uri list2_key2 remote_ip list2_span 86400 list2_out_tag trends.day list2_out_num 5 list2_out_interval 10 </match>
出力例は以下のようになります。
trends.min: {"label":"min","ranks":[{"key1":"http://www.careerlink.vn/","rank":0,"key2_uniq_count":13},{"key1":"http://www.careerlink.vn/file/71ca7183087cce9f04fc559ce37738e9","rank":1,"key2_uniq_count":12}, { ... }, ...],"at":1367840734} trends.day: {"label":"day","ranks":[{"key1":"http://www.careerlink.vn/","rank":0,"key2_uniq_count":8034},{"key1":"http://www.careerlink.vn/file/065d88676460f47d99ec59263c650f54","rank":1,"key2_uniq_count":7735},{"key1":"http://www.careerlink.vn/file/71ca7183087cce9f04fc559ce37738e9","rank":2,"key2_uniq_count":7266}, { ... }, ... ],"at":1367840734}
TODO
- gem化
- 省メモリ化のため、オブジェクトの生成数をもっと減らしたい