ただ、 CounterizeII のアクセス解析はデザインが旧態依然ですし、すでに4年以上更新がないため、そろそろアクセス解析プラグインの乗り換えを考えることにしました。いろいろなプラグインがある中で、見た目とテーブルの簡素さから StatPress 系の NewStatPress にすることにしました。
ただ、そのまま使い始めますとアクセスカウンターがまたゼロからのスタートになってしまいます。これ、なんとかしたいなーということで、CounterizeII のアクセスログを NewStatPress へマイグレーション(移行)することにしました。テーブル間でSQL一発のマイグレーションも可能ですが、やはりできるだけ資産(データ)を生かしてマイグレーションしたいなーと。
SQL による CounterizeII から NewStatPress へのマイグレーションですと、純粋に CounterizeII のログデータを NewStatPress テーブルにコピーするだけですね。date, time, ip, urlrequested, agent, referrer, timestamp の生ログが対象になりますかね。
テーブルのフィールドマッピングは以下の通りです。テーブル名の接頭辞($wpdb->prefix)は、省略しています。
SQL ですとこのような感じになりますかね。
INSERT INTO statpress (
date,
time,
ip,
urlrequested,
agent,
reverrer,
timestamp)
SELECT
DATE_FORMAT(a.timestamp, '%Y%m%d') as date,
DATE_FORMAT(a.timestamp, '%H:%i:%s') as time,
a.IP,
b.url,
c.name as agent,
d.name as referrer,
a.timestamp
FROM
Counterize a
LEFT JOIN Counterize_Pages b ON a.pageID = b.pageID
LEFT JOIN Counterize_UserAgents c ON a.agentID = c.agentID
LEFT JOIN Counterize_Referers d ON a.refererID = d.refererID
ORDER BY
id ASC ;
なお、CounterizeII のIPアドレスはデフォルトでは暗号化されています、私は CounterizeII をカスタマイズして暗号化せず生IPをロギングするよう変更していましたのでそのまま移行できますが、暗号化されたハッシュ値のままであれば、あまり使い道がなさそうなので移行不要かもしれませんね。
CounterizeII のログデータに本来 NewStatPress が行うログ解析処理を適用後、statpress テーブルにマイグレーションするという意味になります。具体的には、SQLで取得した date, time, ip, urlrequested, agent, referrer, timestamp の生ログに NewStatPress とほぼ同様のログ解析ロジックを適用し、search, nation, os,browser, searchengine, spider, feed を取得後、statpress テーブルにマイグレーションします。
PHPコード
PHPコードは以下のような感じですかね。ファイル名はさし当たって counterizeii2statpress.php とでもしておきましょうか。なお5行目の require_once() の <WordPress Dir> には WordPress 設置ルートディレクトリをフルパスで指定してください。言わずと知れた外部から WordPress の関数をロードしたい場合のおまじないですね。
#!/usr/bin/php
<?php
//require the WP bootstrap
require_once('<WordPress Dir>/wp-load.php');
// Execute migration
mig_StatAppend();
/**
* CounterizeII to NewStatPress migration
*
*/
function mig_StatAppend() {
global $wpdb;
$table_name = nsp_TABLENAME;
$offset = $wpdb->get_row("SELECT count(*) as count FROM " . $table_name);
$count = $offset->count;
$start = $wpdb->get_row("SELECT id FROM " . counterize_logTable() . " ORDER BY id ASC LIMIT 1 OFFSET " . $count);
$sql =
"SELECT
a.id,
DATE_FORMAT(a.timestamp, '%Y%m%d') as date,
DATE_FORMAT(a.timestamp, '%H:%i:%s') as time,
ip,
url,
c.name as agent,
d.name as referrer,
a.timestamp
FROM
" . counterize_logTable() . " a
LEFT JOIN " . counterize_pageTable() . " b ON a.pageID = b.pageID
LEFT JOIN " . counterize_agentsTable() . " c ON a.agentID = c.agentID
LEFT JOIN " . counterize_refererTable() . " d ON a.refererID = d.refererID
WHERE
id >= " . $start->id . "
ORDER BY
id ASC;";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res)) {
$id = $row['id'];
$vdate = $row['date'];
$vtime = $row['time'];
$ipAddress = $row['ip'];
$urlRequested = $row['url'];
$userAgent = $row['agent'];
$referrer = $row['referrer'];
$timestamp = $row['timestamp'];
$login = null;
$urlRequested = mig_URL($urlRequested);
$urlRequested = esc_sql($urlRequested);
$referrer = esc_sql($referrer);
$referrer = esc_html($referrer);
$userAgent = esc_sql($userAgent);
$userAgent = esc_html($userAgent);
$os = nsp_GetOs($userAgent);
$browser = nsp_GetBrowser($userAgent);
$spider = nsp_GetSpider($userAgent);
$searchengine = '';
$search_phrase = '';
if ($spider != '') {
$os = '';
$browser = '';
} else {
// Trap feeds
$feed = nsp_IsFeed($urlRequested);
// Get OS and browser
$os = nsp_GetOs($userAgent);
$browser = nsp_GetBrowser($userAgent);
$exp_referrer = mig_GetSE($referrer);
if ( isset($exp_referrer) ) {
list($searchengine,$search_phrase) = explode("|",$exp_referrer);
}
}
// Country (ip2nation table) or language
$countrylang = "";
if ( $wpdb->get_var("SHOW TABLES LIKE 'ip2nation'") == 'ip2nation' ) {
$sql2 = 'SELECT *
FROM ip2nation
WHERE ip < INET_ATON("'.$ipAddress.'")
ORDER BY ip DESC
LIMIT 0,1';
$qry = $wpdb->get_row($sql2);
if ( $qry != null ) {
$countrylang = $qry->country;
}
}
$insert =
"INSERT INTO " . $table_name . "(
date,
time,
ip,
urlrequested,
agent,
referrer,
search,
nation,
os,
browser,
searchengine,
spider,
feed,
user,
timestamp
) VALUES (
'$vdate',
'$vtime',
'$ipAddress',
'$urlRequested',
'".addslashes(strip_tags($userAgent))."',
'$referrer','" .
addslashes(strip_tags($search_phrase))."',
'".$countrylang."',
'$os',
'$browser',
'$searchengine',
'$spider',
'$feed',
'$login',
'$timestamp'
)";
$results = mysql_query( $insert );
if ($results < 1) {
print "insert error: line $id\n";
}
if ( ++$count % 1000 == 0 ) {
print "$count\n";
}
}
}
/**
* Processing the url
*
* @param urlRequested the source url
* @return processing the url
*/
function mig_URL($urlRequested = '') {
if(substr($urlRequested,0,2) == '/?') { $urlRequested = substr($urlRequested,2); }
if($urlRequested == '/') { $urlRequested = ''; }
return $urlRequested;
}
/**
* Get the search engines
*
* @param referrer the url to test
* @return the search engine present in the url
*/
function mig_GetSE($referrer = null){
global $newstatpress_dir;
$key = null;
$lines = file($newstatpress_dir.'/def/searchengines.dat');
foreach($lines as $line_num => $se) {
list($nome,$url,$key) = explode("|",$se);
if(strpos($referrer,$url) === FALSE) continue;
# find if
$variables = nsp_GetQueryPairs(html_entity_decode($referrer));
$i = count($variables);
while($i--){
$tab = explode("=",$variables[$i]);
if($tab[0] == $key && count($tab) >= 2){return ($nome."|".urldecode($tab[1]));}
}
}
return null;
}
?>
マイグレーションの実行
今回は、ダウンタイムを出来る限り最小限に収めるという観点からマイグレーションを考えてみます。そのため多少手順が煩雑になるかもしれません。
NewStatPress プラグインのインストール
NewStatPress を稼働させたままマイグレーションしますとアクセスがあった場合、ログが新旧で混ざってしまいます。まず事前準備として、
WP Maintenance Mode プラグインなどでサイトをメンテナンスモードにして閉塞します。
閉塞後 NewStatPress プラグインをインストールします。有効化したらダッシュボードの NewStatPress メニューの Tools > Database Tools から ip2nation もインストールしておきます。
ロギングの停止
次にロギングの停止ですが、NewStatPress メニューの Options > Filters > Parameters to ignore > IP addresses 欄に以下のようにCIDRで記載しますとロギングが停止します。本来ならIPアドレスを ANY で拒否すればよいので、 0.0.0.0/0 でよいはずなのですが、どうもサブネットマスクを /0 にするとempty($mask) 判定でひっかかり強制的 32 に変更されてしまい、正常に全IPアドレスのアクセス拒否ができません。そのためサブネットマスクを 1 にしアドレスを2つに分けました。
[cc]
0.0.0.0/1,128.0.0.0/1
[/cc]
上記を追加すればロギングは停止しますので、メンテナンスモードを解除しサイトを開放します。なおログが新旧混ざってもよいのであればこの手順は不要です。
解析定義データの追加
次に昨日 2015/09/19 リリースの NewStatPress v1.0.8 は、解析定義データがやや不足している箇所がありますので、プラグインフォルダ配下の def ディレクトリの dat ファイルに、以下の定義を追加しておくとログ解析の精度が上がるかと思います。
ただし追加する際は、次の点にご注意ください。dat ファイルは上から順にマッチ検索しますので、数字が大きいほうを先に記述してください。FireFox40 と FireFox4 の場合は、FireFox40 を先に(上に)記述してください。例えばブラウザのバージョンが FireFox40 であった場合、FireFox4 が先に記述されていると FireFox4 にヒットしてしまい、バージョンは 40 であるのにも関わらず、4と判定されてしまいます。またブラウザのバージョンなどは未来のバージョンを記述しておいても特に問題ありません。
また spider.dat は、定義に該当しないアクセスは、すべて Visitor と判定され bot にも関わらず、アクセス数扱いにされてしまいますのでご注意ください。このファイルは、適宜メンテしないと正しいアクセス数が得られないのではないかと思います。ここは少々面倒ですね。
参考までに、今回追加した定義ファイルを以下に置いておきます。
- browser.dat
Chrome 46|Chrome/46|
Chrome 47|Chrome/47|
Chrome 48|Chrome/48|
Chrome 49|Chrome/49|
Chrome 50|Chrome/50|
Chrome 5|Chrome/5|
Firefox 50|Firefox/50|
Firefox 51|Firefox/51|
Firefox 52|Firefox/52|
Firefox 53|Firefox/53|
Firefox 54|Firefox/54|
Firefox 55|Firefox/55|
Firefox 56|Firefox/56|
Firefox 57|Firefox/57|
Firefox 58|Firefox/58|
Firefox 59|Firefox/59|
Firefox 60|Firefox/60|
Firefox 4|Firefox/4|
Firefox 5|Firefox/5|
Firefox 6|Firefox/6|
Microsoft Edge|Edge/12|
Microsoft Edge|Edge/13|
Microsoft Edge|Edge/14|
Microsoft Edge|Edge/15|
- os.dat
Windows 10|WindowsNT10.0|
- searchengine.dat
Yahoo は search.yahoo.com になっていますので、必ず search.yahoo. に変更してください。
Yahoo|search.yahoo.|p|
Bing|www.bing.com|q|
ezweb|ezsch.ezweb.ne.jp|query|
docomo|search.smt.docomo.ne.jp|MT|
au|sp-search.auone.jp|q|
Rakuten|websearch.rakuten.co.jp|qt|
OCN|wsearch.ocn.ne.jp|MT|
J:COM|search.myjcom.jp|q|
So-net|www.so-net.ne.jp|query|
JWord|search.jword.jp|name|
Sleipnir|search.fenrir-inc.com|q|
Lunascape|s.luna.tv|q|
FMWORLD|search.azby.fmworld.net|q|
MyVAIO|search.start.sony.jp|MT|
- spider.dat
360Spider|360Spider|
Linkdex|linkdexbot|
SimilarTech|SMTBot|
コンソール実行
コンソールから couterizeii2statpress.php を実行します。処理が把握できるように 1000 件処理毎に件数を出力するようにしてあります。
また Web からでも実行は可能ですが、WordPress ディレクトリ配下ではなく外部の php ファイルが動作するディレクトリに配置する必要があります。HTML 表示になりますので改行の<br>を適宜入れておくとよいと思います。ただ Web からですとログ量にもよりますが、おそらくHTTP コネクションのタイムアウトになってしまう気がします。
[cc lang=”bash” theme=”blackboard”]
$ php couterrizeii2statpress.php
1000
2000
3000
….
[/cc]
27万件程度でも問題なく処理が終了しました。ただ私のサーバは実行中プロセスが60分経過すると強制的に kill (中断)される仕様になっているようで、17万件あたりで停止してしまい再実行を余儀なくされました。
再実行の処理は中断した場所から再開し継続するよう処理を組んでいます。途中から再開し継続するカラクリは以下のコードですね。
まず statpress テーブルに登録され件数を取得します。Counterize テーブルからこの件数に該当する位置の行を OFFSET 句で取得し、その行の id を取得します。この id が継続開始位置ですね。本当は副問い合わせを使って SQL 一発で id を取得したかったのですが、MySQL は LIMIT/OFFSET 句の副問い合わせはエラーになり、結局それぞれでSQLを投げて取得する方法になりました。イマイチ。PostgreSQL なら可能だと思いますね。
$offset = $wpdb->get_row("SELECT count(*) as count FROM " . $table_name);
$count = $offset->count;
$start = $wpdb->get_row("SELECT id FROM " . counterize_logTable() . " ORDER BY id ASC LIMIT 1 OFFSET " . $count);
WHERE
id >= " . $start->id . "
また、再度最初から行う場合は、statpress テーブルの初期化(全件削除 & AUTO_INCREMENT=1)を行っておく必要があるかと思います。
[cc lang=”sql” theme=”blackboard”]
mysql> TRUNCATE statpress;
[/cc]
差分の同期
最後にもう一度サイトをメンテナンスモードにしてサイト閉塞します。コンソールから couterizeii2statpress.php を再実行します。これは先ほどのコンソール実行以後にアクセスされたログの差分を同期するためです。今度は直ちに終了するかと思います。
終了したら、ロギングを再開するため先ほど NewStatPress メニューの Options > Filters > Parameters to ignore > IP addresses 欄の「0.0.0.0/1,128.0.0.0/1」を消去し保存します。最後にメンテナンスモードを解除し、マイグレーションは完了です。
最後に
NewStatPress 高機能?と言われているようですが、私が欲しいと思う集計がないというか集計が基本的なものしかありませんね。例えば 不正アクセスがないかなどの Visitor 別日(週)集計や、ランキング確認の記事別月(週)集計などがありません。またカウンタ用の前日ページビュー数などもありません。この辺はカスタマイズしていかないと無理っぽいですね。
ただCounterizeII ではスパイダー数が全く解らなかったのですが、NewStatPress にしてページビューより多くこんなに多いのかと少々驚きでした。 bot アクセスが多過ぎですね。
また定義ファイルですが、現在はブラウザ名とアイコンファイルを同一名で共有していますが、ここは分けたほうがよいのではないかと思いますね。定義ファイルに追加する度にアイコンファイルを追加しなければなりませんので、これではファイル名が違うだけの同一画像ファイルが増え過ぎてしまいます。
[cc]
ブラウザ名兼アイコンファイル名|ユーザーエージェント|
Firefox 40|Firefox/40|
↓
ブラウザ名|ユーザーエージェント|アイコンファイル名|
Firefox 40|Firefox/40|firefox|
[/cc]
また普段は PHP 使いではないため、今回 MySQL の大量データを PHP で扱う場合、どのようにすればよいか少々戸惑いました。これはまた別記事にしたいと思います。
ラグビーW杯 南アフリカ v 日本、深夜世紀のジャイアントキリングに感涙。リアルタイムで観れたことに感謝(レスター岡崎に感謝(汗))。
これほど魂が震えたのは久しぶりです。個人的にはジョホールバルかWBC決勝か五輪女子ソフトか南アW杯デンマーク戦(現地)か、でも世界的には今日の勝利はそれ以上のインパクトです。RWC史上最大の衝撃ですから。どこに魂が震えたかというと試合展開も劇的でしたが、あの日本代表のメンタルの強さですね。TV画面からその気迫がひしひしと伝わってきました。そのメンタルに触れた観客もJAPANコールに。最後エンジンを組み、勝ちにこだわる選択にも感動しました。
やはり日本人は泥臭く粘り強くコツコツひたむきにやらないと世界では勝てないということですね。スモールベースボールにしろ、練習は嘘をつかない、まさしくそれでした。以前、エディー・ジョーンズ HCについて触れましたが、あの時の練習量も半端なかったですしね。
先日、プロフェッショナル・仕事の流儀というエディー・ジョーンズ ラグビー日本代表監督のNHK番組がありました。エディー監督いわく以下の点について説いてました。
- 強みを知り、強みを伸ばす
日本人の強み。それは、どんな過酷な練習にも耐え、向上心を持ち続ける”勤勉(タフ)さ”。真面目で忍耐力があること。それは間違いなく世界一です。他の国の選手なら、とっくに逃げ出しているでしょう。
(AM6~PM7までの過酷な練習って高校野球じゃないんだから。でも映像からは相当な過酷さが垣間見えました。)
- ハッピーにしない
選手を成長させるために必要なのは、選手を正しく理解し、それに合った方法で“少しの不安”や“緊張感”を与えること。居心地がいいと能力は発揮できないからです。ときには少し突き放すことで、選手が100%安心しないようにしています。
- どんどんミスさせる
日本の練習で一番間違っているのはミスをしないように練習すること。ノーミス、ノーミスと言うが、ミスするから上達する。失敗から学ぶということが重要。
- 責任感を持たせる
各ポジションのリーダー(サブリーダー)が責任感を持つ必要がある。責任とは各ポジションのメンバーによいパフォーマンスをさせること。
- 感情の波を小さく
指導者として、誰にでも感情に起伏があることを理解した上で、そうした波を最小限にとどめさせることが大切。
引用元:SKYBLUES.ORG
アジアカップ2015 日本代表QF敗退 と アギーレ監督解任
南アフリカは白人:黒人の比率が1:8なんですよね(南アというといつもこの比率で見てしまう(汗))。5年前にサッカーW杯で現地に行きましたが、当時でもいまだ格差は凄まじいものがありました。南アにしてもオージーにしてもイギリス連邦加盟国ですからイギリスの影響を色濃く受けてます。同組にスコットランドがいるとはいえイギリス国内中、ジャイキリした日本をリスペクトしていて、その喜びようといったら日本人以上です。スポーツの力って凄いですね!ラグビー日本代表に「勇気」を貰いました。
最近涙腺が弱いのか(汗)、先ほど録画での再放送でもまた涙してしまいました。
この記事、なかなか今の私の心のモヤモヤを言い当てていて、リツイートならぬ、リブログ!?
ドルトムントでの香川は、トゥヘル新監督からかなりの部分で「任せられている」。4-2-3-1から4-3-3へとシステムが流動的に変化する中で、「自分で判断して中盤か前かを決めろ」というのが大筋の指示だという。つまりインサイドハーフ的に前線の3枚を生かすこともあれば、1列前でプレーすることもある。それは相手の守備の陣形や時間帯によって変化する。これにより、4-2-3-1のトップ下に固定され、セカンドトップとして高い位置でプレーし、得点に直接絡むことを求められていた時期のフラストレーションはなくなった。
引用元:webスポルティーバ
ドルトムントで絶好調の香川真司が、日本代表で輝けない理由
そうなんですよね。昨期と今期の香川をヒートマップやポジションニングマップなどで比較すれば一目了然ですよね。今期のドルトでの香川は、ある時にはギュントアンやヴァイグルより後ろの最終ラインまで下がってみたり、かと思えば、オーバメヤンと同等の位置まで上がって行くなど、かなりの自由度を与えられているように思います。4-1-4-1や4-2-1-3ってことも。これは香川に限らずで、攻撃陣はかなり流動的にポジションチェンジしてますよね。流石はトゥヘル。
フォーメションなどその時々で機能すればよいのですから、香川においてはあまりポジショニング云々を言わないほうが結果が伴う気がしてます。(とかく型にはめたがるハリルには逆行してますけどね(笑))むしろボランチやインサイドハーフと言っておいたほうが肩の力が抜けていい動きをしそうな気がしてます。現に今年はかなり引き気味なポジショニングも目立ちます。この人はメンタル的にはまだまだWeakな部分があるのですが、ここはなかなか技術と同じようには習得できない。QBKなんか言わせておけばいい。次も決めて黙らせればいいんです。
香川いわく、「楽しい」という感覚が彼にって一番なのですから。
2018ロシアW杯は本田ではなく香川のW杯だと確信しています。出られたらね(汗)
最近はほとんど国内代表戦はスルーしていたのですが、ブラジルW杯のレシフェの宿でたまたまご一緒した方が大阪からわざわざ代表チケ持参でお誘いを受けたので、ウン年ぶりの埼玉スタジアム2002まで行ってきました。サッカーなら先月J3リーグを観戦してますが、代表戦の現地観戦となると昨年アウェイの日本vブラジル@シンガポール以来。
浦和美園駅を出たあたりからポツポツと小雨が。南門で1年3カ月ぶりの再会。お互い久々の再会に乾杯。ゴール裏も久しぶり。やっぱり埼スタは観やすいですね!
試合はというとW杯(予選)は「結果がすべて」、まあ言うことはあまりないのですが、今日はゴールエリアサイド深い位置からのマイナスのクロスが確実に増えてましたが、最近、コパや欧州リーグばかり見ていたせいか、パススピードが遅過ぎで、ダイレクトプレーが少な過ぎで止まっているように見えてしまうのは私だけでしょうか。パス回しがチンタラに見えてしまうんですよね!ワンツーやドリブル、裏を取る動きをもっと増やしてほしいですね。宇佐美が唯一停滞ムードな流れを変えた感じがしました。あと長友へのパスはいつも雑(笑)。これでハリル監督も”ホッ”でしょうね!
ということで、帰りは安定の浦和美園駅渋滞。レシフェのアレーナ・ペルナンブーコの帰路も本当に壮絶でしたが、こちらは全く人が流れない。
改札少ないんじゃないのかと思いましたが、入場制限をしているからなんですかね。改札を抜けたらかなり空いてました。もちろん電車は満員でしたが、次駅の東川口で1/3は下車していき、帰路の電車はやはりレシフェのほうが醜かった。そういえばあの時も雨でしたね。
例え日本代表がロシアに行けなくとも、ロシアで再会する約束をし、本当は祝杯をあげたかったのですが、帰れなくなるのでおとなしく解散となりました。
そう言えばスタジアムを出る所のオフィシャルショップで代表ユニが50%オフになってました。そろそろ脱皮ですかね!?結束の一本線よりはマシでしたが、勝敗ではブラジルW杯が惨敗だっただけにあまりよいイメージがない現代表ユニ。ピンクは止めて赤にしてェ~。イタリアやフランスのようにもっとシンプルなユニがいいですね。いつも奇をてらい過ぎです。今話題のエンブレム問題ではないですが、誰がデザインしているんですかね?この際公募にしてみたらどうでしょう!
そっかー、大阪からのサポ仲間は今日の「大阪880万人訓練」は受け取れないのかぁ~(独り言)