fluentdでレコードにちょっとした処理をしてフィールドを追加する汎用的プラグインの比較

  • 52
    Like
  • 2
    Comment
More than 1 year has passed since last update.

先日つくったfluentdによる簡易ブックマーク結構使ってるんですが、今後細かい分析をしていきたいと考えた時、ドメイン別のブックマークの傾向とか見れるといいなと思いつきました。

{"tag":["tech","ruby"],"title":"hatena-bookmark | RubyGems.org | your community gem host","url":"https://rubygems.org/gems/hatena-bookmark"}

というjsonが来た時に、URLからドメイン名を抽出して

{"tag":["tech","ruby"],"title":"hatena-bookmark | RubyGems.org | your community gem host","url":"https://rubygems.org/gems/hatena-bookmark", "domain":"rubygems.org"}

というように加工してmongodbに保存したい。

ブックマークレットでjson組み立てる段階でdomain埋め込んでもいいんだけど、タグごとに大量にコピペしてふやしたのであれはもう弄りたくない…
というわけで、fluentd側でrubyの正規表現とかやってちょちょいとフィールド追加するプラグインどうせあるんでしょ?
と思って探したらプラグインたくさんありすぎて見つからないわ、それぞれ微妙に望む動きが実現できそうでできないわで結構困ったのでメモっておきます。。

探した場所はココとgoogleです。
http://fluentd.org/plugin/

fluent-plugin-map

<match bkmk.kogaidan.**>
  type map
  tag "mapped."+tag
  time time
  record {"domain"=>record["url"].scan(/^https?:\/\/(.*?)\//).first.first, "url"=>record["url"], "title"=>record["title"], "tag"=>record["tag"]}
</match>

最初に試してみたのはfluent-plugin-map。
https://github.com/tomity/fluent-plugin-map

このプラグインではrecordは加工してemitするハッシュそのものを表しています。
元のJSONにフィールドを追加したい場合、変更の不要なフィールドまで明示的に書くのでちょっとめんどいです。

また、fluentdの設定ファイルは好き勝手改行できるものではないので、横に長くなってしまいます。
本来は任意のフィールドだけ抜きだしてちょっと加工してemitするためのプラグインのようです。

元のtagを含めて拡張してemitできるのは良いかも。

追記:
recordがemitするハッシュそのものを表すなら、

record record["domain"]=record["url"].scan(/^https?:\/\/(.*?)\//).first.first;record

ってやったらできるかもしれないけどどうだろう

fluent-plugin-record-reformer

<match bkmk.kogaidan.**>
  type record_reformer
  output_tag reformed.bkmk
  domain ${url.scan(/^https?:\/\/(.*?)\//).first.first}
</match>

つぎにリストを眺めてたら見つけたのがfluent-plugin-record-reformer。
https://github.com/sonots/fluent-plugin-record-reformer

このプラグインでは明示的に指定されたフィールドにだけ処理が行われて、それ以外はなにも触らずにスルーしてemitしてくれます。ハイ、これがまさに探していたものでした。

${}の中では元のレコードに含まれるキーを変数として使えます。

ただしoutput_tagは書かれている文字列をそのまま使っているようで、元のタグの構造がなくなってしまうという問題があります。
これもfluent-plugin-forestなどを組み合わせれば解決できるかもしれませんが。

できそうで試したらできなかったプラグイン

先の二つを見つける前に試行錯誤しててぜんぜん思うようにいかなかったのが以下のふたつでした。

fluent-plugin-rewrite

これはレコードの情報をタグに含めて再emitする、レコードのフィールドを書き換えて再emitする、の二つはできますが既存のレコードの情報を使いつつ新たなフィールドを加える、という処理はできないものでした。

fluent-plugin-rewrite-tag-filter

こちらもタグの書き換えが主のプラグインです。