Apacheログをfluentdで読み出してelasticsearchに転送する流れをdockerでシミュレートするハンズオン
こんにちはみなさん
Elasticsearchって、AWSのサービスじゃなかったんです。
そんな感想を持っているのが私だけじゃなかったので、少しうれしくなりつつ、業務でアクセスログやアプリログの格納先として使用することになりました。
そもそも、AWSにはElasticsearchのホスティングサービス( ESS )というのができているし、イマドキだとログはMongoDBに入れるよりもElasticsearchに入れたほうが、後々扱いやすくなるっぽいです。
急にバックグラウンドでdockerを動かすと突然落ちたりするところに不安をいだきつつ、今回はハンズオン形式でログをElasticsearchに突っ込んで、kibanaで見物するところまで見てみましょう。
事前準備
前提として、以下の環境で行います
- docker: 1.12.2
- docker-compose: 1.8.1
- Mac 10.11.6
Apacheのログをfluentdに読ませる
Apacheの設定
まず、Apacheのコンテナを作りましょう
全体のプロジェクトディレクトリを作成し、そこにさらにapacheディレクトリを作ります。
以降のファイルパスなどは以下のプロジェクトディレクトリ、log_elasticを起点にしたパスを記載しています。
$ mkdir log_elastic
$ cd log_elastic
$ mkdir apache
$ cd apache
$ mkdir htdocs log conf
$ ls
conf htdocs log
続いて、apacheディレクトリ上にDockerfileを配置します。
FROM httpd
COPY conf/httpd.conf /usr/local/apache2/conf/httpd.conf
ここで設置する設定ファイルは以下のようにします。
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User www-data
Group www-data
HostnameLookups Off
LogLevel warn
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
# ports.conf
Listen 80
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
DocumentRoot /usr/local/apache2/htdocs
<Directory /usr/local/apache2/htdocs>
AllowOverride All
Require all granted
</Directory>
AccessFileName .htaccess
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
LogFormat "domain:%V\thost:%h\tserver:%A\tident:%l\tuser:%u\ttime:%{%d/%b/%Y:%H:%M:%S %z}t\tmethod:%m\tpath:%U%q\tprotocol:%H\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tagent:%{User-Agent}i\tresponse_time:%D" apache_ltsv
CustomLog /var/log/apache2/access.log apache_ltsv
ここで注目すべきはLogFormatとCustomLogの部分ですね。
LogFormatではapache_ltsvというログを自作していますが、これはltsv形式という解析しやすいログのフォーマットとなっています。
え?combined? fluentd先輩が読み込みに失敗することがあるので、使いません。
LTSVのすばらしさは、以下のサイトを見てみるといいでしょう。
LTSV FAQ - LTSV って何? どういうところが良いの?
最後にapacheで表示する内容ですが、なくてもいいです。
単純にapacheデフォルトの"It works!!"が出るだけでも十分ですが、一応用意してみましょう
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
docker-composeで立ち上げ
では、docker-composeを使ってapacheを立ててみましょう。
まず、docker-compose.ymlを以下のように作成します。
version: '2'
services:
apache:
build: ./apache
volumes:
- ./apache/log:/var/log/apache2
- ./apache/htdocs:/usr/local/apache2/htdocs
ports:
- 80:80
この状態で、docker-composeでapacheを立てます。
立てたらブラウザでアクセスしたり、curl打ったりしてみましょう。
$ docker-compose up -d
$ curl http://127.0.0.1/index.html
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
すると、ログ配下に
domain:127.0.0.1 host:172.24.0.1 server:172.24.0.4 ident:- user:- time:29/Sep/2016:**:**:** +0000 method:GET path:/index.html protocol:HTTP/1.1 status:200 size:55 referer:- agent:curl/7.43.0 response_time:5715
こんな感じのログが吐き出されます。
トラブルシューティング
ここで、apacheサーバが起動しない場合、confの設定が間違っている場合があります。
docker ps
コマンドでapacheサーバが起動していない場合は
$ docker-compose up
でフォアグラウンドで実行して、エラーを確かめましょう。
エラー箇所が判明したら、修正し、
$ docker-compose build apache
$ docker-compose up
で起動するまで試行錯誤しましょう。
後のfluentdについても同じです。
fluentdでログを読む
次に、fluentdでログを読んで、とりあえずホストにファイルで出力してみましょう。
今回はapacheサーバにfluentdを仕込んだりせず、ボリューム共有を使って直接ファイルからログを拾ってみましょう。
真面目にやるのならばログの集約サーバを用意するといいですが、今回はそこまで必要ではないでしょう。
まず、プロジェクトルート上に設定用のディレクトリを作成します。
$ mkdir fluentd
$ cd fluentd
$ mkdir data plugins
そして、fluentd用のDockerfileを作ります。
FROM fluent/fluentd
RUN gem install fluent-plugin-elasticsearch
COPY fluent.conf /fluentd/etc/fluent.conf
もう予めelasticsearch用のプラグインが入ってますね。
次に、fluentdの設定ファイルを作ります。
<source>
type tail
path /var/log/apache2/access.log
format ltsv
tag apache.access_log
pos_file /home/fluent/access.log.pos
time_format %d/%b/%Y:%H:%M:%S %z
</source>
<match apache.**>
type file
path /var/log/fluent/access
time_format %Y%m%dT%H%M%S%z
flush_interval 60s
#compress gzip
timezone +09:00
</match>
docker-composeで、サーバ起動
それではdocker-composeを使って、再びサーバを再起動させてみましょう。
version: '2'
services:
apache:
build: ./apache
volumes:
- ./apache/log:/var/log/apache2
- ./apache/htdocs:/usr/local/apache2/htdocs
ports:
- 80:80
fluentd:
build: ./fluentd
volumes:
- ./apache/log:/var/log/apache2
- ./fluentd/data:/var/log/fluent
environment:
FLUENTD_CONF: fluent.conf
このようにdocker-compose.ymlを書き換えた上で、
$ docker-compose stop
$ docker-compose up -d
$ curl http://127.0.0.1/index.html
すると、fluentd/data ディレクトリに、fluentdがファイルログを吐き出しているはずです。
動作の確認ができたら、一旦止めておきましょう。
$ docker-compose stop
Elasticsearchにログを入れるまで
さて、次にfluentdからログをelasticsearchに転送してみましょう。
ただ、とりあえず自分のローカルにもログは出し続けるようにしておきます。
elasticsearchの設定をdocker-compose.ymlに入れる
まず、elasticsearchとkibanaを使えるようにしておきましょう。
実際にこの二つは、すでにあるイメージをそのまま使ってしまうのが良いと思います。
docker-compose.ymlの設定は以下のとおりです。
version: '2'
services:
apache:
build: ./apache
volumes:
- ./apache/log:/var/log/apache2
- ./apache/htdocs:/usr/local/apache2/htdocs
ports:
- 80:80
fluentd:
build: ./fluentd
volumes:
- ./apache/log:/var/log/apache2
- ./fluentd/data:/var/log/fluent
environment:
FLUENTD_CONF: fluent.conf
elasticsearch:
image: elasticsearch
ports:
- 9200
kibana:
image: kibana
links:
- elasticsearch:elasticsearch
ports:
- 5601:5601
docker-composeの設定はこれで終わりです。
fluentdの設定し直し
elasticsearchにログを転送できるように、fluent.confを書き直しましょう。
<source>
type tail
path /var/log/apache2/access.log
format ltsv
tag apache.access_log
pos_file /home/fluent/access.log.pos
time_format %d/%b/%Y:%H:%M:%S %z
</source>
<match apache.**>
type copy
<store>
type elasticsearch
include_tag_key true
tag_key _tag
host elasticsearch
port 9200
index_name access
logstash_format true
logstash_prefix log
</store>
<store>
type file
path /var/log/fluent/access
time_format %Y%m%dT%H%M%S%z
#compress gzip
timezone +09:00
</store>
</match>
こんな感じで、ログをfluentdに流しつつ、ローカルにもログを吐き出すように設定できます。
編集が完了したら、fluentdイメージを再生成しておきます。
docker-compose build fluentd
docker-composeで起動
準備が整ったので、docker-composeを使ってサーバ群を起動してみましょう。
$ docker-compose up -d
$ curl http://127.0.0.1/index.html
これで大丈夫のはずです。
kibanaを眺めてみる。
kibanaが既に起動していて、5601ポートが空いていますので、以下のURLでkibanaを見てみましょう。
すると、こんな画面になります。
まず、フォームの「logstash-*」と書いてある部分の「logstash」を、fluent.confの「logstash_prefix」に設定した文字列に書き直して、フォーカスアウトすると、ボタンができるので、これを押します。
これでkibanaを使う準備が整いましたので、ログを見てみましょう。
画面上部の「Discover」というボタンがあるので、これを押してみましょう。
こんな感じの画面になり、いつアクセスが有ったかがわかるようになります。
あとは色々といじってみましょう。
ハンズオン自体はこれで終りとなります。
まとめ
dockerを使うと、いろいろなシミュレーションが簡単にできます。
今回のシミュレーションを本番に適用する場合は、ログ集約用のfluentdを作ってもいいかと思います。
今回はこんなところです。
参考
elasticsearch
fluentd-elasticsearch-plugin
fluentd × Elasticsearch × kibanaによるアクセスログ解析
Author And Source
この問題について(Apacheログをfluentdで読み出してelasticsearchに転送する流れをdockerでシミュレートするハンズオン), 我々は、より多くの情報をここで見つけました https://qiita.com/niisan-tokyo/items/73d8053afa539cfea65b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .