in_execプラグインとはなにか
外部のスクリプトを定期的・恒久的に実行し、スクリプトの標準出力を読み取る機能を提供するプラグイン。サードパーティ製ではなく、Fluentdに標準で組み込まれている。
詳細は公式マニュアル参照。
使ってみる
まずは、実行対象の外部スクリプトをRubyで適当に作る。
ファイル名はsample.rbとし、/tmp以下に配置する。
# sample.rb
print '{"one": 1, "two": "2", "three": ["a", "b", "c"]}';
次にfluentdの設定ファイル(/etc/td-agent/td-agent.conf)を以下のように編集する。
# INPUT
<source>
type exec
tag in_exec_test
# 実行するコマンド
command ruby /tmp/sample.rb
# commandで指定した外部スクリプトの出力フォーマットをjsonに設定
format json
# 5秒毎に実行する
run_interval 5s
</source>
# OUTPUT
<match in_exec_test>
type file
# 以下のファイルに出力する
path /tmp/in_exec_test.log
</match>
td-agentを再起動する。
$ sudo service td-agent restart
Shutting down td-agent: [ OK ]
Starting td-agent: [ OK ]
OUTPUTプラグインによる出力結果を確認する。
$ tail -f /tmp/in_exec_test.log.20141121.b508590dabae46c41
2014-11-21T19:09:34+09:00 in_exec_test {"one":1,"two":2,"three":"san","four":["a","b","c"]}
2014-11-21T19:09:39+09:00 in_exec_test {"one":1,"two":2,"three":"san","four":["a","b","c"]}
2014-11-21T19:09:44+09:00 in_exec_test {"one":1,"two":2,"three":"san","four":["a","b","c"]}
.
.
.
設定通り5秒毎に出力されている。
出力内容もスクリプトで実行した結果そのまま。
TSV形式でも実行してみる
in_execはJSON、TSV、MessagePackの3種類のフォーマットに対応しているようで、もう1つくらい試してみたいと思ったのでTSV形式でもやってみる。
まず、/tmp/sample.rbを以下のように編集する。
print "foo\tbar\tbaz";
/etc/td-agent/td-agent.confも編集する。
# INPUT
<source>
type exec
tag in_exec_test
# 実行するコマンド
command ruby /tmp/sample.rb
# commandで指定した外部スクリプトの出力フォーマットをtsvに設定
format tsv
# TSV形式の場合はkeysにkey名を指定する必要がある
keys one,two,three
# 5秒毎に実行する
run_interval 5s
</source>
# OUTPUT
<match in_exec_test>
type file
# 以下のファイルに出力する
path /tmp/in_exec_test.log
</match>
td-agentを再起動する。
$ sudo service td-agent restart
Shutting down td-agent: [ OK ]
Starting td-agent: [ OK ]
OUTPUTプラグインによる出力結果を確認する。
$ tail -f /tmp/in_exec_test.log.20141121.b508590dabae46c41
2014-11-21T19:19:15+09:00 in_exec_test {"one":"foo","two":"bar","three":"baz"}
2014-11-21T19:19:20+09:00 in_exec_test {"one":"foo","two":"bar","three":"baz"}
2014-11-21T19:19:25+09:00 in_exec_test {"one":"foo","two":"bar","three":"baz"}
.
.
.
keysで指定したone、two、threeがそれぞれJSONデータのキー名になっていて、sample.rbのタブ区切りでの出力内容が順番に値になっている。
【番外編】formatをJSONに指定しつつ、JSONでないデータを出力した場合にどうなるか
個人的に少し気になったので試す。
source.formatにjsonと指定しつつ、スクリプトではTSV形式の出力を行ってみる。
というわけで設定ファイル(/etc/td-agent/td-agent.conf)だけ編集する。
# INPUT
<source>
type exec
tag in_exec_test
command ruby /tmp/sample.rb
format json
run_interval 5s
</source>
# OUTPUT
<match in_exec_test>
type file
path /tmp/in_exec_test.log
</match>
再起動。
$ sudo service td-agent restart
Shutting down td-agent: [ OK ]
Starting td-agent: [ OK ]
ログを見る。
$ tail -f /tmp/in_exec_test.log.20141121.b508590dabae46c41
.
.
.
何も出力されていない。
fluentd自体のログにエラーが出力されていないか見てみる。
$ sudo tail -f /var/log/td-agent/td-agent.conf
2014-11-21 19:28:17 +0900 [error]: exec failed to run or shutdown child process error="lexical error: invalid string in json text.\n foo\tbar\tbaz\n (right here) ------^\n" error_class="Yajl::ParseError"
2014-11-21 19:28:17 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.55/lib/fluent/plugin/exec_util.rb:39:in `parse'
2014-11-21 19:28:17 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.55/lib/fluent/plugin/exec_util.rb:39:in `call'
2014-11-21 19:28:17 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluentd-0.10.55/lib/fluent/plugin/in_exec.rb:124:in `run_periodic'
めっちゃエラー出てた。5秒毎に出てるし当然か。
出力されているフォーマットがJSONじゃないぞって感じで怒られている。
この後、設定は元に戻しました。
以上、in_execを使ってみたまとめでした。