[fluentd] 同じメッセージを間引く fluent-plugin-suppress を書いた

fluentdで、なんらかの理由で大量に同じメッセージが送信されてきたときに、それを渡す output plugin によってはちょっと困ることがあります。たとえば out_mail を使うとメールが大量に飛んでしまう。

ということで、同じ (指定したkeyの値を連結したものが同じ) メッセージを適当に間引いてくれるプラグインを書きました。

使いかた

<match foo.**>
  type           suppress
  interval       10
  num            2
  attr_keys      host,message
  add_tag_prefix sp.
</match>

[interval] 秒間に [num] メッセージはタグが書き換わって再 emit され、それを超えた分は捨てられます。「同じメッセージ」の判断は、tag と attr_keys で指定したカラムの値を "\0" で連結した文字列で行われます。

入力例

  2012-11-22T11:22:33 foo.info {"id":1,"host":"web01","message":"error!!"}
  2012-11-22T11:22:34 foo.info {"id":2,"host":"web01","message":"error!!"}
* 2012-11-22T11:22:35 foo.info {"id":3,"host":"web01","message":"error!!"}
* 2012-11-22T11:22:36 foo.info {"id":4,"host":"web01","message":"error!!"}
  2012-11-22T11:22:37 foo.info {"id":5,"host":"app01","message":"error!!"}
* 2012-11-22T11:22:38 foo.info {"id":6,"host":"web01","message":"error!!"}
* 2012-11-22T11:22:39 foo.info {"id":7,"host":"web01","message":"error!!"}
* 2012-11-22T11:22:40 foo.info {"id":8,"host":"web01","message":"error!!"}
  2012-11-22T11:22:45 foo.info {"id":9,"host":"web01","message":"error!!"}
(* = 間引かれるメッセージ)

出力例

2012-11-22T11:22:33 sp.foo.info {"id":1,"host":"web01","message":"error!!"}
2012-11-22T11:22:34 sp.foo.info {"id":2,"host":"web01","message":"error!!"}
2012-11-22T11:22:37 sp.foo.info {"id":5,"host":"app01","message":"error!!"}
2012-11-22T11:22:45 sp.foo.info {"id":9,"host":"web01","message":"error!!"}

この例だと、10秒間の間に "host": "web01", "message":"error!!" のメッセージは2つのみ通過、id:3,4,5,6,7,8 は捨てられます。id:9 は10秒以上経過しているので通過。id:5 は "host":"app01" なので(別のメッセージなので) 通過します。

通知など、用途によっては便利かもしれませんね!