Y-Ken Studio

新しもの好きのデータエンジニアが四方山話をお届けします。

自在にタグを書き換える fluent-plugin-rewrite-tag-filter でログ解析が捗るお話 #fluentd

皆様、ログ解析を行っていますか?
GoogleAnalyticsも便利ですが、表で取れないデータの解析も行いたいですよね。そんな時にfluentdが便利です。
内部の生ログからの解析が捗る、fluent-plugin-rewrite-tag-filter が安定版となりましたので、設定例を交えつつ紹介したいと思います。
このプラグインは100台規模の本番環境で1ヶ月少々、特にトラブルもなく稼働しているものです。


はじめに

Amazonでは応答速度が0.1秒遅くなると売り上げが1%減る と言われているように、Webアプリケーションの応答速度はとても重要なものです。
機能追加による性能劣化は良くある話で、応答速度等の見える化を行う事で迅速な対応が取れば売り上げ等への影響も軽微です。
パフォーマンス改善等の指標として利用する場合のユースケースを紹介したいと思います。

fluentdとは

リアルタイムに構造化されたログを収集する汎用ツールで、既にNHN(Livedoor)やcookpadslideshareなどで実践投入されているrubyプロダクトです。
豊富なプラグインと拡張性を持ちながら、導入の敷居がこれまでのscribed等に比べて劇的に低いのが特徴です。

fluent-plugin-rewrite-tag-filterとは

データ内容を条件に任意のtagに書き換えるという、Apachemod_rewriteを意識したフィルタプラグインです。
先頭から順番に正規表現で評価し、該当すればそのtagに書き換えるという動作をします。
https://github.com/y-ken/fluent-plugin-rewrite-tag-filter
http://rubygems.org/gems/fluent-plugin-rewrite-tag-filter

例えば、このプラグインを組み合わせて利用することで、Apacheアクセスログから以下の解析を行う事も出来ます。

  • サイト毎・機能毎の応答速度集計とグラフ化を行う
    見える化されている事で、一部機能の性能劣化が起きても迅速に改善が出来ます。
  • 検索エンジンのロボットによるクロール状況推移のグラフ化
    サイトのリリース後、どれほどロボットにクロールされているのか気になりますよね。

プラグインのインストール方法

  • ネイティブインストールしている場合
gem install fluent-plugin-rewrite-tag-filter
  • td-agent を使ってインストールしている場合
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-rewrite-tag-filter

使用例

マルチドメイン環境のApacheアクセスログを用いた、3つの設定例を紹介します。

  1. サイト毎にテーブルを分けてアクセスログをmongoDBへ保存する
  2. サイト・機能毎に応答速度、レスポンスコード、UserAgentを集計し、グラフ化する
  3. 指定URLやUserAgent等を除外した後に応答速度の集計を掛け、グラフ化する

使用例1: サイト毎にテーブルを分けてmongoDBへ保存

  • 設定ファイル
# ログの読み込み
<source>
  type tail
  path /var/log/httpd/access_log
  format /^(?<domain>[^ ]*) (?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<status>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" (?<response_time>[^ ]*))?$/
  time_format %d/%b/%Y:%H:%M:%S %z
  tag td.apache.access
  pos_file /var/log/td-agent/apache_access.pos
</source>

# 先頭から順番に正規表現で評価し、該当すれば、そのtagに書き換えます。
# rewriterule1のように除外してから処理を進める事や、
# rewriterule5のようにいずれにも該当しなかったデータにtagを付ける事も出来ます。
<match td.apache.access>
  type rewrite_tag_filter
  #rewriteruleN <key> <pattern> <new_tag>
  rewriterule1 path \.(gif|jpe?g|png|pdf|zip)$ clear
  rewriterule2 domain ^maps\.google\.com$ site.GoogleMap
  rewriterule3 domain ^news\.google\.com$ site.GoogleNews
  rewriterule4 domain ^mail\.google\.com$ site.GoogleMail
  rewriterule5 domain .* site.other
</match>

# site.*というパターンのtagをmongoDBにへ保存します。
# tag_mapped指定を付けると、テーブル名にtagが使われるので、個別に指定する必要はありません。
<match site.*>
  type mongo
  host localhost
  database apache_access
  remove_tag_prefix site
  tag_mapped
  capped
  capped_size 100m
</match>

# 不要なタグはそのまま削除します。
<match clear>
  type null
</match>
  • 結果

タグ毎にテーブルを分けて保存する事が出来ました。

$ mongo
MongoDB shell version: 2.0.6
> use apache_access
switched to db apache_access
> show collections
GoogleMap
GoogleNews
GoogleMail
other

使用例2: サイト・機能毎に応答速度、レスポンスコード、UserAgentを集計し、グラフ化する

実践応用編となる、 使用例2の設定サンプル にて行っている事をまとめると以下の通りです。

  • アクセスログをtag名 td.apache.access に格納
  • で取り込んだドメインを見て、サイト毎にtagを書き換えと、機能毎の解析用のtagへの書き換えも行う
  • 機能毎の解析用のtagにて、URL毎のtag書き換えや、referer毎のtag書き換え、UserAgent毎のtag書き換えを行う
  • 先程作成したtagを で取り込み、以下それぞれの集計を掛けてタグの書き換えを行う
    • 応答速度の集計を行い、tagの接頭辞に gf.responsetime. を追加
    • レスポンスコードの集計を行い、tagの接頭辞に gf.responsecode.を追加
    • UserAgent毎の集計を行い、tagの接頭辞に gf.useragent. を追加
  • tag毎にgrowthforecastプラグインを利用し、グラフ化を行う

なお、この記事のトップ画像は、この設定を基に作られたGrowthForecastの画面のキャプチャです。

使用例3: 指定URL等を除外した後に応答速度の集計を掛け、グラフ化する

不要なパターンを除外した後に集計を掛けるサンプルです。
使用例2と共通部分が多いため解説を省略します。
使用例3の設定サンプル

まとめ

  • out_exec_filter 書かなくて良い。楽。
  • データの中身は変更せず、タグの書き換えを自在に行えます。

以上、非常にシンプルですが強力なプラグインですので、積極的にこのプラグインを利用して頂けると嬉しいです。