このエントリーをはてなブックマークに追加
スポンサーリンク

urldec

urldecとは

urldecは、apacheのログ解析ソフト「analog」の補助ソフトです。

apacheのアクセスログを、combinedにするとログにrefererが記録されます。これは、検索エンジンからリンクしてきた訪問者が、どのような検索単語を用いてサーバーにアクセスしたのかを判別するのに大変役に立ちます。しかし、訪問者が日本語で検索した際に、検索文字はURLエンコードされて記録され、そのままではanalogの検索単語の集計にエンコードされた文字(%xx%xx%xx%xx)が記録されてしまいます。

そこで、アクセスログからURLエンコードされた部分をデコードするソフトを作成しました。
 特徴
・Cで作ってあるため高速。
・1行は4096バイトでカット。ウィルスからのアクセス記録があっても重くならない。
・二重エンコード対応。二重エンコードされた文字列は二重デコード。
・Googleのキャッシュからのアクセスに含まれる特有文字列を、検索キーワードから削除。

作成方法

まず、下記リンクをクリックして、ソース一式をダウンロードします。
urldec-1.02.tar.gzをダウンロード
これを、適当なコンパイル用のディレクトリにアップします。

tar xvzf urldec-1.02.tar.gz
cd urldec-1.02
make
sudo make install

コンパイルが通れば、実行ファイルが/usr/local/binにコピーされます。外部ライブラリは使ってないので、configureスクリプトは入ってません。お使いの環境でコンパイルが通らない場合は、Makefileを書き換えてみてください。

このサイトで使っているサーバー(CentOS4.7)では正常にコンパイルする事ができましたが、全てのLinuxでコンパイルできるとは限りません。Linuxのディストリビューションによってはエラーが出てしまう事も考えられますが、その際は申し訳ありませんが、エラーの内容をチェックしてソースやMakefileの修正をお願いします。

使い方

ソースが正しくコンパイルされていれば、実行ファイルurldecというファイルが作られていると思います。このファイルを実行します。
書式
urldec [オプション] [--help]
オプション
-i 入力ファイル
入力ファイルを指定します。指定しないと標準入力になります。

-o 出力ファイル
出力ファイルを指定します。指定しないと標準出力になります。

-c0
Googleのキャッシュからのアクセス記録の、cache:xxxx:URL 文字列を消去します。(デフォルト)

-c1
Googleのキャッシュからのアクセス記録であっても、そのまま残します。

-c2
Googleのキャッシュからのアクセス記録は削除します。

--help 簡単な説明を出します。この指定は最優先されます。

使用例

urldec < /usr/local/apache/logs/access_log
標準入力のリダイレクトを使って、apacheのアクセスログを読み込み、結果を標準出力へ出力します。telnetで手作業で入力するなら、こちらのやり方がてっとり早いです。
urldec < /usr/local/apache/logs/access_log > access_log2
結果が標準入力からリダイレクトされて、access_log2というファイルに入ります。
urldec -i /usr/local/apache/logs/access_log -o access_log2
標準入力、標準出力のリダイレクトは使わずに、-iオプションと-oオプションを使って入力ファイルと出力ファイルを指定します。crontabに登録する時や、その他、シェルスクリプト中に実行する時などは、このように書いておいたほうが、見た目スマートになります。

ご注意

-oや>で指定した出力先は、書込み禁止属性がついていない限り、上書きされます。ファイルがない場合は削除されます。大事なファイルは書き込み禁止にしておいてください。という事で、あまりルート権限で動作させない方がいいと思います。

詳しい説明

このプログラムは内部で以下のような作業を行っています。

URLデコード

検索エンジンからアクセスしてきた記録のリファラはURLエンコードされているため、これを2バイト文字にデコードします。

具体的には、
・+をスペースに変換します。
・%HH 形式をバイナリコード(H)に変換します。
・&uHHHH 形式(UTF-16)のユニコードを、バイナリ(HH)に変換します。
・%EH%HH%HH形式(UTF-8)で表された3バイトのコードを、2バイトのユニコード(HH)に変換します。

コードの統一

出力される日本語文字は、EUCコードに統一されます。

・ユニコード
ユニコードは内部でいったんシフトJISコードに変換された後、 EUCコードになります。 MSNサーチで半角カナで検索すると半角カナのユニコードにエンコードされますが、これらは全角に変換しています。 そうしないと、ANALOGで集計した際に同じワードで検索しているのに半角と全角が別物として集計されてしまうためです。 また、訪問者が日本語以外で検索した時など、シフトJISコードに変換できなかった場合は、そのままのコードでデコードされます。 したがって、日本語以外のマルチバイト言語の方がアクセスした場合は、残念ながら文字化けしてしまうと思います。これは今後の課題という事で。

・シフトJIS
シフトJISコードはEUCコードに変換されます。

