#osc16ep (20161005) | 2016-10-05 11:46 |
piwik-fluentd (2.0.3) | 2015-11-12 15:22 |
Piwik patches for Japanese (20160813) | 2016-08-13 15:23 |
import_logs.py を使って fluentd 経由で apache combined アクセスログを取り込む
Piwik で集計したいサイトは、Piwik 管理画面で指示される javascript をサイト内に埋め込む必要があります(Piwik tracker)。通常は、Piwik tracker により piwik.php を直接叩いてリアルタイム集計が行われるのですが、MySQL のトラブル、または Piwik の度重なる update 毎に集計がとまります。
apache または nginx のログを取り込む import_logs.py には、piwik.php のアクセスログよりリアルタイム集計を再現する機能がもともと実装されているのですが、取り込み単位が一ファイルなので、 トラブルまたはメンテナンスで停止していた時間を再集計 することが困難です。そこで、piwik-fluentd >= 2.0.0 では、 import_logs.py でログ取り込み範囲を時間選択できるオプションを追加しました。
Piwik tracker で普通に集計できていて、 piwik-fluentd で Piwik tracker のアクセスログ後追い集計を行うと二重集計になるのでご注意ください。
piwik のアクセス集計では web の各ページにトラッキングコードを入れることが最も理想的ではありますが、
等の理由により、apache の combined log から集計というせざるをえない場合があります。幸い piwik では、 import_logs.py という python ベースのアクセスログ取り込みプログラムが用意されています。しかしアクセスログから集計する上で最大かつどうしようもない問題が、 メモリ です。取り込むまではいいんです。しかし piwik では
piwik/console core:archiveを実行しなければ、グラフなどは出ません。 しかし、一つのある程度大きいログファイルを import_logs.py で読み込んだ後に、 console core:archive を叩くと、メモリが足りない
PHP Fatal error: Allowed memory size of XXXX bytes exhaustedとエラーが出て処理がとまります。処理がとまるたびに piwik/config/config.ini.php で minimum_memory_limit_when_archiving の数値を増やして対応することになりますが、すぐに限界がきます。たかだか 10 万ページビューのアクセスログで、8G 確保しても足りなくなるのです。 piwik 2.1から改善 されてはいるようなのですが、それでもメモリー食いすぎです。
まあでも、小さいログファイルに分割してちょくちょく
を交互に実行すれば 100 万ページビュー/月 であろうとも集計できるのです。ただ、ログ集計は以下の点でめんどくさい:
このうち、1, 2 (4 も?) については、いま流行っている fluentd でそう手間をかけずに piwik サーバーに集約できそうです。3, 4 については、難しいこと考えず単純に make とシェルスクリプトで実現することにします。
import_logs.py と console core:archive を実行する piwik サーバーに piwik-fluentd-2.0.3.tar.gz を展開します。 td-agent 以下、は web サイト毎のディレクトリです(説明上展開されるディレクトリは site1 - site5 としていますが、名前は何でもいいです)。td-agent 以下各サイトのアクセスログを格納するディレクトリは fluentd 導入後に owner を td-agent:td-agent とします。
your_own_path は、 piwik-fluentd-2.0.3.tar.gz を展開したディレクトリです。
/your_own_path/fluentd/ ├── bin (fluentd 対応の import_logs.py、シェルスクリプト) ├── exclude (取り込んではいけない URL パスが書かれたファイルを格納) ├── log (piwik/console core:archive のログ) ├── piwik-patch (Piwik 日本語(マルチバイト)問題解決パッチ) └── td-agent (各サイト毎アクセスログディレクトリ) ├── piwik_tracker (Piwik tracker のアクセスログ)(piwik-fluentd >=2.0.0) ├── site1 (Web サイト 1 のアクセスログ) ├── site2 (Web サイト 2) ├── site3 ├── site4 └── site5_test_disable (もしテストしたければ。disable を入れると定時処理からは除外する)
Piwik で集計したいサイトは、Piwik 管理画面で指示される javascript をサイト内に埋め込む必要があります(Piwik tracker)。通常は、Piwik tracker により piwik.php を直接叩いてリアルタイム集計が行われるのですが、piwik.php のアクセスログ、つまり Piwik サーバーそのもののアクセスログをここに配置することにより、リアルタイム集計を後追いすることができます。
対象 Web サーバー、1 siteid が 100 万ページビュー/月 を超えるときは、 piwik/config/config.ini.php の General セクションに次のように追加します:
[General] ; Minimum memory limit enforced when archived via ./console core:archive minimum_memory_limit_when_archiving = 2048
残念ながら、2G 程度は必要です。 さらに同じサーバーでデータベースを動かすのならば最低でも 4G 程度のメモリーが必要でしょう。 デフォルトは 768 で、月末にメモリーが足りなくなります。 monthly visitor の集計を行うので、月初はいいのですが、月末に近づくほど厳しくなります。
このあたりの議論は、 How do I enable “Unique Visitors” metric for Yearly reports and for Custom Date Ranges? を参照してください。ここにあるように yearly の集計を行うのであればもっとメモリが必要になります。
ここからダウンロード して、td-agent を piwik サーバー、各 web サイトサーバーともにインストールします。インストール時に td-agent というユーザーとグループが作られるのですが、uid, gid は固定ではないので、全サーバーで適当に合わせておきます。
/etc/td-agent/td-agent.conf
<match site1.example.com> ← Web サイトの tag 名と合わせること type file path /your_own_path/fluentd/td-agent/site1/access ← access はファイル名の prefix になります。 time_slice_format %Y%m%dT%H time_format %Y-%m-%dT%H:%M:%S%z # default 8m buffer_chunk_limit 16m compress gzip localtime ← これがないと突然 GMT になるときがあります </match>
/etc/td-agent/td-agent.conf
<source> type tail format apache ← urchin のログ形式ではないのでこれでよし time_format %d/%b/%Y:%H:%M:%S %z pos_file /var/log/td-agent/access_log.pos ← 複数サイトがあっても、pos_file は同じファイルにできます path /var/log/httpd/piwik/access_log tag piwiktracker.apache.access ← Piwik server の tag 名 </source> <match piwiktracker.apache.access> ← Piwik server の tag 名と合わせること type file path /your_own_path/fluentd/td-agent/piwik_tracker/access time_slice_format %Y%m%dT%H time_format %Y-%m-%dT%H:%M:%S%z # default 8m buffer_chunk_limit 16m compress gzip localtime ← これがないと突然 GMT になるときがあります </match>
/etc/td-agent/td-agent.conf
<source> type tail # urchin (combined + cookie) format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<cookie>[^\"]*)")?$/ time_format %d/%b/%Y:%H:%M:%S %z pos_file /var/log/td-agent/access_log.pos ← 複数サイトがあっても、pos_file は同じファイルにできます path /var/log/httpd/site1/access_log tag site1.example.com ← この Web サイトの tag 名 </source> <match site1.example.com> ← Web サイトの tag 名を合わせること type forward send_timeout 60s recover_wait 300s heartbeat_interval 1s phi_threshold 16 hard_timeout 60s <server> name piwik host piwik サーバーの IP アドレス port 24224 weight 100 </server> # use longer flush_interval to reduce CPU usage. # note that this is a trade-off against latency. # flush_interval 60s </match>
/var/log/httpd/site1/access_log については、一意のファイル名でないとなりません。 cronolog とか apache の rotatelogs を使ってアクセスログのファイル名に日付を付ける設定にしている場合は、現在書き込みをしているログファイルに一意の(たとえば access_log)シンボリックリンクを張るオプションを利用しファイル名が見かけ上変わらないようにします。
なお cronolog 使用時は 1 時間ごとにシンボリックリンクのタイムスタンプが変更されてしまい、fluentd がログが切り替わったと誤判定してpiwikサーバーに同じログが二重に転送されてしまいます。 cronolog ではこのようなオプションは使わず、たとえば次のようなスクリプトを毎日 00:00:00 に実行することで対処できます。
td-agent.conf の format の正規表現は、現状のログに合わせてください。ミスマッチの場合、デフォルトではすべてのアクセスログが web サイトサーバーの /var/log/td-agent/td-agent.log に記録され、あっちゅー間に /var が一杯になります。アクセスログをカスタマイズしている場合は Fluentular で一度チェックします。
設定が完了したら fluentd を起動します。起動したら、/var/log/td-agent 以下のログで設定が問題ないかを確認します。piwik サーバーの各サイト毎アクセスログディレクトリに access.20140701T16_0.log.gz のようなファイルが作製されれば成功です。
# /etc/init.d/td-agent start # chkconfig td-agent on