【Fluentd】アプリケーションログを転送し、オリジナルと同じ状態で出力する

前回の課題として、受信サーバ側で出力する際のログのフォーマットが変わってしまう、というものがありました。「fluent-agent-lite、もしくはfile-alternativeプラグインを使用することで対処できる」というコメントを頂きましたので、今回は、それらを検証してみたいと思います。

fluent-agent-liteは送信専用のエージェントで、ログの増分を他のfluendへ送信する機能を持ちます。Perlで作成されており、ログ増分を正規表現でパースしないため、動作が軽いのが特徴です。一方、fluent-plugin-file-alternativeはfluentdのファイル出力用プラグインで、ログ出力時の形式をカスタマイズすることができるようです。

1. 受信サーバ側でfluent-plugin-file-alternativeを使用する

それでは、最初にfile-alternativeプラグインのみを使用して設定してみます。前回の設定作業に加えて、受信サーバ側にこのプラグインをインストールします。ここでは、fluentdに組み込まれているRubyのfluent-gemコマンドを使用してインストールを行います。ちなみに、RHEL 6.xのRubyはバージョンが古いため、OSのパッケージ版のgemコマンドを使用してインストールすることはできません。

(送信サーバ側)
# cd /usr/lib64/fluent/ruby/bin
# ./fluent-gem install fluent-plugin-file-alternative
Fetching: fluent-plugin-file-alternative-0.1.4.gem (100%)
Successfully installed fluent-plugin-file-alternative-0.1.4
1 gem installed
Installing ri documentation for fluent-plugin-file-alternative-0.1.4...
Installing RDoc documentation for fluent-plugin-file-alternative-0.1.4...

これで、プラグインのインストールは完了です。次に、受信サーバ側のtd-agentの設定ファイルを編集します。なお、/etc/td-agent/td-agent.confについては、前回の設定内容を全てご破算とし、下記の1行のみを記述します。

