WebアプリやIoTデバイスが吐くログをFluentdに集約する環境を構築したり運用していると、次のようなことをやりたくなってきます。
- Fluentdに流れてくるメッセージの中身を確認したい
- メッセージを別のconfに流して動作を確認したい
これらのことをやろうとすると、場合によっては今動いているconfをいじったり、Fluentdを再起動したりする必要がでてきます。
しかしながら、matchが定義されていないtagだったらconfをいじらなくてはいけないし、type stdoutを加えるためだけにそれをやるのは手間だし、もう少し気軽に新しい設定を試したかったりします。さらに、それがproduction環境であれば、ちょっと設定を変えてみる、とかはあまりやりたくなかったりします。
そこで、fluentd-tcp-capturer
(https://github.com/takumakanari/fluentd-tcp-capturer) というツールを作りました。
What
TCPでFluentdに流れてくるパケットをキャプチャします。
キャプチャしたパケットを、Fluentdのメッセージに変換して表示したり、別のFluentdに流したりします。
Usage
Setup
gemをインストール
$ gem install fluentd-tcp-capturer
fm-cap
というコマンドが使えるようになります。
Usage: fm-cap [options]
-d, --device DEVICE Device name [default: eth0]
-p, --port PORT Fluentd port to capture [default: 24224]
--forward-host HOST If set, message will be forwarded to other Fluentd host
--forward-port PORT Fluentd port to forward message (used when --forward-host is set)
--debug Set loglevel DEBUG
テスト用のFluentdを次のような設定で立ち上げておきます。
<source>
@type forward
</source>
<match test.**>
@type stdout
</match>
メッセージをDumpする
別のターミナルでfam-cap
を立ち上げ、eth0/24224に流れてくるFluentd宛のメッセージをキャプチャします。
内部でpcapを利用しているので権限がいります。
$ sudo fm-cap
I, [2017-03-03T22:41:31.141436 #14088] INFO -- : Start capturing eth0/port=24224
もう一つ別のターミナルを立ち上げて、fluentdにメッセージを流してみます。
$ echo '{"message" : "hello"}' | fluent-cat test.hoge
そうすると、Fluentdのstdoutとは別に、fm-cap側でもメッセージがdumpされるのがわかります。
$ sudo fm-cap
I, [2017-03-03T22:41:31.141436 #14088] INFO -- : Start capturing eth0/port=24224
2017-03-03 13:41:34 +0000 | tag=test.hoge msg={"message"=>"hello"}
captureするnetwork deviceやFluentdのportはオプションで指定することができます。
$ sudo fm-cap -d lo0 -p 4567
メッセージを別のFluentdに転送する
--forward-host
、--forward-port
を指定すると、captureしたメッセージを、他のFluentdに転送することができます。
* 現時点で、全くセキュアな実装になっていない(TODO)ので、実行環境によっては注意が必要です,,
もう一つ、別のFluentdを立ち上げておきます。
<source>
@type forward
port 34224
</source>
<match fuga.**>
@type file
path /var/log/fuga
time_slice_format %Y%m%d
time_slice_wait 10m
time_format %Y%m%dT%H%M%S%z
</match>
fm-cap
を立ち上げます。
$ sudo fm-cap --forward-host localhost --forward-port 34224
I, [2017-03-03T22:46:31.878876 #14564] INFO -- : Start capturing eth0/port=24224
これで、24224に流れてきたメッセージが、34224でlistenしている別のFluentdにも転送されるようになります。
$ echo '{"message" : "hello"}' | fluent-cat fuga.hoge
$ sudo fm-cap --forward-host localhost --forward-port 34224
I, [2017-03-03T22:46:31.878876 #14564] INFO -- : Start capturing eth0/port=24224
I, [2017-03-03T22:46:34.577661 #14564] INFO -- : Forwarded message to other-fluentd-node:4567
この例だと、24224で待っているFluentdには、tag fuga.**
のmatchが設定されていないので何も出力されませんが、新たに立ち上げた34224では拾われて、ファイルにメッセージが出力されます。
まとめ
まだまだbuggyなのと、例えばdumpするときのtimestampのtimezoneが指定できなかったり等、いろいろ改善の余地があります
(おそらく)secure forwardには使えません。また使うべきではない。。
内部的に走っているのはpcapを利用したパケットキャプチャなので、実行する環境によってはパフォーマンスに影響をあたえる場合があり、考慮が必要です。
TODO
- httpとか別のprotocolにも対応できるとよい
- もう少しsecureにしたい