前回の記事 でアクセスログの保存方法について検討しました。そして「テキストファイルを使ってみよう」という、一応の結論が出ました。

その結論が出るまでのプロセスは省くとして、、以下のような流れで考えれば良いのではないか?と思っています。

(1)アクセスログをテキストファイルに追加する

WEBページにアクセスがある度にユーザの情報をテキストファイルに保存します。
保存は、(日付).log にします。

なぜ日付にしているのかというと、AWstatsというアクセス解析がそうしていたから真似たというのが本音ですが、すべてのログを同じファイルに書き込むよりも、日で分けた方が読み込み時のファイルを開く時に、重くならないだろうという思惑もあります。

(2)日付が変わった時、保存したテキストファイルを圧縮する

ただログを保存していくと、テキストファイルの容量が肥大化してしまいます。私の実験では、10万行(10万PV)で14MBになりました。たった1日のファイルでこれならアクセスの多いサイトでは、すぐにサーバの容量を食いつぶす事になります。

そう思って調べたところ、AWstatsのログファイルの拡張子が「gz」になっている事に気づきました。
gzは圧縮しているからだと言う事は分かったのですが、PHPで圧縮出来るのだろうか?そう思って検索したら、どうやら出来るみたいです。

http://php.plus-server.net/ref.zlib.html

こんな便利な関数があったんですね。
このZlib関数を使う事で、10万行14MBのファイルが65KBまでなりました。

Zlib関数には圧縮したファイルを読み込んで出力する機能もあるので、特に解凍する必要は無さそうです。
ですので、日付が変わった時に昨日に値するファイルを圧縮したいと思います。

(3)集計用のファイルを作成する

データベースを使っていると、
「SELECT * FROM acclog WHERE date='2008-11-27'」
などのSQL文で、簡単に検索条件に合ったデータを抽出させる事が出来ます。

しかし、テキストファイルの場合は全て読み込んで1行毎に検査していくしかありません。

ただでさえ何万行何MBとなるファイルを読み込むのに負荷がかかるのに、解析結果のページにアクセスする度に読み込んでいては負荷がかかりすぎる。表示に時間もかかるし良くない。

っと思ったのが、テキストファイルで保存しない一番の理由でした。

しかし、「毎回アクセスするのではなく、予め結果が集計されたデータにアクセスすれば良い」という事実に気づきました。

つまり、

20081127175200 127.0.0.1 index.php
20081128175210 127.0.0.1 test.php

と記録されているログがあるなら、これをまとめて集計して

[月の集計]
11 2

[日の集計]
27 1
28 1

と言うように別ファイルでまとめれば良いと言う事です。

これなら解析ページにアクセスしても負荷はかからず、一瞬で集計後の内容が表示されるでしょう。
検索する場合でも集計結果のファイルに対して一致する文字列を読み込めばいいわけですから、そんなに時間がかかりません。

ただ、複雑な検索は難しいでしょうね。
例えば「2008年10月~2008年11月、index.phpにアクセスし、Firefoxでアクセスした人」
とかの条件は難しいように感じます。ここまでやりたいのなら、データベースを使うべきでしょうね。


と言うわけで、テキストファイルの保存でも一長一短ありますが、主に閲覧を目的とするならこの流れで良いと思います。Amebaも閲覧だけですしね。