nginxのアクセスログをfluentdを使ってelasticsearchに登録し、その情報をkinaba3を使って見れるようにした時のメモ
環境
- Amazon Linux AMI 2015.03 (HVM), SSD Volume Type
- td-agent 0.12.7
- elasticsearch 1.3(最終的に1.4にアップグレード)
- kibana3
td-agent2のインストール
最新のFluentd(td-agent2)ではAmazonLinuxもサポートとなったようなのでスクリプトからインストールします
td-agent2をAmazon Linuxで実行する
curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
$td-agent --version
td-agent 0.12.7
$sudo chkconfig td-agent on
$sudo chkconfig --list |grep td-agent
elastic-search1.3のインストール、起動
基本的には公式サイトに書いてあるように進めます。
elastic-search(YUM)
$sudo rpm --import https://packages.elasticsearch.org/GPG-KEY-elasticsearch
$sudo vi /etc/yum.repos.d/elasticsearch.repo
以下を記載します。
[elasticsearch-1.3]
name=Elasticsearch repository for 1.3.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.3/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
enabled=1
インストールおよび自動起動登録、起動をします。
$sudo yum install elasticsearch
$sudo chkconfig --add elasticsearch
$sudo chkconfig --list |grep elasticsearch
$sudo service elasticsearch start
なお、起動時にメモリ量が確保出来なくてエラーになる場合があります。その場合には不要なプロセスをkillすればt2.microでも起動できました。もしくは/etc/elasticsearch/elasticsearch.ymlでメモリ量を記載することでも調整できるようです。
クラスタとノードの名前を確認
クラスタとノードの名前を確認します。
jqをインストールしていない人はyumでインストールしておくと便利だと思います。
# cluster
$curl -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
}
# node
$curl -XGET http://localhost:9200/ | jq .
{
"status": 200,
"name": "Sam Wilson",
"version": {
"number": "1.3.9",
"build_hash": "0915c7306e6264ba21a6cb7609b93545ccc32ef1",
"build_timestamp": "2015-02-19T12:34:48Z",
"build_snapshot": false,
"lucene_version": "4.9"
},
"tagline": "You Know, for Search"
}
デフォルトだとクラスタ名はelasticsearch、ノードは任意のマーベルコミックの人物になるようです。
クラスタの名前を変更する
クラスタ名とノード名を任意のものに変更します。本例ではクラスタ名をtest_cluster、ノード名をnode_1としました。
$sudo vi /etc/elasticsearch/elasticsearch.yml
cluster.name: test_cluster
node.name: "node_1"
設定後、サービスを再起動します。
$sudo service elasticsearch restart
変更を確認します。
# cluster
$curl -XGET http://localhost:9200/_cluster/health | jq .
# node
curl -XGET http://localhost:9200/ | jq .
どちらも変更されていることが確認できると思います。
nginxのインストール
$sudo yum install nginx
$sudo service nginx start
$sudo chkconfig nginx on
$chkconfig --list |grep nginx
fluentdのelastic-searchプラグインのインストール
fluentd経由でelastic-searchのプラグインをインストールします。事前に必要となるDevelopment toolsとcurl-develもインストールします。
$sudo yum groupinstall 'Development tools'
$sudo yum -y install curl-devel
$sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch
nginxのアクセスログのフォーマットを確認する
nginxのログフォーマットを確認するためにFluentularというサイト上でFluentdのログフォーマットを確認できるサイトを使います。
上記サイトで実際に出力されるログとそのフォーマットが正しくできるまでを確認後、実際に設定ファイルに記載して内容を確認します。
まずは、標準出力に出すようにしています。
$sudo vi /etc/td-agent/td-agent.conf
以下のように記載します。
<source>
type tail
path /var/log/nginx/access.log
format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
time_format %d/%b/%Y:%H:%M:%S %z
pos_file /var/log/td-agent/nginx-access.log.pos
tag nginx.access
</source>
<match nginx.access.**>
type stdout
</match>
実際に動作が可能なやってみます。
今回はログがわかり易いようにflunetdをトレースモードで起動します。
$sudo td-agent -vv &
その後、実際にnginxにアクセスしてみます。
$wget http://localhost
--2015-04-11 02:53:04-- http://localhost/
localhost (localhost) をDNSに問いあわせています... 127.0.0.1
localhost (localhost)|127.0.0.1|:80 に接続しています... 接続しました。
2015-04-11 02:53:04 +0000 nginx.access: {"remote":"127.0.0.1","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"3770","referer":"-","agent":"Wget/1.16.1 (linux-gnu)","forward":"-"}
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 3770 (3.7K) [text/html]
`index.html' に保存中
index.html 100%[=====================>] 3.68K --.-KB/s 時間 0s
2015-04-11 02:53:04 (555 MB/s) - `index.html' へ保存完了 [3770/3770]
設定がうまくいっていれば、上記のメッセージの中にnginx.accessなどのように正しくfluentdがログをパースできているか確認できます。
上記、問題なければ一度fluentdを止めます。
$ps aux|grep ruby|awk ‘{ print $2 }’|sudo xargs kill -KILL
td-agentの設定ファイルを変更します。
デバッグ用にcopyプラグインを使って、標準出力もしつつ、ElasticSearchへの登録を行う設定に変更します。
$vi td-agent.conf
以下のように変更します。
<source>
type tail
path /var/log/nginx/access.log
format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
time_format %d/%b/%Y:%H:%M:%S %z
pos_file /var/log/td-agent/nginx-access.log.pos
tag nginx.access
</source>
<match nginx.access.**>
type copy
<store>
type stdout
</store>
<store>
type elasticsearch
host localhost
port 9200
type_name nginx_log
include_tag_key true
logstash_format true
tag_key tag
</store>
</match>
再起動後、nginxにリクエストを投げてアクセスログを更新します。
$td-agent -vv &
$wget http://localhost
先程と同じように標準出力にログがパースできているか確認し、問題なければ少し待つと以下のような出力がされます。
2015-04-11 04:19:50 +0000 [info]: plugin/out_elasticsearch.rb:67:client: Connection opened to Elasticsearch cluster => {:host=>"localhost", :port=>9200, :scheme=>"http"}
上記出力後、問題なければlogstash–2015.04.11というような今日の日付のインデックスができていると思うので全ての内容を取得します。
#データ取得(全件)
curl -XGET http://localhost:9200/logstash-2015.04.11/_search -d '
{
"query": {
"match_all" : {}
}
}
' | jq .
{
"took": 44,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "logstash-2015.04.11",
"_type": "nginx_log",
"_id": "8w0OI32bRRObQna13HGcJQ",
"_score": 1,
"_source": {
"remote": "127.0.0.1",
"host": "-",
"user": "-",
"method": "GET",
"path": "/",
"code": "200",
"size": "3770",
"referer": "-",
"agent": "Wget/1.16.1 (linux-gnu)",
"forward": "-",
"tag": "nginx.access",
"@timestamp": "2015-04-11T04:18:57+00:00"
}
}
]
}
}
例えばsizeパラメーターが3000より大きいものみ取得したい場合には以下のようなリクエストを送ります。
curl -XGET http://localhost:9200/logstash-2015.04.11/_search -d '
{
"query": {
"query_string" : {
"query" : "size:>3000"
}
}
}
' | jq .
kibanaのインストール
現在はKibana4がリリースされていますが、導入してみたところ、elasticsearch1.4.4以上である必要があったので今回はKinaba3で実施することにしました。
Kibana3.1.2
$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
nginxを再起動します。
$service nginx restart
上記の場合http://yourhost/kibanaとするとkibanaのサイトにアクセスできるようになっているかと思います。
ただし、Connection failedと表示されてelasticsearchとの接続がうまくできていないようでした。
上記原因の一つとしてまず、SecurityGroupの設定で9200ポートを開いていないことが問題の一つだったので、開けるように設定します。
また、上記を対応してもまだ接続エラーとなってしまい、色々探したのですが、利用が全くわからなかったのでelasticsearchのバージョンを1.3から1.4にあげて、設定を変えてみたところうまくいきました。
ElasticSearch–1.4-YUM
$sudo vi /etc/yum.repos.d/elasticsearch.repo
以下に変更。
[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
アップデート。
$sudo yum update
また、elasticsearch1.4からセキュリティ向上が目的で設定が追加で必要になったようで、それを追加します。
Kibana3+Elasticsearch1.4.1でConnection Failedと怒られる
$sudo vi /etc/elasticsearch/elasticsearch.yml
以下を末尾に追記。
http.cors.allow-origin: "/.*/"
http.cors.enabled: true
サービスを再起動。
$sudo service elasticsearch restart
$sudo service nginx
この状態でアクセスするとうまくできました。