ログをS3にひたすら溜めるんだ! fluentd編|アドカレ2013 : CFn #15

よく訓練されたアップル信者、都元です。アドベントカレンダー2013「AWS CloudFormationビッグバンテンプレート」、本日は15日目です。

昨日は植木さんのソンナコトモアロウカト編でした。ナニコノナマエー( ´,_ゝ`)プッ

fluentd

ログっすよ、ログ。システムを物理サーバ1台で回していた時代において、全てのログがローカルファイルシステムに存在しました。grep等を駆使して動きを追いかけたりすることがそこそこ簡単にできましたね。しかし、今はクラウドの時代。サーバインスタンスの数が増えたのはもちろん、Immutable Infrastructure等の考え方が生まれたことにより、インスタンスの使い捨てリソース化が加速しています。

「XX月YY日ZZ時頃にサーバがおかしかったっぽいんだけどログ追ってよ」と簡単に言われるものの、そのファイルどこだよ、ってのがスタートです。当時起動していたインスタンスのIDは何なのか。っていうかそもそもきちんと保存されているのだろうか…。

まぁ、そんな時のfluentdなわけですね。弊社ブログでも何度も取り上げてきたプロダクトであります。

さてこの中の一番最後。これを今回、堅牢な公開テンプレートとして整備しました。小規模なシステムであれば、各サーバにtd-agentを仕込んで各々がS3にファイルをアップロードして行けば良いのですが、例えば100台のサーバが30秒毎にファイルをアップロードすると、1分あたり50ファイルが生成されることになります。そこをある程度集約・バッファリングして、S3へのリクエスト頻度を緩和しつつ、ファイル数を減らす中継サーバとして本テンプレートのインスタンスをご利用頂ければと。

まぁしかし、このテンプレートを使ったとしてもS3にアップロードされるファイルの数は、手動では手に負えない量になります。そのあたりはEMR/Hiveを使ってガッチョンガッチョンすればいい話。MongoDBに入れたい等色々ニーズはあるかと思いますが、本テンプレートではとにかくS3に溜めることを第一義とします。あれこれやるなら、きちんと自前でfluentdサーバの設計からスタートしてください。

んではまずデモから

簡単に構成図がこんな感じです。ELB配下に2台のWebサーバを配置してあり、それらのsyslogとaccess_logがfluentdサーバに飛ぶ(5秒毎!)ようになっています。fluentdサーバはそれをバッファリングしてから、S3に書き込む(1時間毎)ようになっています。

fluentd01

fluentdのデモを起動

パラメータは以下のとおりです。ひとまずこれだけ!

  • KeyName: ECのキーペア名。EC2へのSSH接続用。
  • Sub-Stackを利用するため「I acknowledge that this template may create IAM resources」にチェックを入れてください。

スタックができあがったら、ロードバランサ経由でWebサーバにアクセスしてみてください。適当な/index.html/info.phpが用意してあります。1時間程度待つと、S3バケットにログがアップロードされるはずです。私の環境では、寝て起きたらこんな感じに。

$ aws s3api list-objects --bucket fluentd-demo-logbucket-************* --query "Contents[*].Key"
[
    "fluent.info/2013/12/14/ec2-2013-12-14-15_0.gz",
    "fluent.info/2013/12/14/ec2-2013-12-14-16_0.gz",
    "fluent.warn/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-15_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-16_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-16_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-17_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-17_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-18_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-18_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-19_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-19_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-20_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-20_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-21_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-22_0.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-22_1.gz",
    "ip-10-0-0-237/apache.messages/2013/12/14/ec2-2013-12-14-23_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-16_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-17_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-18_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-19_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-20_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-22_0.gz",
    "ip-10-0-0-237/syslog.messages/2013/12/14/ec2-2013-12-14-23_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-15_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-16_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-17_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-18_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-18_1.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-19_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-20_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-21_1.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-22_0.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-22_1.gz",
    "ip-10-0-0-99/syslog.messages/2013/12/14/ec2-2013-12-14-23_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-15_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-16_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-16_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-17_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-17_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-18_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-18_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-19_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-19_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-20_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-20_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-21_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-22_0.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-22_1.gz",
    "ip-10-0-1-186/apache.messages/2013/12/14/ec2-2013-12-14-23_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-16_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-17_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-18_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-19_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-20_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-21_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-22_0.gz",
    "ip-10-0-1-186/syslog.messages/2013/12/14/ec2-2013-12-14-23_0.gz"
]

細かく挙動を追いたい方は、各インスタンスにSSHでログインし、/var/log/td-agentディレクトリ内を覗いてみると良いかと思います。fluentdサーバには、発生から1時間に満たないログが溜め込まれているのが確認できるかと思います。

# pwd
/var/log/td-agent
# tree
.
├── buffer
│   ├── ip-10-0-0-237
│   │   ├── apache.messages.2013%2F12%2F15%2Fec2-2013-12-15-00.b4ed880cd8b98105f.log
│   │   └── syslog.messages.2013%2F12%2F15%2Fec2-2013-12-15-00.b4ed879fc6ab25241.log
│   ├── ip-10-0-0-99
│   │   └── syslog.messages.2013%2F12%2F15%2Fec2-2013-12-15-00.b4ed8785dd862e887.log
│   └── ip-10-0-1-186
│       ├── apache.messages.2013%2F12%2F15%2Fec2-2013-12-15-00.b4ed880cba8e90405.log
│       └── syslog.messages.2013%2F12%2F15%2Fec2-2013-12-15-00.b4ed87910f1e51130.log
├── syslog.pos
└── td-agent.log

その他、障害を想定してfluentdサーバをStop/Startしてみたりして、ログが失われないことを確認してみたりするといいかもしれません。

本番用テンプレート

上記のELBとWebサーバ無し、つまりfluentdサーバ1台だけを起動するテンプレートがこちら。

fluentdを起動

パラメータは以下のとおりです。

  • VpcId: VPC ID
  • VpcCidrBlock: VPCのIPアドレス帯域(CIDR)
  • SubnetId: fluentdを配備するサブネットID。S3と通信するので、publicまたはprotectedである必要があります。
  • LogBucket: ログを送り込むバケット名
  • InstanceType: fluentdサーバのインスタンスタイプ。
  • FlushInterval: S3にファイルをアップロードする間隔。
  • KeyName: ECのキーペア名。EC2へのSSH接続用。

もちろんGitHubに公開済みです

このテンプレートは例によってGitHubに公開済みです。要望・改善案等ございましたら、issue発行なりpull requestなり、ご自由にどうぞ!