結論:PHPのapache_note関数とhttpd.confの設定の小細工を組み合わせれば、Apacheのログになんでも出せる。
(たしかperlでもmod_perl使うと似たような仕組みがあったはず)
ログは重要だ。日々の動作の統計の基礎データだし、トラブったときの手がかりでもある。
しかしログは面倒だ。ログを記録するということはログを管理するということだから。
ログファイルが無駄に肥大化しない程度に適度に選んだ情報を出さなければならないし、
それでも肥大化したら圧縮するなり移動するなり削除するなりしなければならないし、そのタイミングも考えなければならない。
情報セキュリティを気にする必要が大きい場合は、
暗号化保存なんて面倒なことも考えなければならないこともある。
ところで、Webシステムではたいていの場合はほっといてもいろんなソフトがログを吐く。
apacheのログ、tomcatのログ、postfixのログ、etcetc。
もしもこれらのログが通常出力する内容では都合が悪い、不足だ、という場合には、
オリジナルなログ出力システムを構築して、出力されたログを別途管理しなければならない。
それは面倒だと言う場合には、今すでに出力されていて管理もされているログに相乗りすればいい。
というアイデアはいかがだろう。
前置きが長くなった。
たとえばindex.phpというPHPスクリプトに
<?php
$val = "hogehoge";
apache_note("originallog", $val);
?>
と書いて、apacheのhttpd.confのログフォーマット設定で
LogFormat "%h %l %u %t \"%r\" %>s %b %{originallog}n" common
のようにしておくと、index.phpにアクセスしたときにapacheログには次のように出力される
192.168.212.51 - - [20/Jul/2005:21:39:03 +0900] "GET /index.php HTTP/1.1" 200 735 hogehoge
この方法は、たとえば会員番号とパスワードで認証してクッキーでセッション管理しているという、
よくあるタイプの会員制のWebサイトを運用している場合に便利だ。
apacheのログに会員番号を記録させるようにすれば、会員ごとの動作履歴を追跡(トラッキング)できる。
利用動向の調査やユーザーからの問い合わせ対応の際に重宝するんじゃないだろうか。
ちなみにこれを実現しようとしてLogformatに %{Cookie}i と書いておいて、Cookieに会員番号を書き込んでおくと言う手法を取るサイトもあるようだが、セキュリティ上大変よろしくない。ブラウザ側に保存されているCookieはその気になれば簡単に書きかえることができてしまう。そんな信頼できないものをログにとっても意味ない。
なお、analogなどのWebサーバーログ解析ソフトでは、HTTPベーシック認証されているユーザーのユーザー名が記録されているログ=apacheでいうと %u =を解析することができる。
この%uにあたる部分に、そのサイト独自の認証で使っている会員番号などを上記の方法で埋め込んだログを吐かせれば、ログ解析ソフトのこうした機能をそのまま活用できるだろう。
通常では記録されない、POSTされたデータ自体をログに記録したいという場合も
apache_note("originallog", var_export($_POST, true));
のような感じでできるんじゃないだろうか。ただし改行コードがあったらどうなるとかPOSTデータがでかかったらとかバイナリだったらどうなるとかは知らないので各自テストされたし。(なお、POSTデータの監視についてはmod_security導入という手もある)
apacheは複数のモジュールで構成されている。デフォルトで含まれるmod_log_configもそのひとつだ。
apacheにはモジュール間で情報をやりとりするためのnoteという共通記憶領域の概念がある。
mod_php4がnoteに書き込み、mod_log_configがnoteを読み込んでログを吐く、というカラクリである。
ということで、いろんな情報をapacheのログに吐かせることで、既存のapacheログの価値を向上させつつログ管理の手間を省くTIPSでした。
そういえば最近ログがらみの話が多い気がするが別にたまたまです。
see also:
apacheのログに出る時刻はバージョン1.3.xと2.xとで違う(2006/7)