各々のサーバの様々な場所に分散しているWebサーバやその他各種ログファイルをFluentdでまとめてAmazon S3にガシガシ保存。かつ、分析用にコピーを自前のElasticsearchにも保存します。保存したログはKibanaで手軽にビジュアライズ。

Fluentdはとてもシンプルな仕組みで理解しやすい。「ログを集積したい!」と感じたらサクッと導入できる超便利ツールです。

今回は集積用サーバを経由してElasticsearchとS3に保存する構成にします。

Fluentd

Elasticsearchのインストール

Fluentdで集積したログは保存するだけならS3で良いのですが、手軽にビジュアライズしたいので、今回はKibanaを使えるようにElasticsearchにも保存するようにします。今回はCentOSに導入するので、公式のyumリポジトリからインストールします。

$ sudo rpm --import http://packages.elasticsearch.org/GPG-KEY-elasticsearch

リポジトリを手動で登録する必要があります。

$ sudo vi /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-1.2]
name=Elasticsearch repository for 1.2.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.2/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
enabled=1
$ sudo yum install elasticsearch

自動起動を設定したり、サービスを起動したり。

$ sudo chkconfig --add elasticsearch
$ sudo service elasticsearch start

以上でHTTPのポート9200で動作していると思いますが、今回はKibanaから使いやすいようにApacheでリバースプロキシを設定しておきます。(実際には外部からのアクセス制御など適切に設定してください)

$ sudo vi /etc/httpd/conf.d/elasticsearch.conf
<VirtualHost *:80>
ServerName elasticsearch.example.com
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:9200/
ProxyPassReverse / http://localhost:9200/
</VirtualHost>

Kibanaのインストール

KibanaはフロントエンドのJavaScriptだけで作られたアプリケーションなので、基本的にはWebサーバに置くだけで使えます。1点だけ、設定ファイルのElasticsearchのエンドポイントURLだけ正しく設定しておきましょう。

$ wget https://download.elasticsearch.org/kibana/kibana/kibana-3.1.0.zip
$ unzip kibana-3.1.0.zip
$ vi kibana-3.1.0/config.js
elasticsearch: "http://elasticsearch.example.com/“,

Webサーバの設定を適当に

$ sudo vi /etc/httpd/conf.d/kibana.conf
<VirtualHost *:80>
ServerName kibana.example.com
DocumentRoot /var/www/kibana-3.1.0
</VirtualHost>

Fluentdのインストール

Fluentdは、ログを集めたい各ノードとログ集積サーバそれぞれにインストールします。方法はいくつかありますが、今回はCentOSに導入するので、公式のRPMパッケージでインストールする手順に従いサクッと入れます。

$ sudo curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh

今回は各ノードから集積サーバへインターネット越しにログを飛ばすので、安全に通信してくれるfluent-plugin-secure-fowardプラグインを入れます。

$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-secure-forward

集積サーバではElasticsearchに保存するので、fluent-plugin-elasticsearchプラグインを導入。

$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch

fluent-plugin-secure-fowardはTCPおよびUDPの24284番ポートを使用するので、集積サーバの/etc/sysconfig/iptablesに次の設定を追加しておきます。

-A INPUT -m state --state NEW -m tcp -p tcp --dport 24284 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 24284 -j ACCEPT

Fluentdの自動起動を設定したり、サービスを起動したり。 

$ sudo chkconfig td-agent on
$ sudo service td-agent start

ログファイルのパーミッション調整

ログファイルを監視してFluentdで拾う機能(in_tail)を使う場合、対象のログファイルがroot権限でのアクセスしか許可されておらず、Permission deniedとなってしうことがよく起こります。それを回避するための調整をします。

まず問題のログファイルのパーミッションを調整します。

$ sudo chmod og+rx /var/log/httpd
$ sudo chmod og+r /var/log/messages /var/log/secure /var/log/httpd/*

syslog関係のファイルはログローテートの時にパーミッションが戻ってしまうのでその対策をします。CentOS 6の場合、/etc/rsyslog.confに次の2行を追加します。

$FileCreateMode 0644
$DirCreateMode 0755

で、rsyslogをリスタート。

$ sudo service rsyslog restart

ちなみにCentOS 5の場合は、/etc/sysconfig/syslogのSYSLOG_UMASKを変更します。

SYSLOG_UMASK=022

で、syslogをリスタート。

$ sudo service syslog restart

Fluentdの設定例(各ノード)

設定ファイル(/etc/td-agent/td-agent.conf)に、入力元(<source>)と、出力先(<match>)を書きます。

## Apacheのログファイル
<source>
type tail
format apache
path /var/log/httpd/access_log
pos_file /var/log/td-agent/httpd.access.pos
tag hostname.httpd.access
</source>
<source>
type tail
format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\] (?<message>.*)$/
time_format %b %d %H:%M:%S %Y
path /var/log/httpd/error_log
pos_file /var/log/td-agent/httpd.error.pos
tag hostname.httpd.error
</source>

## syslogのログファイル
<source>
type tail
format syslog
path /var/log/messages
pos_file /var/log/td-agent/messages.pos
tag hostname.messages
</source>
<source>
type tail
format syslog
path /var/log/secure
pos_file /var/log/td-agent/secure.pos
tag hostname.secure
</source>

## 集めたログは集積サーバへ転送
<match *.**>
type secure_forward
shared_key FLUENTD_SECRET
self_hostname node1.example.com
<server>
host logs.example.com
</server>
</match>

Fluentdの設定例(集積サーバ)

## 転送されてきたログ
<source>
type secure_forward
shared_key FLUENTD_SECRET
self_hostname logs.example.com
cert_auto_generate yes
</source>

## ElasticsearchとS3に保存
<match *.**>
type copy
<store>
type elasticsearch
host localhost
port 9200
include_tag_key true
tag_key @log_name
logstash_format true
flush_interval 10s
</store>
<store>
type s3
aws_key_id AWS_KEY
aws_sec_key AWS_SECRET
s3_bucket S3_BUCKET
s3_endpoint s3-ap-northeast-1.amazonaws.com
path logs/
buffer_path /var/log/td-agent/buffer/s3
time_slice_format %Y-%m-%d/%H
time_slice_wait 10m
</store>
</match>