ログをFluentdで集めて、Norikraで集計して、Kibanaで表示、ということをやっていたのですが、ログ上はidしか流れてこないので、Kibanaで表示するときに不便な状況でした。そこで、idを名前に変換する単純なKey-valueのTSVファイルを用意して、Norikra上で変換を行うためのUDF(norikra-udf-lookup)を書きました。
インストール
Gemfileに以下を書いてbundle install
するか、
gem 'norikra-udf-lookup'
手でgem
コマンドでインストールします。
$ gem install norikra-udf-lookup
その後Norikraサーバを再起動します。(Norikra 1.3.0以降だとkill -HUPをNorikraプロセスに送ればいけるかも。自分はなぜかできなかったのですが。)
UDFの使い方
まずNorikraサーバ上に、key-valueペアのTSVファイルを用意します。
% cat /tmp/lookuptest.tsv
1 aaa
2 bbb
3 ccc
このTSVファイルを使ってkeyを値に変換するために、3つの文字列型引数を取る、lookup_tsvというUDFが用意されています。引数はTSVファイルのパス、入力フィールド、TSV内に値が見つからなかった時のデフォルト値、です。
こんな感じのクエリを登録して使います。
SELECT
id, lookup_tsv('/tmp/lookuptest.tsv',id,'not found') as name, count(*) as cnt
FROM
test_stream.win:time_batch(1 min)
GROUP by id
この状態で、イベントを流してみます。
% echo '{"id":"1"}' | norikra-client event send test_stream
% echo '{"id":"2"}' | norikra-client event send test_stream
% echo '{"id":"3"}' | norikra-client event send test_stream
% echo '{"id":"4"}' | norikra-client event send test_stream
すると、lookup_tsv
関数に渡されたid
フィールドが変換されて出てきます。TSVに見つからなかった値は、第三引数に指定した文字列(ここでは"not found")に変換されます。
% norikra-client event sweep
{"time":"2015/07/28 12:13:24","query":"lookuptest","id":"3","cnt":1,"name":"ccc"}
{"time":"2015/07/28 12:13:24","query":"lookuptest","id":"2","cnt":1,"name":"bbb"}
{"time":"2015/07/28 12:13:24","query":"lookuptest","id":"1","cnt":1,"name":"aaa"}
{"time":"2015/07/28 12:13:24","query":"lookuptest","id":"4","cnt":1,"name":"not found"}
lookup_tsvの引数をlookup_tsv("/path/to/tsv",id,id)
みたいにすれば、見つからなかった値はそのまま出力、になります。
TSVファイルの更新については、ファイルのタイムスタンプを1分ごとに見ていて、更新があったら再読み込みするようになっています。
最後に
と、言うことで初めてNorikraのUDFを書いてみました。NorikraのUDFはnorikra-udf-mockを参考にして簡単に書くことができました。簡単な割に以外にサードパーティのUDFが無いのは、大体Norikra(Esper)の標準機能でなんとかなってしまうからなのかな。
あと、今回みたいにidを名前に変換して表示したい、という要件の場合画面側で変換できるなら、そっちの方が良い場合があるかも知れません。Kibanaの場合、多分今はできなくて、https://github.com/elastic/kibana/issues/4361 が実現するとできるようになるかな、と期待しています。