fluent-agent-lite と td-agent で、小さくはじめる fluentd
fluentdを使ってみたいけど、「JSONでシリアライズしなくていいのに・・・生でいいのに・・・」と思ってなかなか使い出せないというケースはままあるのではないでしょうか。
こんなときに困ってしまうからですよね。
- rsyncやscpで毎日深夜にやってくる生ログを解析するスパゲッティスクリプトたちを使えなくなってしまう
- アプリケーションサーバにログをパースさせるための負荷をかけたくない
それでも使ってみたい、現存の古臭い解析機構をアクティブにしたまま、徐々にfluentdによる先鋭的なログ解析を始められたらいいなと思っている方、
fluent-agent-lite と td-agent で、fluentd を小さくはじめてみたらいいと思います。
結論を先に言うと、fluent-agent-lite + fluent-plugin-file-alternative + fluent-plugin-file-parser + out_exec_filterの構成でだいたいの場合間違いないです。
小さくはじめて・・・
fluentdと周辺ツール
インストール | 特徴など | |
---|---|---|
fluentd | gem | OS,rbenv,rvmなど、システムにruby環境が必要 |
td-agent | リポジトリを追加して、(yum|apt-get) install | ruby環境を内包しているので、システムのruby環境に依存せず非破壊的に導入可能 |
fluent-agent-lite | インストールスクリプト or rpmbuildしてrpmをインストール | perlで書かれているが、依存モジュールなどを内包するので、システムのperl環境に依存せず非破壊的に導入可能。生ログファイルをtailし、パース処理せずにログを送信 |
td-agent-lite | - | v.11で登場予定。パース処理をしてからログを転送。in_tailとout_forwardだけのtd-agent? |
特徴などをざっと。
今回登場するのは、td-agentとfluent-agent-liteです。
生ログをfluentdで送ってみよう
まずは生ログをfluentdのプロトコルでリアルタイムに転送してみるところからやってみます。
この項で、夜間バッチのscpやrsyncを捨てられるようになる(といいですね)。
recipe
- 送信側サーバ
- fluent-agent-lite
- 受信側サーバ
- td-agent
- fluent-plugin-file-alternative
fluent-agent-lite インストール (送信側)
fluent-agent-liteは、perlで書かれて、パースを行わずにfluentdのプロトコルを用いてログを送ってくれるツールです。
単純にログを送るだけならシンプルな設定をすればすぐに使うことができるし、細かいパラメータ調整も出来るスグレモノです。
冗長構成も取れます。
インストール手順等含め、詳しくは作者のtagomorisさんのブログをごらんください。
#fluentd 用ログ収集専用のエージェント fluent-agent-lite 書いた - tagomorisのメモ置き場
僕はrpmを作って各サーバにデプロイして使っています。
td-agent + fluent-plugin-file-alternative インストール (受信側)
fluentdはrubyで書かれています。
非rubyな環境ではruby環境を用意しなくてはならないし、rubyな環境であっても、バージョンが古かったりなどした場合には少し大変です。
td-agentは、自分の中にruby環境を内包してfluentdを動かしてくれるので、ruby環境を用意しなくても、非破壊的かつ簡単にfluentdをはじめることができます。
インストールはリポジトリを追加してパッケージをインストールするだけ。簡単。
Installing td-agent for Redhat and CentOS
Installing td-agent for Debian and Ubuntu
td-agentが入ったら、fluent-gemコマンドでfluent-plugin-file-alternativeを入れます。
fluent-gemコマンドのパスは環境によって異なるので注意。
# /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-file-alternative
fluent-agent-lite 設定 & 起動 (送信側)
単純にログを送るだけのシンプルな設定です。環境に合わせて調整する場合はtagomorisさんのgithubを見るといいです。
また、タグにホスト名を埋めてますが、このへんはchefとかでよしなにやるといいと思います。(plackで設定ファイルを動的に・・・とかって話を誰かがしていたような気もするけど忘れた)
# vim /etc/fluent-agent-lite.conf TAG_PREFIX="apache" LOGS=$(cat <<"EOF" access.app01 /var/log/httpd/access_log error.app01 /var/log/httpd/error_log EOF ) PRIMARY_SERVER="log_server:24224"
# /etc/init.d/fluent-agent-lite start
デフォルトでは、/tmp/fluent-agent.logにログを吐きますので、起動したら異常がないか確認しましょう。
異常がない場合は何も吐かない(はず)です。
詳しいログが必要な場合は、設定ファイルに'LOG_VERBOSE="yes"'を追記して起動するといいですね。
td-agent 設定 & 起動 (受信側)
受信側の設定です。
# vim /etc/td-agent/td-agent.conf <source> type forward </source> <match apache.access.**> type file_alternative path /tmp/httpd/access.*.log time_slice_format %Y%m%d output_include_time false output_include_tag false output_data_type attr:message add_newline true </match> <match apache.error.**> type file_alternative path /tmp/httpd/error.*.log time_slice_format %Y%m%d output_include_time false output_include_tag false output_data_type attr:message add_newline true </match>
# /etc/init.d/td-agent start Starting td-agent: [ OK ]
td-agentのログは、/var/log/td-agentに出力されます。
'Starting td-agent:[ OK ]'と表示されてもエラーログが出ている場合があるので、起動したら必ずログを確認しましょう。
異常がない場合は、概ねこんな感じで吐かれているはず。
2012-08-24 11:56:37 +0900: starting fluentd-0.10.25 2012-08-24 11:56:37 +0900: reading config file path="/etc/td-agent/td-agent.conf" 2012-08-24 11:56:37 +0900: adding source type="forward" 2012-08-24 11:56:37 +0900: adding match pattern="apache.access.**" type="file_alternative" 2012-08-24 11:56:37 +0900: adding match pattern="apache.error.**" type="file_alternative" 2012-08-24 11:56:37 +0900: listening fluent socket on 0.0.0.0:24224
確認
ここまでで、app01サーバから、log_serverサーバに生ログを送ることが出来るようになりました。
更新がアクティブなログにはハッシュ値が付与され、更新が停止すると除外されます。
今まで保存していたログとファイル名が違うので解析スパゲッティスクリプトたちが使えなくなってしまうとお嘆きかも知れませんが、内容はしっかりまんま生ログなのでどうにかなるでしょう。
# cd /tmp/httpd # ls -lrt total 68916 -rw-rw-rw- 1 td-agent td-agent 3270233 Aug 24 00:10 error.20120823.log -rw-rw-rw- 1 td-agent td-agent 58868447 Aug 24 00:10 access.20120823.log -rw-rw-rw- 1 td-agent td-agent 193356 Aug 24 14:45 error.20120824.b4c7f94e7f34b2191.log -rw-rw-rw- 1 td-agent td-agent 8142756 Aug 24 14:45 access.20120824.b4c7facd8e6800702.log
もう日次バッチのscp,rsyncを捨てられますよね。
生ログを保存しつつ、パースもする
せっかくfluentdを使うのだから、ログをパースして、データをカウントしてグラフにしたり*1、シングルノードでオンメモリで収まるサイズに限定してキャッシュストレージとして使うには最強と噂のMongoDBにデータをストアしたいとか考えるのが普通ですよね。
fluent-plugin-parserを使う
fluent-agent-liteで送られてくるデータは、'message'というキーがついています。
例としてaccess_logを対象とし、'message'キーのデータをパースして、別のファイルに書きだしてみます。
access_logのフォーマットは、一般的なcombinedの末尾にレスポンスタイムを足した形式とします。
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %D" combined
td-agent.confを修正します。
type copyを用いて、生ログを保存しつつ、パースも行います。
# vim /etc/td-agent.conf <match apache.access.**> type copy <store> type file_alternative path /tmp/httpd/access.*.log time_slice_format %Y%m%d output_include_time false output_include_tag false output_data_type attr:message add_newline true </store> <store> type parser add_prefix parsed format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" (?<response>[^ ]*))?$/ time_format %d/%b/%Y:%H:%M:%S %z key_name message </store> </match> <match parsed.apache.access.**> type file path /tmp/httpd/parsed.apache.access </match> <match apache.error.**> type file_alternative path /tmp/httpd/error.*.log time_slice_format %Y%m%d output_include_time false output_include_tag false output_data_type attr:message add_newline true </match>
書き換えたら、td-agentを再起動します。ログの確認をお忘れなく。
# /etc/init.d/td-agent restart Shutting down td-agent: [ OK ] Starting td-agent: [ OK ]
結
生ログもとっておきたくて、さらに色々やってみたいとかだったら、とりあえずアプリケーションサーバにはfluent-agent-liteだけ入れておけば間違いないですね。
アプリケーションサーバにtd-agentを入れていろいろやらせるとなると、パースなどの処理で負荷が上乗せされることになるし*2、変更があったときにデプロイするのめんどくさいし*3。
さらに細かく何かやりたくなったら、受信側のtd-agentで処理させてあげればいいんじゃないかなと思っています。
アプリケーションサーバよりは台数も少ないだろうし、デプロイも比較的容易でしょう。
それじゃあマサカリ待ってるわね。enjoy!!