これは、なにをしたくて書いたもの?
Fluentdを使って、ひとつのinputから条件に応じてoutputを振り分ける練習に、と。
お題
Fluentdを使って、Apacheのアクセスログをtailして読み込み、HTMLとそれ以外にアクセスした際のログを、別々のoutputに
振り分けるというお題で試してみます。
HTMLに対するアクセスログはElasticsearch、それ以外に対するアクセスログは標準出力(Fluentdのログ)に出力するものとします。
環境
Ubuntu Linux 18.04 LTS上で行い、Fluentdのバージョンは以下とします。
2019-03-09 06:05:25 +0000 [info]: starting fluentd-1.3.3 pid=25 ruby="2.4.5"
Apacheは、同じ環境上でインストール。Apacheで公開するコンテンツは、Apache自身のドキュメントとしましょう。
$ sudo apt install apache2 -y $ sudo systemctl start apache2.service $ cd /var/www/html/ $ sudo wget https://www-us.apache.org/dist//httpd/docs/httpd-docs-2.4.33.en.zip $ sudo unzip httpd-docs-2.4.33.en.zip $ sudo mv httpd-docs-2.4.33.en/* ./.
Apacheのバージョン。
[Sat Mar 09 06:07:01.535225 2019] [mpm_event:notice] [pid 554:tid 140371125488576] AH00489: Apache/2.4.29 (Ubuntu) configured -- resuming normal operations
Fluentdがアクセスログを読むことができるように、Apacheのログ出力まわりの権限を変更しておきます。
$ sudo chmod 755 /var/log/apache2 $ sudo chmod 544 /var/log/apache2/*
Elasticsearchは、6.6.1で別ホスト(172.17.0.3)で用意。
ここまでが、前提環境です。
Fluentdの設定をする
では、Fluentdの設定をしましょう。
Input Pluginとしてtail、ログのパースにはapache2を使いましょう。
apache2 Parser Plugin | Fluentd
Output Pluginとしては、elasticsearchとstdout。
Elasticsearch Output Plugin | Fluentd
stdout Output Plugin | Fluentd
ログの振り分けには、rewrite_tag_filterでタグを付け替えることで行います。
rewrite_tag_filter Output Plugin | Fluentd
結果、こんな感じになりました。
/etc/td-agent/td-agent.conf
<source> @type tail @id input_tail <parse> @type apache2 </parse> path /var/log/apache2/access.log pos_file /var/log/td-agent/apache2-access.log.pos tag apache.access </source> <match apache.access> @type rewrite_tag_filter @id rewrite_tag <rule> key path pattern /(\/|\.html)$/ tag apache.access.html </rule> <rule> key path pattern /.+/ tag apache.access.styles </rule> </match> <match apache.access.html> @type elasticsearch @id output_elasticsearch host 172.17.0.3 port 9200 index_name html-access-log </match> <match apache.access.styles> @type stdout @id output_styles_stdout </match>
ポイントはout_rewrite_tag_filterの設定で、あるキー(項目)に対して正規表現を書いて、マッチしたものに対してタグを
付け替えるように指定します。
<match apache.access> @type rewrite_tag_filter @id rewrite_tag <rule> key path pattern /(\/|\.html)$/ tag apache.access.html </rule> <rule> key path pattern /.+/ tag apache.access.styles </rule> </match>
今回は「path」が「/」で終わるか拡張子「.html」だった場合は「tag apache.access.html」というタグにリライトし、
<rule> key path pattern /(\/|\.html)$/ tag apache.access.html </rule>
それ以外のものは「apache.access.styles」というタグにリライトしました。
<rule> key path pattern /.+/ tag apache.access.styles </rule>
このタグがルーティングされるように、Output Pluginの設定を行っています。
<match apache.access.html> @type elasticsearch @id output_elasticsearch host 172.17.0.3 port 9200 index_name html-access-log </match> <match apache.access.styles> @type stdout @id output_styles_stdout </match>
他のサンプルとしては、out_rewrite_tag_filterのドキュメントにも載っているのでこちらを見てみるとよいでしょう。
ここまで設定したら、Fluentdを再起動。
確認
では、Apacheにアクセスして確認してみます。
Fluentdのログには、以下のように画像やCSSなどに関するアクセスログが出力されます。
2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual-zip.css","code":200,"size":862,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/prettify.css","code":200,"size":1443,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/images/left.gif","code":200,"size":342,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/scripts/prettify.min.js","code":200,"size":13428,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual.css","code":200,"size":4557,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/images/feather.png","code":200,"size":21432,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual-zip-100pc.css","code":200,"size":870,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual-print.css","code":200,"size":3427,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual-loose-100pc.css","code":200,"size":1445,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"} 2019-03-09 06:24:59.000000000 +0000 apache.access.styles: {"host":"172.17.0.1","user":null,"method":"GET","path":"/favicon.ico","code":404,"size":501,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
一方で、Elasticsearch側には
$ curl '172.17.0.3:9200/html-access-log/_search?q=*&pretty' { "took" : 82, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "OHogYWkBIj4IrKe-DMlO", "_score" : 1.0, "_source" : { "host" : "172.17.0.1", "user" : null, "method" : "GET", "path" : "/", "code" : 200, "size" : 2502, "referer" : null, "agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" } } ] } }
このアクセスログはトップページへのものですが、その他のページについても順次ログが保存されていきます。
{ "_index" : "html-access-log", "_type" : "fluentd", "_id" : "OnojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "host" : "172.17.0.1", "user" : null, "method" : "GET", "path" : "/getting-started.html", "code" : 200, "size" : 4747, "referer" : "http://172.17.0.2/", "agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" } },
Fluentdのログに、HTMLのログが出力されていないことを確認。
$ $ grep apache.access.styles /var/log/td-agent/td-agent.log | grep '"path":' | grep -Ec '"path":"(/|[^"]+html)"' 0 $ grep apache.access.styles /var/log/td-agent/td-agent.log | grep '"path":' | perl -wp -e 's!.+"path":"([^"]+)".+!$1!; s!.+(\..+)!$1!' | sort -u .css .gif .ico .js .png
Elasticsearch側も確認。
$ curl '172.17.0.3:9200/html-access-log/_search?q=*&pretty&_source=path' { "took" : 3, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 9, "max_score" : 1.0, "hits" : [ { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "PHojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/howto/auth.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "PXojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/vhosts/index.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "OXohYWkBIj4IrKe-QMnm", "_score" : 1.0, "_source" : { "path" : "/" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "P3ojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/stopping.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "OHogYWkBIj4IrKe-DMlO", "_score" : 1.0, "_source" : { "path" : "/" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "O3ojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/index.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "QHokYWkBIj4IrKe-_smY", "_score" : 1.0, "_source" : { "path" : "/vhosts/index.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "OnojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/getting-started.html" } }, { "_index" : "html-access-log", "_type" : "fluentd", "_id" : "PnojYWkBIj4IrKe-qslX", "_score" : 1.0, "_source" : { "path" : "/stopping.html" } } ] } }
いくつかアクセスしても、HTMLやトップページ(「/」)に対するアクセスのみが入ります。
大丈夫そうです。