(受信サーバ側)
(/etc/td-agent/td-agent.conf)
include plugin/*.conf

(/etc/td-agent/plugin/file-alternative.conf)  ※新たに作成
<source>
  type forward
</source>
<match httpd.error>
  type file_alternative
  path /var/log/td-agent/httpd.log
  #compress gzip
  output_include_time false
  output_include_tag false
  output_data_type attr:message
  time_slice_format %Y%m%d
  #add_newline false
</match>

設定ファイル編集後は、受信サーバ側のtd-agentサービスを再起動します。

(受信サーバ側)
# service td-agent restart
Shutting down td-agent:                                    [  OK  ]
Starting td-agent:                                         [  OK  ]

次に、送信サーバ側のtd-agentの設定を少し変更します。これにより、1行分のログを全てmessageという名前でキャプチャして転送します。

(送信サーバ側)
# forwarding httpd error_log
<source>
  type tail
  # 下2行をコメントアウト
  #format /^\[(?<time>[\w: ]+)\] \[(?<level>\w+)\] (?<message>.+)$/
  #time_format %a %b %d %H:%M:%S %Y
  # 下の1行を追加
  format /^(?<message>.+)$/
  path /var/log/httpd/error_log
  pos_file /var/log/td-agent/httpd-error_log.pos
  tag httpd.error
</source>
<match httpd.error>
  type forward
  <server>
    host 192.168.XXX.XXX  ※受信サーバのIPアドレス
  </server>
</match>

設定ファイル編集後は、同様に送信サーバ側のtd-agentサービスを再起動します。これで準備完了です。早速、送信サーバ側のhttpdを再起動して、ログが転送されることを確認します。

(送信サーバ側)
# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]

(受信サーバ側)
# tail /var/log/td-agent/httpd.log.20130518.b4dcf7040e0c42931
[Sat May 18 14:02:31 2013] [notice] caught SIGTERM, shutting down
[Sat May 18 14:02:31 2013] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Sat May 18 14:02:31 2013] [notice] Digest: generating secret for digest authentication ...
[Sat May 18 14:02:31 2013] [notice] Digest: done
[Sat May 18 14:02:31 2013] [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations

期待どおり、送信サーバ側のhttpdのログと全く同じ内容が、受信サーバ側に出力されました。

2. 送信サーバ側でtd-agentの代わりにfluent-agent-liteを使用する

ここまでで当初の目的は達成できたのですが、折角なのでfluent-agent-liteの方も検証してみたいと思います。GitHubからzipアーカイブを入手し、解凍してインストーラを実行します。なおインストールの途中で、依存するCPANモジュールが自動的にインストールされますが、一部XSを使用するモジュールが含まれているため、事前にgccをインストールしておく必要があります。

(送信サーバ側)
# yum install gcc
...
# unzip fluent-agent-lite-master.zip
# cd fluent-agent-lite-master/bin
# ./install.sh
--> Working on inc::Module::Install
...
4 distributions installed
# chkconfig --add fluent-agent-lite

次に、fluent-agent-liteの設定ファイルを編集します。

(送信サーバ側)
(/etc/fluent-agent-lite.conf)
...
# LOGS: tag /path/to/log/file
#
LOGS=$(cat <<"EOF"
# 下の1行をコメントアウト
#apache2     /var/log/apache2/access.log
# yourservice /var/log/yourservice/access.log
# 下の1行を追加
httpd.error     /var/log/httpd/error_log
EOF
)

# SERVERNAME[:PORTNUM]
# port number is optional (default: 24224)
# 下の1行をコメントアウト
#PRIMARY_SERVER="primary.fluentd.local:24224"
# 下の1行を追加
PRIMARY_SERVER="192.168.XXX.XXX:24224"  ※受信サーバのIPアドレス
...

設定ファイルの編集が済んだら、td-agentを停止し、代わりにfluent-agent-liteを起動します。

# service td-agent stop
Shutting down td-agent:                                    [  OK  ]
# service fluent-agent-lite start
Starting fluent-agent-lite: ok.
# service fluent-agent-lite status
Checking fluent-agent-lite: ok.

fluent-agent-liteが起動しました。念のため、プロセスを確認してみます。

# ps -ef | grep -f /var/run/fluent-agent-lite.pid
root     31337     1  0 14:17 pts/0    00:00:00 perl /usr/local/fluent-agent-lite/bin/fluent-agent-lite httpd.error /var/log/httpd/error_log 192.168.XXX.XXX:24224
root     31342 31337  0 14:17 pts/0    00:00:00 /usr/bin/tail -n 0 -F /var/log/httpd/error_log

perlのプロセス、及びその子プロセスとしてtailコマンドが実行されていることが確認できます。それでは、送信サーバ側でhttpdを再起動し、ログが受信サーバ側に出力されるかどうか確認します。

(送信サーバ側)
# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]

(受信サーバ側)
# tail /var/log/td-agent/httpd.log.20130518.b4dcf7040e0c42931
...
[Sat May 18 14:24:10 2013] [notice] caught SIGTERM, shutting down
[Sat May 18 14:24:10 2013] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Sat May 18 14:24:10 2013] [notice] Digest: generating secret for digest authentication ...
[Sat May 18 14:24:10 2013] [notice] Digest: done
[Sat May 18 14:24:10 2013] [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations

こちらも期待どおり、送信サーバ側のhttpdのログと全く同じ内容が、受信サーバ側に出力されました。なおfluent-agent-liteの方は、ログ増分を検知すると、直ちに宛て先のfluentdへ送信するようです。

ちなみに、fluent-agent-liteはログ送信専用ということもあり、転送するログを設定ファイルで少なくとも1つ以上指定する必要があるようです(1つも指定しない場合、プロセスが起動後すぐに終了します)。また、転送するログが複数ある場合は、その数だけperlのプロセスとtailの子プロセスが作成されるようです。

以上、簡単ですがfluentdに関する話題をご紹介しました。今後機会があれば、より深く掘り下げてみたいと思います。

Leave a Reply

You must be logged in to post a comment.