Fluentd + ElasticSearch + Kibana3で簡単に様々なログを可視化・解析する

Posted on | 2336 words | ~5mins
fluentd kibana ElasticSearch

ISUCON本戦に参加することができてしまったため,各種ログを集めて簡単に見れると良さそうだなぁと思っていたところ,Fluentd + Elasticsearch + Kibana3の組み合わせがなかなかよさそうだったので試してみました.
本記事では,NginxのAccessLogとMySQLのSlowQueryLogを可視化してみます.

Fluentdはご存知の方も多いと思いますが,Treasure Dataのメンバによって開発が進めれているオープンソースのログ収集ツールです.Fluentdに追加された様々なログデータはJSONに変換,アウトプットされます.実装はRubyで行われており,pluginを追加することでで様々なINPUT/OUTPUT先を追加することができます.
Fluentdにはリアルタイムにログを収集して活用できることや,様々なログフォーマットの違いを吸収してJSONで同じように扱えることなどのメリットがあります.

ElasticSearchは分散型の全文検索エンジンです.RESTfulなAPIを通してデータの追加や検索を行います.スキマーレスでありスケーラビリティも考慮されていて,foursquareGithubでも使われているようです.

Kibana3は,ブラウザ上でElasticSearch上のログをリアルタイムビジュアライゼーションする事ができるWebアプリケーションです.Kibana2はRubyで実装されていたのですが,Kibana3はHTMLとJavascriptで書かれており,様々なパネルが用意されていて見た目も綺麗になっています.ただHTML+Javascriptであるため,ブラウザが動作しているマシンからデータが保存されているElasticSearchにアクセスできなければならないという制限があります.

導入と設定

今回は以下のような環境で試してみました

  • Ubuntu 12.04
  • ruby 1.9.3
+------------------------+        +---------------------------------------+
| Nginx  ---+            |        |                                       |
|           |            |        |                                       |
|           +--> Fluentd | =====> | Fluentd --> ElasticSearch --> Kibana3 |
|           |            |        |                                       |
| MySQL  ---+            |        |                                       |
+------------------------+        +---------------------------------------+
        Web Server                                Log Server

まず下準備としてNginxとMySQLの設定を確認しておきましょう.Nginxはltsvでログを出力するように,MySQLはSlowQueryLogを出力するようにします.ここでは導入方法は省きます.

...snip...

http {
  log_format  ltsv  'time:$time_local\t'
                      'msec:$msec\t'
                      'host:$remote_addr\t'
                      'forwardedfor:$http_x_forwarded_for\t'
                      'req:$request\t'
                      'method:$request_method\t'
                      'uri:$request_uri\t'
                      'status:$status\t'
                      'size:$body_bytes_sent\t'
                      'referer:$http_referer\t'
                      'ua:$http_user_agent\t'
                      'reqtime:$request_time\t'
                      'upsttime:$upstream_response_time\t'
                      'cache:$upstream_http_x_cache\t'
                      'runtime:$upstream_http_x_runtime\t'
                      'vhost:$host';
  
  access_log  /var/log/nginx/access.log  ltsv;

...snip...
...snip...

slow_query_log=ON
slow_query_log_file=/var/log/mysql/slow_query.log
long_query_time=1

...snip...

それではLogServerにElasticSearchを導入しましょう.最新版は公式サイトで確認して下さい.ElasticSearchにはJavaの実行環境が必要なのでなければそれも導入します.

# apt-get install openjdk-7-jdk
$ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.6.deb
# dpkg -i elasticsearch-0.90.6.deb

起動します.

# service elasticsearch start

次にログを収集するために各サーバにFluentdを導入します.ここではFluentdの安定版であるtd-agentを使います.最新版が利用したい場合はGitリポジトリから最新版を落としてきて導入してください.

$ sudo -i
# curl -L http://toolbelt.treasure-data.com/sh/install-ubuntu-precise.sh | sh

次に各サーバに必要なプラグインを導入し,/etc/td-agent/td-agent.confを編集します.なおtd-agentは自前のRubyインタプリタを使用しているため,/usr/lib/fluent/ruby/bin/gemなどtd-agentとともに導入されたgemを使ってプラグインの導入を行ってください(でないと認識されない).

  • Web Server
# gem install fluent-plugin-mysqlslowquery
<source>
  type tail
  format ltsv
  path /var/log/nginx/access.log
  tag nginx.access
  time_format %d/%b/%Y:%H:%M:%S %z
</source>

<source>
  type mysql_slow_query
  path /var/log/mysql/mysql-slow.log
  tag mysql.slow_query
</source>

<match **>
  type forward
  <server>
    host {IP of Log Server}
    port 24224
  </server>
  flush_interval 1s
</match>
  • Log Server
# gem install fluent-plugin-elasticsearch
<source>
  type forward
  port 24224
</source>

<match nginx.*>
  index_name adminpack
  type_name nginx
  type elasticsearch
  include_tag_key true
  tag_key @log_name
  host localhost
  port 9200
  logstash_format true
  flush_interval 3s
</match>

<match mysql.*>
  index_name adminpack
  type_name mysql
  type elasticsearch
  include_tag_key true
  tag_key @log_name
  host localhost
  port 9200
  logstash_format true
  flush_interval 3s
</match>

設定が済んだら起動しましょう.ログがとれているか確認したい場合は,Log Server側でtype stdoutを利用して標準出力を見たり,/var/log/td-agent/td-agent.logを確認しましょう.

# service td-agent start

これでLogServerのElasticSerchにログが保存されていくようにになりました.

最後にLogServerにKibana3を導入します.LogServerの公開用ディレクトリにgit cloneして,/sampleにある設定ファイルを参考に,index.htmlにブラウザでアクセスできるようにします.

$ git clone https://github.com/elasticsearch/kibana.git

使い方

ブラウザでhttp://{IP of Log Server}にアクセスすると下のようなページが表示されるので,真ん中下あたりの赤丸で囲んでいるLogstash Dashboardをクリックします.

きちんとログがElasticSearchに追加されていれば,下のようにグラフとJSONフォーマットなデータが見れるようになっているはずです.

あとは上にある検索窓や左にあるFieldから絞込を行って,ある時間のuri毎のアクセス数を見たり,Statusコードの割合を見たり,レスポンスに一定以上の時間がかかっているアクセスを探したりと色々なことができます. またこのページの上でのせたようにグラフの種類や色を変えたりももちろんできます.

この辺りの使い方は以下の記事がよくまとまっているので参考にしてみてください.

Kibana3というのもありまして - @johtaniの日記 2nd

ちなみにこんな感じでドラッグで範囲を指定すると

選択した範囲で絞り込めたりもします.すごい(小並感)

まとめ

以上かなり長くなってしまいましたが,Fluentd + ElasticSearch + Kibana3でNginxのアクセスログやMySQLのSlowQueryLogを可視化・解析する方法を紹介しました.WebServerの台数が増えてもFluentdでTagをつけておけばServer毎の解析や全体での解析もスムーズに切り替えることができますし,なかなか良いのではないのでしょうか :)