話題の記事

Amazon LinuxにFluentdをインストールしてS3とMongoDB連携する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

あらゆるログを収集する

fluentd-001

昨年あたりから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アドレスがタグとして取得できてバケット内の各フォルダ内に保存されています〜♪

fluentd-000

S3にもMongoDBにも入れたいな

fluentd-002

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でプラグインが書けますので、そのうち自作プラグイン書いてみたいですね〜。

参考資料

fluentd

mongodb