・JIS(ISO-2022-JP)
JISコードは、内部でシフトJIS→EUCコードに変換されます。

残念ながら現バージョンでは出力結果はEUCコードに限定されています。 シフトJISコードで出力したい場合は、 | nkf -s という風にnkfをパイプさせれば可能ですが、 その分処理が重くなってしまい、「Cで作ってあるので高速」というこのソフトの売りの1つは失われてしまうでしょう。これは今後の課題ということで。

キャッシュから来たログの再デコード

GoogleやYahooのキャッシュページから来た記録や、Googleのイメージ検索の結果画面からアクセスされた場合は、URLが二重にエンコードされています。そのため、それらのアクセス記録は自動的に、内部で二重デコードするようになっています。

キャッシュからのアクセスの対策
Googleのキャッシュからのアクセスされた場合、ログに、
q=cache:xxxxxx(結果ID):(元ページのURL)+検索単語
という文字列が記録されます。このせいでanalogはq=以降の文字を検索単語として認識してしまい、検索単語のリストにcache:xxxxx:URL という文字列がまじってしまい大変目障りです。

そこで、cache:xxxxxx:URL という文字列は削除します。しかし、ログ管理ソフトによっては、キャッシュからのアクセスをきちんと分けて集計してくれるものがあります。また、analogのバージョンアップでGoogleのキャッシュからのアクセスをきちんと分けてくれるかもしれません。そこで、-c1オプションをつけることによって、cache:xxxx:URL文字列を残す事もできます。

また、-c2オプションをつけることで、キャッシュからのアクセスの行自体を出力させない事もできます。

制限事項

・1行の長さの制約
行バッファを4Kバイト分しかとっていないため、1行で4Kバイト以上になるアクセスログは、4096バイト目でカットされます。その4096バイト目に2バイトコードがあった場合は文字化けを起こす可能性があります・・・・・が、通常1回のアクセスログは、せいぜいい100バイト前後であって、そんな数キロバイトも使わないです。

それに、時折ウィルスからのアクセスで、search \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90…のような文字列が延々32キロバイト続くものが記録されたりしますが、このような場合にいちいち必要な分だけメモリを確保してデコード処理をしていたのでは、動作が非常に遅くなってしまうだけなので、適当な長さでカットする方が良いと思います。

Perl言語で作ったデコードソフトは、1行の長さをあまり気にせずに変数($_)に格納して、デコード処理を行うものが多く、そのためPerl言語でデコードソフトを作るとどうしても処理が重くなってしまいます。

このurldecを、analog以外の目的(例えば、単純にユニコードがURLエンコードされたテキストファイルをデコードするためなど)で使う時は、1行の長さの制約がある事を覚えておいてください。

・2重デコードの弊害
文字列中に、「imgurl=」か「cache」があると二重エンコードと判断して、二重デコードをかけます。なので、検索文字列にたまたまcacheという文字を入れると二重デコードされてしまいます。

それでも大抵は問題ないのですが、もし偶然にcache%100のような、いかにもキャッシュから来っぽい文字列で検索してヒットした場合はキャッシュからのアクセスと判断して二重デコードしたり、該当文字を削除したりします。

しかし、もし仮にそんな行があったとしても「検索単語レポート」にはさして影響しないと思われます。

前バージョンとの違い

バージョン1.01から、Yahooモバイルのキャッシュから来たログは二重にデコードするようになりました。

Yahooモバイルのキャッシュから来ると、検索単語が二重にエンコードされて来るのですが、Googleのようなキャッシュから来た事を明確に示す文字がないので、Yahooモバイルでよく使われる引数"_jig_"という文字があれば二重デコードします。

なので、もし偶然「_jig_=いちご%100」みたいな文字列があると%10をデコードしてしまいます。といっても、確率的にYahooモバイルから来た検索語が全部URLエンコードされたままよりはマシなので、_jig_という文字がると二重デコードします。

analog以外での使い方

一応analog用の補助ツールとして公開していますが、パスの通ったディレクトリに実行ファイル(urldec)を入れておけば普通にコマンドとしても使えます。

例えば、
cat /var/log/apache/acces_log | urldec
という風にすれば、アクセスログをデコードされた状態で見る事ができるので、analog解析にかけずとも目視でどんなキーワードで検索して来てるのか確認する事ができます。

それとか、<form action="mailto" …>で送信されたメールを確認するとか、ルパン三世メーカーのURL引数を解析するとか、そういった普通にデコードしたい場合にも使えます。

今のところどこのディストリビューションにも入ってないrpmにもなってない野良ソフトですが、いつか標準コマンドで/usr/binあたりに標準で入れてもらえないかなーと企んでたりもします。まあ、ヘルプが日本語で出る時点で無理かもしれませんが・・・。
スポンサーリンク