Amazon LinuxにFluentdをインストールしてS3とMongoDB連携する
あらゆるログを収集する
昨年あたりからfluentdという名前をよく耳にするようになりました。弊社での実際のプロジェクト活用が出てきています。そこで今回は備忘録としてセットアップからプラグインのインストール等の基本的な手順を紹介したいと思います。
セットアップ
Amazon Linuxにインストールするためにリポジトリを設定して簡単インストールします。
$ sudo vi /etc/yum.repos.d/td.repo [treasuredata] name=TreasureData baseurl=http://packages.treasure-data.com/redhat/$basearch gpgcheck=0
yumでインストールにて自動起動設定します。
$ sudo yum install td-agent -y $ sudo service td-agent start $ sudo chkconfig td-agent on
ログの収集のために権限を設定
fluentdはシステム系のログを取得して転送することができますので、まずはfluentdが閲覧できるように設定します。
$ sudo chgrp td-agent /var/log/httpd/ $ sudo chgrp td-agent /var/log/tomcat7/ $ sudo chgrp td-agent /var/log/messages $ sudo chgrp td-agent /var/log/secure $ sudo chgrp td-agent /var/log/cron $ sudo chmod g+rx /var/log/httpd/ $ sudo chmod g+rx /var/log/tomcat7/ $ sudo chmod g+rx /var/log/messages $ sudo chmod g+rx /var/log/secure $ sudo chmod g+rx /var/log/cron
fluentdプラグインのインストール
fluentdは自身がリポジトリを持っています。そこでこのリポジトリからプラグインをインストールします。今回は複数サーバ構成時に効率よく名前付けしながらログを収集する仕組みを作るために以下のプラグインを入れました。
- fluent-plugin-s3 : S3にログを書き出すプラグイン ※デフォルトでインストールされてました!
- fluent-plugin-forest : タグを動的に扱うプラグイン
- fluent-plugin-config-expander : プレースホルダを扱えるようにするプラグイン
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem update $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-s3 $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-forest $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-config-expander
fluentdの設定を書く
ほとんどはテンプレートをもとに書けば出来上がります。
$ sudo vi /etc/td-agent/td-agent.conf <source> type forward port 24224 </source> <source> type config_expander <config> type tail format apache path /var/log/httpd/access_log tag ${hostname}/apache.access </config> </source> <source> type config_expander <config> type tail format syslog path /var/log/messages tag ${hostname}/syslog.messages </config> </source> <match *.**> type forest subtype s3 <template> s3_bucket akari-ec2-log s3_endpoint s3-ap-northeast-1.amazonaws.com path ${tag}/ buffer_path /var/log/td-agent/buffer/${tag} time_slice_format %Y/%m/%d/ec2-%Y-%m-%d-%H flush_interval 1m </template> </match>
この設定は、自分自身のサーバが送り元であり送り先である場合にこのような形式になります。もし、ログの送り元サーバとログの送り先サーバを分けたければ、fluentdをそれぞれのサーバにインストールしつつ、以下のようにそれぞれ記述すればOKです。
ログの送り元:発生したログを収集サーバに送る
<source> type forward retry_limit 5 flush_interval 5s <server> host 10.0.1.100 (ログ収集先) port 24224 (ログ収集先fluentdの待ち受けポート番号) </server> </source> <source> type config_expander <config> type tail format apache path /var/log/httpd/access_log tag ${hostname}/apache.access </config> </source> <source> type config_expander <config> type tail format syslog path /var/log/messages tag ${hostname}/syslog.messages </config> </source>
ログの送り先:各サーバから送られてきたログをまとめてS3にアップする
<source> type forward port 24224 </source> <match *.**> type forest subtype s3 <template> s3_bucket akari-ec2-log s3_endpoint s3-ap-northeast-1.amazonaws.com path ${tag}/ buffer_path /var/log/td-agent/buffer/${tag} time_slice_format %Y/%m/%d/ec2-%Y-%m-%d-%H flush_interval 1m </template> </match>
fluentdの動作を確認する
実際にログがS3に書き込まれているか確認してみましょう。今回は、事前にS3にバケットが作成済みであることと、IAM RoleによってS3のカギ設定が不要だったことを補足しておきます。また、Apacheインストールして起動済みとします。
$ sudo service td-agent restart $ curl localhost $ sudo tail /var/log/td-agent/td-agent.log 2013-01-14 13:29:16 +0000: this parameter is highly recommended to save the position to resume tailing. 2013-01-14 13:29:16 +0000: adding source type="config_expander" 2013-01-14 13:29:16 +0000: 'pos_file PATH' parameter is not set to a 'tail' source. 2013-01-14 13:29:16 +0000: this parameter is highly recommended to save the position to resume tailing. 2013-01-14 13:29:16 +0000: adding match pattern="*.**" type="forest" 2013-01-14 13:29:16 +0000: listening fluent socket on 0.0.0.0:24224 2013-01-14 13:29:16 +0000: following tail of /var/log/httpd/access_log 2013-01-14 13:29:16 +0000: following tail of /var/log/messages 2013-01-14 13:29:53 +0000: out_forest plants new output: s3 for tag 'fluent.info' 2013-01-14 13:29:53 +0000: out_forest plants new output: s3 for tag 'ip-10-132-80-240/apache.access'
すこし時間を置いてからS3を見てみましょう。送信元のIPアドレスがタグとして取得できてバケット内の各フォルダ内に保存されています〜♪
S3にもMongoDBにも入れたいな
S3に出力することができましたので今度はMongoDBにも入れてみたいと思います。
まずは、ちゃちゃっとMongoDBをインストールします。
$ sudo vi /etc/yum.repos.d/10gen.repo [10gen] name=10gen Repository baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64 gpgcheck=0 enabled=1 $ sudo yum install mongo-10gen-server mongo-10gen $ sudo chkconfig mongod on $ sudo service mongod start Starting mongod: forked process: 21814 all output going to: /var/log/mongo/mongod.log
MongoDBは、27017ポートで起動しました。fluentdでmongodb用の設定をします。
<match *.**> type mongo database httpd collection accesslog host localhost port 27017 flush_interval 10s </match>
この設定自体は正しいのですが、これではS3またはMongoDBに書き込まれてしまいます。どちらにも書き出したいのでtype copyを組み合わせましょう。
<match *.**> type copy <store> type mongo database httpd collection accesslog host localhost port 27017 flush_interval 10s </store> <store> type forest subtype s3 <template> s3_bucket akari-ec2-log s3_endpoint s3-ap-northeast-1.amazonaws.com path ${tag}/ buffer_path /var/log/td-agent/buffer/${tag} time_slice_format %Y/%m/%d/ec2-%Y-%m-%d-%H flush_interval 1m </template> </store> </match>
設定を更新したのでfluentd(td-agent)を再起動して動作を確認します。
$ sudo service td-agent restart $ curl localhost $ curl localhost $ curl localhost $ sudo tail /var/log/td-agent/td-agent.log 2013-01-14 15:45:18 +0000: this parameter is highly recommended to save the position to resume tailing. 2013-01-14 15:45:18 +0000: adding source type="config_expander" 2013-01-14 15:45:18 +0000: 'pos_file PATH' parameter is not set to a 'tail' source. 2013-01-14 15:45:18 +0000: this parameter is highly recommended to save the position to resume tailing. 2013-01-14 15:45:18 +0000: adding match pattern="*.**" type="copy" 2013-01-14 15:45:18 +0000: listening fluent socket on 0.0.0.0:22222 2013-01-14 15:45:18 +0000: following tail of /var/log/httpd/access_log 2013-01-14 15:45:18 +0000: following tail of /var/log/messages 2013-01-14 15:45:37 +0000: out_forest plants new output: s3 for tag 'fluent.info' 2013-01-14 15:45:37 +0000: out_forest plants new output: s3 for tag 'ip-10-132-80-240/apache.access' time=1358178337
最後にmongoのコマンドラインツールを使ってログが書き込まれているか確認します。
$ mongo MongoDB shell version: 2.2.2 connecting to: test > use admin switched to db admin > show dbs admin (empty) httpd 0.203125GB local (empty) > use httpd switched to db httpd > db.accesslog.find() { "_id" : ObjectId("50f41c7ca8f0175639000001"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "403", "size" : "3839", "referer" : "-", "agent" : "curl/7.24.0 (x86_64-redhat-linux-gnu) libcurl/7.24.0 NSS/3.13.5.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.2", "time" : ISODate("2013-01-14T14:55:50Z") } { "_id" : ObjectId("50f41e29a8f0175639000002"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "403", "size" : "3839", "referer" : "-", "agent" : "curl/7.24.0 (x86_64-redhat-linux-gnu) libcurl/7.24.0 NSS/3.13.5.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.2", "time" : ISODate("2013-01-14T15:03:00Z") } { "_id" : ObjectId("50f41e29a8f0175639000003"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "403", "size" : "3839", "referer" : "-", "agent" : "curl/7.24.0 (x86_64-redhat-linux-gnu) libcurl/7.24.0 NSS/3.13.5.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.2", "time" : ISODate("2013-01-14T15:03:00Z") }
S3にも書き込まれていましたので実験完了です!
まとめ
fluentdはインストールも設定も簡単で、インプット・アウトプットのプラグインがあり、複数台のサーバ構成時にログ管理でやりたいことはだいたい実現できてしまうすばらしいツールでした。どこかのサーバが落ちたとしてもバッファリングして再開してくれるので、ログが消失せずにしっかり残してくれるのは業務利用にもうれしいです。rubyでプラグインが書けますので、そのうち自作プラグイン書いてみたいですね〜。