ようへいの日々精進XP

よかろうもん

td-agent + fluent-plugin-elb-log を使って ELB のアクセスログを Elasticsearch + kibana でちょっと見てみる

はじめに

SensuRabbitMQ とか Sensu APIELB 経由で利用するにあたって「ああ、やっぱログ見たいよね」ってことで ELB のログを fluent-plugin-elb-log を介して Elasticsearch + kibana のゴールデンコンビ(当社比)で見てみることにした。


参考


準備

環境

  • Amazon Linux
  • td-agent-1.1.18-0.x86_64
  • elasticsearch-1.0.1
  • fluent-plugin-elasticsearch
  • fluent-plugin-elb-log

td-agent 等のインストールについては割愛。Elasticsearch は 1.0.1 で。

fluent-plugin-elb-log のインストールと設定

インストール。

udo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elb-log --no-ri --no-rdoc -V

設定。

<source>
  type elb_log
  access_key_id     AK123456789012345678
  secret_access_key ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234
  s3_endpoint       s3-external-1.amazonaws.com
  s3_bucketname     sensuelblog
  s3_prefix         sensu
  timestamp_file    /tmp/elb_last_at.dat
  refresh_interval  300
</source>

/etc/td-agent/conf.d を作って hoge.conf とかで置いて include conf.d/*.conf すると td-agent.conf がスッキリして良いかなー。fluent-plugin-elasticsearch の設定も割愛。

ELB でアクセスログを取れるようにする

アクセスログは S3 のバケットに保存しなければならないのでバケットの設定をしなければいけないがただバケットを作るだけではダメ。 S3Bucket Policy を設定する必要があるので注意する。(以下の補足を参照)

適切にバケットを設定したら ELBDescription からアクセスログが吐かれるように設定する。

f:id:inokara:20140331002619p:plain

Edit をクリックすると以下のように詳細の設定が出来る。

f:id:inokara:20140331002628p:plain

interval5 分毎か 30 分毎が選択出来る。ここは迷わず 5 分毎。そしてバケットの設定も忘れずに。


ログが溜まってきた

こんな感じで

暫く放置しておくとバケットに以下のような感じでログが溜まり始める。

f:id:inokara:20140331003826p:plain

一つの接続に対して一つのログファイルが吐かれている模様。以下、Elastisearch に記録されているログ。

f:id:inokara:20140331012251p:plain

以下は接続別の Elasticsearch に記録されているログ。

TCP 接続の場合

接続の種類次第かと思われるが RabbitMQ の接続は以下のようなログが記録される。

{
  "_source": {
    "@timestamp": "2014-03-30T10:38:53+09:00",
    "@log_name": "elb.access",
    "request_protocol": "- ",
    "request_uri": "-",
    "request_method": "-",
    "sent_bytes": "4250",
    "received_bytes": "10226",
    "backend_status_code": "-",
    "elb": "sensu",
    "time": "2014-03-30T01:24:52.355122+0000",
    "logfile_hash": "35v2dd3c",
    "elb_ip_address": "xxx.xxx.x.10",
    "logfile_elb_name": "sensu",
    "logfile_date": "2014/03/30",
    "region": "us-east-1",
    "account_id": "123456789012",
    "client": "xxx.xxx.x.247",
    "client_port": "48919",
    "backend": "xxx.xxx.x.69",
    "backend_port": "5672",
    "request_processing_time": 0.00095,
    "backend_processing_time": 2.2e-05,
    "response_processing_time": 3.4e-05,
    "elb_status_code": "-"
  },
  "found": true,
  "_version": 1,
  "_id": "Or5wN6d5Qyayy_wykpx8EQ",
  "_type": "elb_log",
  "_index": "logstash-2014.03.30"
}

HTTP のように頻繁にログが記録されるのかなーと思っていたら、RabbitMQ の場合には自ら接続を切断したりしない限りはログは記録されずに繋ぎっぱなしになるようでほとんどログは記録されることが無かった...。

HTTP 接続の場合

アクセスログの代表格、HTTP 接続のログは以下のように Elasticsearch に記録される。

{
  "_source": {
    "@timestamp": "2014-03-30T11:08:53+09:00",
    "@log_name": "elb.access",
    "request_protocol": "HTTP/1.1",
    "request_uri": "http://internal-sensu-12345678.us-east-1.elb.amazonaws.com:4567/stashes",
    "request_method": "GET",
    "sent_bytes": "72",
    "received_bytes": "0",
    "backend_status_code": "200",
    "elb": "sensu",
    "time": "2014-03-30T01:56:43.438461+0000",
    "logfile_hash": "1icus5h5",
    "elb_ip_address": "xxx.xxx.x.10",
    "logfile_elb_name": "sensu",
    "logfile_date": "2014/03/30",
    "region": "us-east-1",
    "account_id": "123456789012",
    "client": "xxx.xxx.x.162",
    "client_port": "48274",
    "backend": "xxx.xxx.x.69",
    "backend_port": "4567",
    "request_processing_time": 4.3e-05,
    "backend_processing_time": 0.006778,
    "response_processing_time": 4.3e-05,
    "elb_status_code": "200"
  },
  "found": true,
  "_version": 1,
  "_id": "m7sa3_tyRLy_s9jEOwZyKw",
  "_type": "elb_log",
  "_index": "logstash-2014.03.30"
}

ほうほう。これが見れるのは便利ですな。

kibana で見てみる

Elasticsearch に放り込まれた ELB のログは kibana で見ると以下のような感じ。

f:id:inokara:20140331011933p:plain

おお、これで検証も捗りますな。

(追記)

以下のような fluent-plugin-elb-log 自身のログも出力されるので kibana で見る場合にはちょっとしたコツが要る。

fluent-plugin-elb-log: timestamp at start:...

方法はいくつかあると思うが kibana で以下のようなクエリを送ることで上記のログ以外を抽出している。

-message:"fluent-plugin-elb-log"

補足(S3 のバケットポリシーの設定)

今回はこれが一番難しかった...

ポリシージェネレーター

S3 を他の AWS サービスから利用する場合等にポリシーを設定する必要があるが、そのポリシーを生成してくれる便利ツールがあるのでそれを利用させて頂く。

f:id:inokara:20140331014930p:plain

上記のように設定してポリシーを生成する。

ポリシー設定

生成されたポリシーは以下のようなポリシーとなる。

{
    "Version": "2012-10-17",
    "Id": "AWSConsole-AccessLogs-Policy-123456789012345",
    "Statement": [
        {
            "Sid": "AWSConsoleStmt-123456789012345",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::1234567890:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::sensuelblog/sensu/AWSLogs/12341234123412/*"
        }
    ]
}

上記をバケットプロパティの Edit Bucket Policy にて貼り付ける。

f:id:inokara:20140331015859p:plain

Edit Bucket Policy をクリックしてからの...

f:id:inokara:20140331015922p:plain

ポリシーを貼り付ける。簡単ですな。