SlideShare a Scribd company logo
1 of 28
Download to read offline
Piwik + flutned で 100 万 pv/month サイトのログ解析
YAMAMOTO Takashi
yamachan@piwikjapan.org
Piwik Japan
OSC Tokyo fall
Oct 25, 2015
すでに公開しています
■ Piwik Japan ユーザー会
■ http://www.piwikjapan.org/
■ osdn https://osdn.jp/projects/piwik-fluentd/
■ Piwik osdn で検索するとでます。
■ 細かい設定はすべてこちらに記述しています。
■ 日本語問題のパッチもここに置いています。
2 of 28
ひとつ前のバージョンに対応しています
■ Piwik 2.6.0 - Piwik 2.14.3
■ 2.14.3 は 2015/8 に公開
■ 最新といいたかったんだけど 2.15.0 がおととい(2015/10/21)
にでてしまいました...
3 of 28
その前に
4 of 28
なぜ Piwik なのか
■ Urchin がなくなった
□ google に買収され、現在は google Analytics になった
□ アプリケーションであり google にデータを渡すことなく自前でログ
解析ができた
■ ID を分けて、担当の Web サイト以外の集計は見せないようし
たい
■ google にアクセスログ渡したくない
■ Open Source でログが取り込めるのは Piwik だけ
□ もちろん他もあるけどどれも開発はだいぶ前に終了、今からみれば
低機能
5 of 28
Piwik fluentd で何ができるのか
■ apache のログを Piwik にとりこみます
■ ログは fluentd 形式です
□ 標準では対応していません
■ ついでに、日本語文字コード関連の問題の解決
6 of 28
最新版 piwik-fluentd 2.0.2 では
■ Piwik のリアルタイム集計をログから再現できるようになりま
した
□ トラッキングコード(Javascript)を Web サイトに埋め込むことに
より、apache のログでは採取できないサイト来訪者の詳細情報(画
面の解像度など)を Piwik サーバーに送信します。
□ google Analitics のトラッキングコードと同じ役割です。
□ トラッキングコードからのデータは、通常リアルタイム集計され
ます。
■ 従来からトラッキングコードのログから再現できる機能はありま
したが、fluentd に対応させていませんでした
7 of 28
リアルタイム集計再現でなにがうれしいのか
■ Piwik アップデート時にリアルタイム集計をとめざるをえない
□ 良くも悪くも、頻繁にアップデートされます(一か月に一度程度)
□ Piwik は MySQL をデータ蓄積につかいます
□ アップデート時にデータベースのカラムを追加することがあります
■ 数千万レコードあるテーブルにカラムを追加されることがあります
□ つまりアップデート時のリアルタイム集計停止は避けられません。
■ MySQL 自体が壊れてリアルタイム集計停止
□ 長時間の稼働停止... 各部署から怒られる、まあ直せばいいけど
□ でも、壊れている間のデータはどうなるの
■ Piwik サーバーのログさえあれば後からなんとかできるのはうれ
しい
8 of 28
Piwik ログ取り込みプログラム import logs.py(1)
■ あらゆるログの取り込みを担当
□ piwik/misc/log-analytics/import logs.py
■ ここだけ Python(他は PHP)
■ ログを読み取って、Piwik の API に変換します
□ apache (Urchin 形式含む)、nginx、IIS など
9 of 28
Piwik ログ取り込みプログラム import logs.py(2)
■ 指定したファイルをとりこむだけ。気が利いた機能の実装はあり
ません。
□ 複数のサーバーから apache ログを ftp でとってくるとかそんなの
ない。
□ すでに取り込んだファイルはどこかで覚えておかないとならない。
□ 馬鹿でかいログのの途中から取り込む機能はあるが、開始行を指定
しないとなりません。
■ HTTP POST, GET だけとりこんでくれればいいのだがなぜか
フィルタなし。
□ apache のログを取り込む場合です。
□ トラッキングコードのログ取り込み時は piwik.php のログだけを選択
します。
10 of 28
実装することにします
■ ログの管理機能強化
□ 取り込み済ログの識別 → make を使う
□ 複数サーバーからのとりこみ → fluentd を使う
■ 便利オプションの追加
□ HTTP ヘッダ別で取り込みを選択できるように
□ ある時間範囲だけ取り込むように
□ ページビューから除外する拡張子(urchin と実装を同じにできる)
□ ページビューに含む拡張子(urchin と実装を同じにできる)
□ fluentd 形式(json)ファイルの取り込み
■ バグ? の修正
□ apache ログ取り込み時刻を JST になおす
11 of 28
fluentd はほんとよくできてます
■ こんなことが便利です
□ 複数サイトからログを集約できる
□ 接続断でも、復活後追いかけてくれる
□ ファイルの分割機能
12 of 28
Web ログサーバーをつくることにしました(1)
■ ディレクトリ構成
/your_own_path/fluentd/
├ bin (fluentd 対応の import_logs.py、シェルスクリプト)
├ exclude (取り込んではいけない URL パス)
├ log (piwik/console core:archive のログ)
└ td-agent (各サイト毎アクセスログディレクトリ)
├ piwik_tracker (Piwik tracker のアクセスログ)
├ site1(Web サイト 1 のアクセスログ)
├ site2(Web サイト 2)
├ site3(Web サイト 2)
└ site4(Web サイト 2)
13 of 28
Web ログサーバーをつくることにしました(2)
■ site[1..N] に fluentd からのアクセスログを取り込みます。
□ piwik tracker には piwik 自身のからのアクセスログです。
■ fluentd の設定は osdn を見てください
□ osdn の例では、16M バイト毎に分割していますが、変更可能です。
■ 複数サイトでも fluentd で楽勝です。
■ 少々停止しても転送してくれます。
14 of 28
Web ログサーバーをつくることにしました(3)
■ fluentd からのアクセスログは一定時間毎のバッチで Piwik に取り
込みます。
■ 取り込み完了しているか否かの判定は make に任せます。
□ 新しいファイルは import logs.py にかけられます。
□ ひとつのファイルを取り込みごとに .archive ファイルを作ります
■ このファイルに import logs.py の実行結果が入ります
■ とりこんだ後に集計プロセスを実行しないとなりません
□ import logs.py で取り込んだだけではグラフがでません。
□ バッチの最後に一度だけ、集計プロセスを動かすことにします。
15 of 28
ディレクトリ構成をもう少し見てみましょう
■ ディレクトリ構成
/your_own_path/fluentd/
├ bin (fluentd 対応の import logs.py、シェルスクリプト)
├ exclude (取り込んではいけない URL パス)
├ log (piwik/console core:archive のログ)
└ td-agent (各サイト毎アクセスログディレクトリ)
├ piwik_tracker (Piwik tracker のアクセスログ)
├ site1(Web サイト 1 のアクセスログ)
├ site2(Web サイト 2)
├ site3(Web サイト 2)
└ site4(Web サイト 2)
16 of 28
全体的な設定
■ /your own path/fluentd/bin/env.sh
export PIWIK_INSTALL_DIR=/var/www/piwik/
export PIWIK_URL=http://piwik.example.com/
export PIWIK_TOKEN_AUTH=cxxxxxxxxxxxxxxxxxxxxc ← トークン
export PIWIK_BULK_ARCHIVE=1 ← 最後に一度だけ集計プロセス=1
□ import logs.py から Piwik API を叩くための設定
17 of 28
各サイトの設定(1)∼ 集計除外 URL
■ /your own path/fluentd/exclude/exclude idsite1.txt
/robots.txt
/favicon.*
□ 集計除外したいファイルを指定する
□ 数字は siteid です。exclude idsite[siteid].txt
18 of 28
各サイトの設定(2)∼ siteid
■ /your own path/fluentd/td-agent/site1/IDSITE
IDSITE=4
□ td-agent の下のディレクトリ名は実は適当でいいです。
□ ただしディレクトリ名に disable を入れると集計から除外します。例:
site1 disable
□ リアルタイム集計再現のときは IDSITE=0
19 of 28
各サイトの設定(3)∼ 集計済ファイルの退避先
■ /your own path/fluentd/td-agent/site1/MOVECONDITIONS
LEAVEFILES=2000
DESTDIR=done
□ 集計済ファイルが 2000 を超えると td-agent/site1/done に入れます
■ DESTDIR はなければ作成します。
■ ファイルがあまり多いと make でさばきれなくなるのです。
20 of 28
各サイトの設定(4)∼ 時間範囲
■ /your own path/fluentd/td-agent/site1/IMPORTRANGE
IMPORT_START="2015-10-23:0:0:0"
IMPORT_END="infinity"
□ IMPORT START から IMPORT END までのデータを取り込みます。
■ 取り込みが終わっていないファイルが対象です。
■ 時間外のファイルはすべて集計済としますが、取り込みません。
■ IMPORT START, IMPORT END 両方に infinity を指定できます。
■ Piwik が停止していた時刻だけ取り入れることを想定。
21 of 28
Piwik 日本語問題
22 of 28
開発サーバーとの共用で問題発覚
■ 開発サーバーと共用していて my.cnf で自動変換をお断りしていた
[mysql]
sql_mode="traditional" ← お断りの呪文
■ MySQL の自動変換とは 1
数値 範囲外の数値は頭を押さえつけられる
数値 小数は勝手に丸められる(warning も出ない)
数値 数字以外が入っていると分かるところまでを登録してくれる
文字列 長さを超えると勝手にカットされる
文字列 カラムと異なる文字コードは適当に丸められる
■ 呪文で自動変換をやめさせて、エラーとします
□ 開発時にはエラーとしないとあとから非常に厄介です
1
http://sakaik.hateblo.jp/entry/20100225/mysqlautochange23 of 28
自動変換なし: 文字化け、自動変換お断り: 落ちる
■ パターン 1: UTF-8 前提としたつくりに抵触する
□ サイト検索エンジンキーワードが SJIS または EUC
□ 自サイトの検索キーワードが SJIS または EUC
□ そもそも Piwik トラッカーからのリクエストが文字化け
■ トラッカーからは title 文字列が UTF-8 で送られてきます
■ パターン 2: マルチバイトを前提としたつくりになっていない
□ substr じゃなくて mb substr
□ カラムに合わせて文字列を詰める箇所があるのですが、
□ MySQL の VARCHAR(n) の n はマルチバイトも含めた文字数です。
■ Piwik コミッターがバイト=文字列と思いこんでいる
□ マルチバイトの途中で詰められるともちろん文字化け
24 of 28
サイト検索エンジンキーワード
■ piwik/core/DataFiles/SearchEngines.php
// goo
- ’search.goo.ne.jp’ =>
array(’goo’, ’MT’, ’web.jsp?MT=k’),
- ’ocnsearch.goo.ne.jp’ =>
array(’goo’),
+ ’search.goo.ne.jp’ =>
array(’goo’, ’MT’, ’web.jsp?MT=k’,
array(’UTF-8’, ’EUC-JP’, ’MS932’)),
+ ’ocnsearch.goo.ne.jp’ =>
array(’goo’, ’’, ’’,
array(’UTF-8’, ’EUC-JP’, ’MS932’)),
25 of 28
Piwik トラッカーからの文字列が文字化け
■ piwik/core/Tracker/PageUrl.php
public static function cleanupString($string)
{
$string = trim($string);
- $string = str_replace(array("n", "r", "0"), ’’, $string);
-
+ if (function_exists(’mb_check_encoding’)
+ && !@mb_check_encoding($string, ’utf-8’, true)
+ ) {
□ mb check encoding の三番目のパラメータが重要
□ It would perform a more thorough check, and the result of that call
would be FALSE.2
2
http://stackoverflow.com/questions/17958226/what-does-mbstring-strict-
detection-do26 of 28
マルチバイトを考慮していない
■ piwik/plugins/Referrers/Columns/Keyword.php
$information = $this->getReferrerInformationFromRequest($request);
if (!empty($information[’referer_keyword’])) {
- return substr($information[’referer_keyword’], 0, 255);
+ if (function_exists(’mb_substr’)) {
+ return mb_substr($information[’referer_keyword’], 0, 255, ’UTF-8’
+ } else {
+ return substr($information[’referer_keyword’], 0, 255);
+ }
}
return $information[’referer_keyword’];
□ VARCHAR(255) 制限のために入れたみたいだけど... これはひどい...
27 of 28
ブースは 202 です。
ロシアの飴ちゃん配ってます。
28 of 28

More Related Content

What's hot

GoでEPC作って本番運用している話
GoでEPC作って本番運用している話GoでEPC作って本番運用している話
GoでEPC作って本番運用している話雄也 日下部
 
Qt5 の Input Method
Qt5 の Input MethodQt5 の Input Method
Qt5 の Input MethodTakumi Asaki
 
今さら聞けない人のためのgit超入門 OSC2018京都 資料
今さら聞けない人のためのgit超入門 OSC2018京都 資料今さら聞けない人のためのgit超入門 OSC2018京都 資料
今さら聞けない人のためのgit超入門 OSC2018京都 資料VirtualTech Japan Inc./Begi.net Inc.
 
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7GitLabを骨までしゃぶりつくす@ゆるUniStudy#7
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7Wataru NOGUCHI
 
GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)Wataru NOGUCHI
 
Git 入門
Git 入門Git 入門
Git 入門y-uti
 
HTTP/2でも初めてみます?
HTTP/2でも初めてみます?HTTP/2でも初めてみます?
HTTP/2でも初めてみます?Kento Kawakami
 
HTTP2 時代の Web - web over http2
HTTP2 時代の Web - web over http2HTTP2 時代の Web - web over http2
HTTP2 時代の Web - web over http2Jxck Jxck
 
Arduino compatible layer (with 6LoWPAN) on Contiki
Arduino compatible layer (with 6LoWPAN) on ContikiArduino compatible layer (with 6LoWPAN) on Contiki
Arduino compatible layer (with 6LoWPAN) on Contiki裕士 常田
 
Qt5 の新機能 2012/12/15
Qt5 の新機能 2012/12/15Qt5 の新機能 2012/12/15
Qt5 の新機能 2012/12/15Takumi Asaki
 
RubyでGUIアプリケーションを書く
RubyでGUIアプリケーションを書くRubyでGUIアプリケーションを書く
RubyでGUIアプリケーションを書くMisao X
 
今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集Wataru NOGUCHI
 
猫にはわからないGit講座
猫にはわからないGit講座猫にはわからないGit講座
猫にはわからないGit講座Yusei Yamanaka
 

What's hot (20)

GoでEPC作って本番運用している話
GoでEPC作って本番運用している話GoでEPC作って本番運用している話
GoでEPC作って本番運用している話
 
今さら聞けない人のためのGit超入門
今さら聞けない人のためのGit超入門今さら聞けない人のためのGit超入門
今さら聞けない人のためのGit超入門
 
Qt5 の Input Method
Qt5 の Input MethodQt5 の Input Method
Qt5 の Input Method
 
今さら聞けない人のためのgit超入門 OSC2018京都 資料
今さら聞けない人のためのgit超入門 OSC2018京都 資料今さら聞けない人のためのgit超入門 OSC2018京都 資料
今さら聞けない人のためのgit超入門 OSC2018京都 資料
 
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7GitLabを骨までしゃぶりつくす@ゆるUniStudy#7
GitLabを骨までしゃぶりつくす@ゆるUniStudy#7
 
Gitの使い方あれこれ
Gitの使い方あれこれGitの使い方あれこれ
Gitの使い方あれこれ
 
GitLabをバックアップしてみた
GitLabをバックアップしてみたGitLabをバックアップしてみた
GitLabをバックアップしてみた
 
Git (実践入門編)
Git (実践入門編)Git (実践入門編)
Git (実践入門編)
 
GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)GitLabを16万8千光年ワープさせた話(改)
GitLabを16万8千光年ワープさせた話(改)
 
Git 入門
Git 入門Git 入門
Git 入門
 
今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21
 
HTTP/2でも初めてみます?
HTTP/2でも初めてみます?HTTP/2でも初めてみます?
HTTP/2でも初めてみます?
 
Git
GitGit
Git
 
HTTP2 時代の Web - web over http2
HTTP2 時代の Web - web over http2HTTP2 時代の Web - web over http2
HTTP2 時代の Web - web over http2
 
Arduino compatible layer (with 6LoWPAN) on Contiki
Arduino compatible layer (with 6LoWPAN) on ContikiArduino compatible layer (with 6LoWPAN) on Contiki
Arduino compatible layer (with 6LoWPAN) on Contiki
 
Intel graphics
Intel graphicsIntel graphics
Intel graphics
 
Qt5 の新機能 2012/12/15
Qt5 の新機能 2012/12/15Qt5 の新機能 2012/12/15
Qt5 の新機能 2012/12/15
 
RubyでGUIアプリケーションを書く
RubyでGUIアプリケーションを書くRubyでGUIアプリケーションを書く
RubyでGUIアプリケーションを書く
 
今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集今時のDev opsの取り組み事例集
今時のDev opsの取り組み事例集
 
猫にはわからないGit講座
猫にはわからないGit講座猫にはわからないGit講座
猫にはわからないGit講座
 

Similar to Piwik fluentd at OSC Tokyo 2015 Fall

IBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみたIBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみたYou&I
 
ログにまつわるエトセトラ
ログにまつわるエトセトラログにまつわるエトセトラ
ログにまつわるエトセトラ菊池 佑太
 
WordBench YAMAGUCHI at Ube
WordBench YAMAGUCHI at UbeWordBench YAMAGUCHI at Ube
WordBench YAMAGUCHI at UbeTakashi Yamamoto
 
170622 02
170622 02170622 02
170622 02openrtm
 
今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版VirtualTech Japan Inc./Begi.net Inc.
 
今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版VirtualTech Japan Inc./Begi.net Inc.
 
継続的インテグレーション3分クッキング
継続的インテグレーション3分クッキング継続的インテグレーション3分クッキング
継続的インテグレーション3分クッキングTakayuki Kondou
 
LibreOffice を Windows 上でビルドする UPDATE
LibreOffice を Windows 上でビルドする UPDATELibreOffice を Windows 上でビルドする UPDATE
LibreOffice を Windows 上でビルドする UPDATETomofumi Yagi
 
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hackyut148atgmaildotcom
 
Robotech2012講習会v01最終版v2
Robotech2012講習会v01最終版v2Robotech2012講習会v01最終版v2
Robotech2012講習会v01最終版v2Yuki Suga
 
Rally Updates Mitaka and Next step for Newton
Rally Updates Mitaka and Next step for NewtonRally Updates Mitaka and Next step for Newton
Rally Updates Mitaka and Next step for NewtonYuki Nishiwaki
 
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話Koichiro Sumi
 
ロボットシステム学2015年第9回
ロボットシステム学2015年第9回ロボットシステム学2015年第9回
ロボットシステム学2015年第9回Ryuichi Ueda
 
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶ
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶLingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶ
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶKenichiro MATOHARA
 
OpenStack Object Storage; Overview
OpenStack Object Storage; OverviewOpenStack Object Storage; Overview
OpenStack Object Storage; Overviewirix_jp
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!Yohei Fushii
 

Similar to Piwik fluentd at OSC Tokyo 2015 Fall (20)

IBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみたIBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみた
 
ログにまつわるエトセトラ
ログにまつわるエトセトラログにまつわるエトセトラ
ログにまつわるエトセトラ
 
WordBench YAMAGUCHI at Ube
WordBench YAMAGUCHI at UbeWordBench YAMAGUCHI at Ube
WordBench YAMAGUCHI at Ube
 
170622 02
170622 02170622 02
170622 02
 
今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版
 
今さら聞けない人のためのGit超入門 OSC2018広島版
今さら聞けない人のためのGit超入門 OSC2018広島版今さら聞けない人のためのGit超入門 OSC2018広島版
今さら聞けない人のためのGit超入門 OSC2018広島版
 
今さら聞けない人のためのGit超入門 2020/12/19
今さら聞けない人のためのGit超入門 2020/12/19今さら聞けない人のためのGit超入門 2020/12/19
今さら聞けない人のためのGit超入門 2020/12/19
 
今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版
 
今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門
 
継続的インテグレーション3分クッキング
継続的インテグレーション3分クッキング継続的インテグレーション3分クッキング
継続的インテグレーション3分クッキング
 
Outputz.vim
Outputz.vimOutputz.vim
Outputz.vim
 
LibreOffice を Windows 上でビルドする UPDATE
LibreOffice を Windows 上でビルドする UPDATELibreOffice を Windows 上でビルドする UPDATE
LibreOffice を Windows 上でビルドする UPDATE
 
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
 
Robotech2012講習会v01最終版v2
Robotech2012講習会v01最終版v2Robotech2012講習会v01最終版v2
Robotech2012講習会v01最終版v2
 
Rally Updates Mitaka and Next step for Newton
Rally Updates Mitaka and Next step for NewtonRally Updates Mitaka and Next step for Newton
Rally Updates Mitaka and Next step for Newton
 
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話
毎日2000個のコンテナをstartする鯖が突然死して僕が驚愕した話
 
ロボットシステム学2015年第9回
ロボットシステム学2015年第9回ロボットシステム学2015年第9回
ロボットシステム学2015年第9回
 
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶ
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶLingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶ
LingrBotを作ってみた/ ownCloud+Andoroid+Picasa+Flickr連携/Chromecast をLinuxで遊ぶ
 
OpenStack Object Storage; Overview
OpenStack Object Storage; OverviewOpenStack Object Storage; Overview
OpenStack Object Storage; Overview
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!
 

Piwik fluentd at OSC Tokyo 2015 Fall

  • 1. Piwik + flutned で 100 万 pv/month サイトのログ解析 YAMAMOTO Takashi yamachan@piwikjapan.org Piwik Japan OSC Tokyo fall Oct 25, 2015
  • 2. すでに公開しています ■ Piwik Japan ユーザー会 ■ http://www.piwikjapan.org/ ■ osdn https://osdn.jp/projects/piwik-fluentd/ ■ Piwik osdn で検索するとでます。 ■ 細かい設定はすべてこちらに記述しています。 ■ 日本語問題のパッチもここに置いています。 2 of 28
  • 3. ひとつ前のバージョンに対応しています ■ Piwik 2.6.0 - Piwik 2.14.3 ■ 2.14.3 は 2015/8 に公開 ■ 最新といいたかったんだけど 2.15.0 がおととい(2015/10/21) にでてしまいました... 3 of 28
  • 5. なぜ Piwik なのか ■ Urchin がなくなった □ google に買収され、現在は google Analytics になった □ アプリケーションであり google にデータを渡すことなく自前でログ 解析ができた ■ ID を分けて、担当の Web サイト以外の集計は見せないようし たい ■ google にアクセスログ渡したくない ■ Open Source でログが取り込めるのは Piwik だけ □ もちろん他もあるけどどれも開発はだいぶ前に終了、今からみれば 低機能 5 of 28
  • 6. Piwik fluentd で何ができるのか ■ apache のログを Piwik にとりこみます ■ ログは fluentd 形式です □ 標準では対応していません ■ ついでに、日本語文字コード関連の問題の解決 6 of 28
  • 7. 最新版 piwik-fluentd 2.0.2 では ■ Piwik のリアルタイム集計をログから再現できるようになりま した □ トラッキングコード(Javascript)を Web サイトに埋め込むことに より、apache のログでは採取できないサイト来訪者の詳細情報(画 面の解像度など)を Piwik サーバーに送信します。 □ google Analitics のトラッキングコードと同じ役割です。 □ トラッキングコードからのデータは、通常リアルタイム集計され ます。 ■ 従来からトラッキングコードのログから再現できる機能はありま したが、fluentd に対応させていませんでした 7 of 28
  • 8. リアルタイム集計再現でなにがうれしいのか ■ Piwik アップデート時にリアルタイム集計をとめざるをえない □ 良くも悪くも、頻繁にアップデートされます(一か月に一度程度) □ Piwik は MySQL をデータ蓄積につかいます □ アップデート時にデータベースのカラムを追加することがあります ■ 数千万レコードあるテーブルにカラムを追加されることがあります □ つまりアップデート時のリアルタイム集計停止は避けられません。 ■ MySQL 自体が壊れてリアルタイム集計停止 □ 長時間の稼働停止... 各部署から怒られる、まあ直せばいいけど □ でも、壊れている間のデータはどうなるの ■ Piwik サーバーのログさえあれば後からなんとかできるのはうれ しい 8 of 28
  • 9. Piwik ログ取り込みプログラム import logs.py(1) ■ あらゆるログの取り込みを担当 □ piwik/misc/log-analytics/import logs.py ■ ここだけ Python(他は PHP) ■ ログを読み取って、Piwik の API に変換します □ apache (Urchin 形式含む)、nginx、IIS など 9 of 28
  • 10. Piwik ログ取り込みプログラム import logs.py(2) ■ 指定したファイルをとりこむだけ。気が利いた機能の実装はあり ません。 □ 複数のサーバーから apache ログを ftp でとってくるとかそんなの ない。 □ すでに取り込んだファイルはどこかで覚えておかないとならない。 □ 馬鹿でかいログのの途中から取り込む機能はあるが、開始行を指定 しないとなりません。 ■ HTTP POST, GET だけとりこんでくれればいいのだがなぜか フィルタなし。 □ apache のログを取り込む場合です。 □ トラッキングコードのログ取り込み時は piwik.php のログだけを選択 します。 10 of 28
  • 11. 実装することにします ■ ログの管理機能強化 □ 取り込み済ログの識別 → make を使う □ 複数サーバーからのとりこみ → fluentd を使う ■ 便利オプションの追加 □ HTTP ヘッダ別で取り込みを選択できるように □ ある時間範囲だけ取り込むように □ ページビューから除外する拡張子(urchin と実装を同じにできる) □ ページビューに含む拡張子(urchin と実装を同じにできる) □ fluentd 形式(json)ファイルの取り込み ■ バグ? の修正 □ apache ログ取り込み時刻を JST になおす 11 of 28
  • 12. fluentd はほんとよくできてます ■ こんなことが便利です □ 複数サイトからログを集約できる □ 接続断でも、復活後追いかけてくれる □ ファイルの分割機能 12 of 28
  • 13. Web ログサーバーをつくることにしました(1) ■ ディレクトリ構成 /your_own_path/fluentd/ ├ bin (fluentd 対応の import_logs.py、シェルスクリプト) ├ exclude (取り込んではいけない URL パス) ├ log (piwik/console core:archive のログ) └ td-agent (各サイト毎アクセスログディレクトリ) ├ piwik_tracker (Piwik tracker のアクセスログ) ├ site1(Web サイト 1 のアクセスログ) ├ site2(Web サイト 2) ├ site3(Web サイト 2) └ site4(Web サイト 2) 13 of 28
  • 14. Web ログサーバーをつくることにしました(2) ■ site[1..N] に fluentd からのアクセスログを取り込みます。 □ piwik tracker には piwik 自身のからのアクセスログです。 ■ fluentd の設定は osdn を見てください □ osdn の例では、16M バイト毎に分割していますが、変更可能です。 ■ 複数サイトでも fluentd で楽勝です。 ■ 少々停止しても転送してくれます。 14 of 28
  • 15. Web ログサーバーをつくることにしました(3) ■ fluentd からのアクセスログは一定時間毎のバッチで Piwik に取り 込みます。 ■ 取り込み完了しているか否かの判定は make に任せます。 □ 新しいファイルは import logs.py にかけられます。 □ ひとつのファイルを取り込みごとに .archive ファイルを作ります ■ このファイルに import logs.py の実行結果が入ります ■ とりこんだ後に集計プロセスを実行しないとなりません □ import logs.py で取り込んだだけではグラフがでません。 □ バッチの最後に一度だけ、集計プロセスを動かすことにします。 15 of 28
  • 16. ディレクトリ構成をもう少し見てみましょう ■ ディレクトリ構成 /your_own_path/fluentd/ ├ bin (fluentd 対応の import logs.py、シェルスクリプト) ├ exclude (取り込んではいけない URL パス) ├ log (piwik/console core:archive のログ) └ td-agent (各サイト毎アクセスログディレクトリ) ├ piwik_tracker (Piwik tracker のアクセスログ) ├ site1(Web サイト 1 のアクセスログ) ├ site2(Web サイト 2) ├ site3(Web サイト 2) └ site4(Web サイト 2) 16 of 28
  • 17. 全体的な設定 ■ /your own path/fluentd/bin/env.sh export PIWIK_INSTALL_DIR=/var/www/piwik/ export PIWIK_URL=http://piwik.example.com/ export PIWIK_TOKEN_AUTH=cxxxxxxxxxxxxxxxxxxxxc ← トークン export PIWIK_BULK_ARCHIVE=1 ← 最後に一度だけ集計プロセス=1 □ import logs.py から Piwik API を叩くための設定 17 of 28
  • 18. 各サイトの設定(1)∼ 集計除外 URL ■ /your own path/fluentd/exclude/exclude idsite1.txt /robots.txt /favicon.* □ 集計除外したいファイルを指定する □ 数字は siteid です。exclude idsite[siteid].txt 18 of 28
  • 19. 各サイトの設定(2)∼ siteid ■ /your own path/fluentd/td-agent/site1/IDSITE IDSITE=4 □ td-agent の下のディレクトリ名は実は適当でいいです。 □ ただしディレクトリ名に disable を入れると集計から除外します。例: site1 disable □ リアルタイム集計再現のときは IDSITE=0 19 of 28
  • 20. 各サイトの設定(3)∼ 集計済ファイルの退避先 ■ /your own path/fluentd/td-agent/site1/MOVECONDITIONS LEAVEFILES=2000 DESTDIR=done □ 集計済ファイルが 2000 を超えると td-agent/site1/done に入れます ■ DESTDIR はなければ作成します。 ■ ファイルがあまり多いと make でさばきれなくなるのです。 20 of 28
  • 21. 各サイトの設定(4)∼ 時間範囲 ■ /your own path/fluentd/td-agent/site1/IMPORTRANGE IMPORT_START="2015-10-23:0:0:0" IMPORT_END="infinity" □ IMPORT START から IMPORT END までのデータを取り込みます。 ■ 取り込みが終わっていないファイルが対象です。 ■ 時間外のファイルはすべて集計済としますが、取り込みません。 ■ IMPORT START, IMPORT END 両方に infinity を指定できます。 ■ Piwik が停止していた時刻だけ取り入れることを想定。 21 of 28
  • 23. 開発サーバーとの共用で問題発覚 ■ 開発サーバーと共用していて my.cnf で自動変換をお断りしていた [mysql] sql_mode="traditional" ← お断りの呪文 ■ MySQL の自動変換とは 1 数値 範囲外の数値は頭を押さえつけられる 数値 小数は勝手に丸められる(warning も出ない) 数値 数字以外が入っていると分かるところまでを登録してくれる 文字列 長さを超えると勝手にカットされる 文字列 カラムと異なる文字コードは適当に丸められる ■ 呪文で自動変換をやめさせて、エラーとします □ 開発時にはエラーとしないとあとから非常に厄介です 1 http://sakaik.hateblo.jp/entry/20100225/mysqlautochange23 of 28
  • 24. 自動変換なし: 文字化け、自動変換お断り: 落ちる ■ パターン 1: UTF-8 前提としたつくりに抵触する □ サイト検索エンジンキーワードが SJIS または EUC □ 自サイトの検索キーワードが SJIS または EUC □ そもそも Piwik トラッカーからのリクエストが文字化け ■ トラッカーからは title 文字列が UTF-8 で送られてきます ■ パターン 2: マルチバイトを前提としたつくりになっていない □ substr じゃなくて mb substr □ カラムに合わせて文字列を詰める箇所があるのですが、 □ MySQL の VARCHAR(n) の n はマルチバイトも含めた文字数です。 ■ Piwik コミッターがバイト=文字列と思いこんでいる □ マルチバイトの途中で詰められるともちろん文字化け 24 of 28
  • 25. サイト検索エンジンキーワード ■ piwik/core/DataFiles/SearchEngines.php // goo - ’search.goo.ne.jp’ => array(’goo’, ’MT’, ’web.jsp?MT=k’), - ’ocnsearch.goo.ne.jp’ => array(’goo’), + ’search.goo.ne.jp’ => array(’goo’, ’MT’, ’web.jsp?MT=k’, array(’UTF-8’, ’EUC-JP’, ’MS932’)), + ’ocnsearch.goo.ne.jp’ => array(’goo’, ’’, ’’, array(’UTF-8’, ’EUC-JP’, ’MS932’)), 25 of 28
  • 26. Piwik トラッカーからの文字列が文字化け ■ piwik/core/Tracker/PageUrl.php public static function cleanupString($string) { $string = trim($string); - $string = str_replace(array("n", "r", "0"), ’’, $string); - + if (function_exists(’mb_check_encoding’) + && !@mb_check_encoding($string, ’utf-8’, true) + ) { □ mb check encoding の三番目のパラメータが重要 □ It would perform a more thorough check, and the result of that call would be FALSE.2 2 http://stackoverflow.com/questions/17958226/what-does-mbstring-strict- detection-do26 of 28
  • 27. マルチバイトを考慮していない ■ piwik/plugins/Referrers/Columns/Keyword.php $information = $this->getReferrerInformationFromRequest($request); if (!empty($information[’referer_keyword’])) { - return substr($information[’referer_keyword’], 0, 255); + if (function_exists(’mb_substr’)) { + return mb_substr($information[’referer_keyword’], 0, 255, ’UTF-8’ + } else { + return substr($information[’referer_keyword’], 0, 255); + } } return $information[’referer_keyword’]; □ VARCHAR(255) 制限のために入れたみたいだけど... これはひどい... 27 of 28