ELBログを解析する機会が多くなりました。。。
$sed -e 's/:[0-9][0-9]\.[0-9][0-9][0-9][0-9][0-9][0-9]Z//g' access.log |awk -F " " '{ print $1,$8; }'| sort | uniq -c
のようなコマンドを作って解析しても良いのですが、色々面倒なので、よくあるツール群を使って可視化します。
構成
- Amazon Linux AMI 2015.03 (HVM)(S3へのRead権限を持ったIAMRoleが設定されていること)
- td-agent-2.2.0-0.x86_64
- ElasticSearch-1.4.5
- nginx-1.6.2-1.23.amzn1.x86_64
- Kibana3.1.2
なお、ELBのアクセスログは事前に有効にしておくこと。
参考
- ELBのアクセスログをfluent-plugin-elb-logを使ってkibanaで表示する
- ELB s3 Log + Fluentd + Elasticsearch + Kibana + Ubuntu 14.04 LTS PV + EC2 on AWS
- [技術ブログVol.11] ELBのアクセスログをfluentd+Elasticsearch+kibanaで解析
- fluent-plugin-elb-access-logを作った
- fluentd-v2+elasticsearch+kibana3をEC2上で実施する
nginx
インストール、サービス起動、自動起動設定をします
$sudo yum install nginx
$sudo service nginx start
$sudo chkconfig --add nginx
fluentd
インストール、サービス自動起動設定
$curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
$sudo chkconfig --add td-agent
ELBのアクセスログを取得するためにfluent-plugin-elb-access-logをインストールし、elastcisearchへ登録するためにfluent-plugin-elasticsearchをインストールします。また、事前に必要なパッケージ群もインストールしておきます。
$sudo yum groupinstall 'Development tools'
$sudo yum install curl-devel
$sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch
$sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elb-access-log
ElasticSearch
GPG-KEYの追加
$sudo rpm --import https://packages.elasticsearch.org/GPG-KEY-elasticsearch
リポジトリの追加のために下記ファイルを作成。
[elasticsearch-1.4]
name=Elasticsearch repository for 1.4.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.4/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
enabled=0
インストール、サービス起動、自動起動設定
$sudo yum --enablerepo=elasticsearch-1.4 install elasticsearch
$sudo chkconfig --add elasticsearch
$sudo service elasticsearch start
起動したクラスタを確認
$curl -s -XGET http://localhost:9200/_cluster/health | jq .
{
"cluster_name": "elasticsearch",
"status": "green",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
ELBのログをfluentdで取得
fluent-plugin-elb-access-logを使って、ELBのログを取得します。
<source>
type elb_access_log
account_id 111111
region ap-northeast-1
s3_bucket toshihirock-elb-test
tag elb.access_log
debug true
</source>
<match **>
type stdout
</match>
各設定の詳細及びオプションはfluent-plugin-elb-access-logのREADME参照のこと。
確認のためトレースモードで起動します。
$sudo td-agent -vv &
この状態でELBのURLにアクセスし、少し待ちます。
うまくいっていると標準出力にログが表示されるのが確認できるのですが、以下の証明書エラーとなってしまいました。。。
before_shutdown failed error="SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed"
こちらの問題の調査、解決方法は以下にまとめました。
fluentdのプラグインでcertificate verify failedエラーが発生した話
詳細は上記を見ていただくということでこちらは最終的な対応方法である証明書の差し替えのみ行います。
# AmazonLinuxの証明書の位置を確認
$ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE'
/etc/pki/tls/cert.pem
# バックアップ
$cp /opt/td-agent/embedded/ssl/cert.pem /opt/td-agent/embedded/ssl/cert.pem.original
# 差し替え
$cp /etc/pki/tls/cert.pem /opt/td-agent/embedded/ssl/cert.pem
一度、td-agentのプロセスをkillして再度実行します。
$ps aux|grep ruby|awk '{print $2;}'|sudo xargs kill -KILL
$sudo td-agent -vv &
再度ELBのサイトにアクセスし、5分ほど待ちます。
問題なく解析できていれば、ログが出力されます。
2015-05-30 09:58:23 +0000 elb.access_log: {"timestamp":"2015-05-30T09:58:23.682447Z","elb":"LoadBlancer","client_port":3781,"backend_port":80,"request_processing_time":4.2e-05,"backend_processing_time":0.000791,"response_processing_time":2.7e-05,"elb_status_code":404,"backend_status_code":404,"received_bytes":0,"sent_bytes":3696,"request":"GET http://fuga:80/manager/html HTTP/1.1","client":"boyo","backend":"hoge","request.method":"GET","request.uri":"http://hogefuga:80/manager/html","request.http_version":"HTTP/1.1","request.uri.scheme":"http","request.uri.user":null,"request.uri.host":"abcd","request.uri.port":80,"request.uri.path":"/manager/html","request.uri.query":null,"request.uri.fragment":null}
確認が終わったのでプロセスは終了します。
$ps aux|grep ruby|awk '{print $2;}'|sudo xargs kill -KILL
ELBのログをElasticSearchに保存する
fluentdの設定にelasticsearchに関する内容を追記して、ELBのログを保存するようにします。
<source>
type elb_access_log
account_id 11111111
region ap-northeast-1
s3_bucket toshihirock-elb-test
tag elb.access_log
debug true
</source>
<match elb.access_log>
type elasticsearch
type_name access_log
host localhost
port 9200
logstash_format true
include_tag_key true
tag_key @log_name
</match>
サービス起動。
$sudo service td-agent start
ELBサイトにアクセスし、ログを確認しておきます。
$tail -f /var/log/td-agent.log
5分ぐらい経過すると以下のようなログが流れます。
2015-05-29 14:51:19 +0000 [info]: Connection opened to Elasticsearch cluster => {:host=>"localhost", :port=>9200, :scheme=>"http"}
ElastciSearchに本当に登録されているか確認します。
まず、現在存在するインデックス情報一覧を取得します。
$curl -XGET http://localhost:9200/_aliases?pretty
結果。
{
"logstash-2015.05.29" : {
"aliases" : { }
},
"logstash-2015.05.30" : {
"aliases" : { }
}
}
5月30日の方を確認します。もしjqを事前にインストールしていない場合、sudo yum install jq
を実施するか、パイプ以降のコマンドを削除してください。
$curl -XGET http://localhost:9200/logstash-2015.05.30/_search -d '
{
"query": {
"match_all" : {}
}
}' | jq .
結果
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 18,
"max_score": 1,
"hits": [
{
"_index": "logstash-2015.05.30",
"_type": "access_log",
"_id": "hogefuga",
"_score": 1,
"_source": {
"timestamp": "2015-05-30T10:34:08.552001Z",
"elb": "LoadBlancer",
"client_port": 54931,
"backend_port": 80,
"request_processing_time": 5.1e-05,
"backend_processing_time": 0.00074,
"response_processing_time": 2.1e-05,
"elb_status_code": 304,
"backend_status_code": 304,
"received_bytes": 0,
"sent_bytes": 0,
"request": "GET http://loadblancer-11111.ap-northeast-1.elb.amazonaws.com:80/ HTTP/1.1",
(以下略)
無事登録されていました。
kibana
kibanaのインストール及び配置。
$wget https://download.elastic.co/kibana/kibana/kibana-3.1.2.tar.gz
$tar -zxvf kibana-3.1.2.tar.gz
$mv kibana-3.1.2 kibana
$sudo mv kibana /usr/share/nginx/html
elasticsearch1.4からセキュリティ向上が目的で設定が追加で必要になったようで、それを追加します。
$sudo vi /etc/elasticsearch/elasticsearch.yml
以下を末尾に追加
http.cors.allow-origin: "/.*/"
http.cors.enabled: true
また、SecurityGroupで80番と9200番のポートが空いているか確認します。9200番はKibana が検索クエリを投げるポートのようです。
elasticsearch,nginxの再起動
$sudo service elasticsearch restart
$sudo service nginx restart
この状態で http://[hostname]/kibana/ にアクセスすることで画面が表示されました。