- English
- 日本語
概要
みなさんこんにちはcandleです。今回はtd-agentでnginxのログを収集します。
td-agentで解説しますが、fluentdと設定は基本的に同じになると思うので、参考にしていただけたらと思います。
前提
td-agentまたはfluentdがインストールされている
適当なアクセスできるnginxサーバがある
td-agentのユーザーを変更する
td-agentサーバの実行ユーザーは初期設定でtd-agentですが、nginxのログはrootしかアクセスできません。
もしも、nginxのaccess.logやerror.logを取得しようとすると「Permission denied @ rb_sysopen – /var/log/nginx/access.log」というエラーがでます。
これを回避するのにはtd-agentサーバのユーザをrootにすれば良いのです。
/etc/init.d/td-agentを開きます。
自分のよく使っているエディタで開いてください。
sudo emacs /etc/init.d/td-agent
ファイルの中の「TD_AGENT_USER」の値を「td-agent」から「root」に変更します。
td-agentを再起動します。
sudo service td-agent restart
これで、nginxのログにtd-agentがアクセスできるようになりました。
nginxのaccess.logを取得する
nginxのaccess.logを取得するformatには以下のものがありますが、
format nginx
吐き出されるログに「partter not match」が含まれてしまっています。
これはformat nginxで定義されている正規表現と実際のログがあっていないからです。
以下が吐き出されるログのサンプルです。
2017-03-05 05:21:39 +0000 [warn]: pattern not match: "192.168.33.1 - - [05/Mar/2017:05:21:39 +0000] \"GET /assets/application.css HTTP/1.1\" 304 0 \"http://local-hogehogecom/\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8\" \"-\""
調べてみると多くの記事はltsv形式で取得しているらしいです。
ただこちらの方法もあまりお勧めできません。吐き出されるjsonの形式がいまいちです。
以下がそのサンプルです。
2017-03-05 05:17:00 +0000 nginx.access: {"192.168.33.1 - - [05/Mar/2017":"05:17:00 +0000] \"GET /assets/application.js HTTP/1.1\" 304 0 \"http://local-hogehoge.com/\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8\" \"-\""}
そこで、以下のサイトを参考にさせてもらい、formatを独自で定義します。
http://qiita.com/liubin/items/92a4e7e3917143ae4aaf
td-agentの設定ファイルを開きます。
/etc/td-agent/td-agent.conf
に設定ファイルがあります。
以下を記述しましょう。
<source> @type tail path /var/log/nginx/access.log tag nginx.access pos_file /var/log/td-agent/nginx.access.pos format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)")?/ time_key time_local </source>
type tailはpathで定義されているファイルを取得し続けるという記述
path /var/log/nginx/access.logはtype tailの対象ファイル
tag nginx.access は取得したデータにタグをつけます。
pos_file /var/log/td-agent/nginx.access.pos は取得したログを一時的に置いておくファイル
format はnginxのaccess.logにマッチした正規表現が記述されています。
time time_localは生成されるjsonにtimeを埋め込みます。これが無いとエラーがでます。
デバッグのために、この取得したログを表示する記述も書いておきます。
上の設定で加えたタグ「nginx.access」にマッチした場合にfluentd標準出力し、td-agentのログに残します。
<match nginx.access> type stdout </match>
ファイルを保存して、td-agentを再起動します。
sudo service td-agent restart
再起動したら、td-agentのログを見て、取得できているか確認します。
td-agentのログは/var/log/td-agent/td-agent.logにあります。これを監視しましょう。
sudo tail -f /var/log/td-agent/td-agent.log
ブラウザでnginxにアクセスして、ログが表示されたか確認します。
画像だと分かりづらいですが、下のテキストがサンプルのログです。
2017-03-05 14:21:08 +0000 nginx.access: {"remote":"192.168.33.1","host":"-","user":"-","time":"05/Mar/2017:14:21:08 +0000","method":"GET","path":"/assets/application-89224d7948f4a0ac2f79b292da0.js","code":"304","size":"0","referer":"http://local-hogehoge.com/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8","forwarder":"-"}
取得できていますね。
後はS3にあげるなり、適当な場所に保存するなりします。
nginxのerror.logを取得する
続いて、nginxのerror.logを取得しましょう。
td-agentのconfファイルを開きます。
/etc/td-agent/td-agent.conf
先ほど加えたaccess.logのデバッグ用のディレクティブはコメントアウトしておきます。
#<match nginx.access> # type stdout #</match>
続いて、以下を記述します。
<source> type tail path /var/log/nginx/error.log tag nginx.error pos_file /var/log/td-agent/nginx.error.pos format /^(?<time>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[(?<log_level>\w+)\] (?<pid>\d+).(?<tid>\d+): (?<message>.*)$/ </source>
基本的なことは上のaccess.logと同じです。
formatのところは独自の正規表現を記述しています。nginxのerror.logに対応した正規表現です。
これは公式サイトにあるものを持ってきました。
http://docs.fluentd.org/v0.12/articles/common-log-formats
デバッグのために以下のfluntd標準出力も記述しておきます。
<match nginx.error> type stdout </match>
保存したら、再起動します。
sudo service td-agent restart
同じように、tail -f でtd-agentログを見てみます。
sudo tail -f /var/log/td-agent/td-agent.log
nginxでわざとエラーを起こすのは難しいのですが、下のはrailsでunicornを停止した状態でアクセスした時のエラーです。
2017-03-05 08:28:00 +0000 nginx.error: {"log_level":"error","pid":"1970","tid":"1970","message":"*104 connect() to unix:/tmp/hogehoge_unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 192.168.33.1, server: local-hogehoge.com, request: \"GET / HTTP/1.1\", upstream: \"http://unix:/tmp/hogehoge_unicorn.sock:/\", host: \"local-hogehoge.com\""}
いい感じですね。
まとめ
nginxのaccess.logとerror.logを取得してみました。