印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
Linux Webalizer のインクリメンタル設定を使い分ける

Webalizer の設定で指定できる増分設定を使い分けて,ディスクの有効利用と不要なリファラの削除の両立を狙う。

■ ■ ■

Webalizer は Web サーバへのアクセス統計を表示してくれるソフトウェア。月別の詳細な統計と,1年間のアクセス推移を見やすい形で表示してくれる。

動作設定は /etc/webalizer.conf で行う。Incremental ディレクティブを yes に設定しておくと,新しいアクセス分だけを追加していってくれるため,古いアクセスログを消してしまっても統計情報だけは残すことができる。しかし,逆に不要な統計情報が削除できないという欠点もある。例えば,新しい検索ロボットが来るようになったから統計には加えたくないとか,変なリファラを削除したいなどがある。これらの不要なアクセス情報は webalizer.conf の設定で排除することができるが,設定後のアクセスにしか有効にならない。詳細は nlog(n): 不要なリファラを無視したい に書いた通りで,結構悩ましい。

次にあげる若干矛盾する要件を満たすような方法を考えてみたい。

  • ディスクを有効に使いたい
  • 不要なリファラを排除したい
  • 処理時間を短縮したい

Webalizer の「Webalizer は最長1年前までの情報しか集計しない」を加味して考えて,次のように対処することにする。

  • ディスクを有効に使いたい
    → 1年以上前のログは圧縮する
  • 不要なリファラを排除したい
    → 不要なリファラは webalizer.conf に手で追加していく
  • 処理時間を短縮したい
    • 1時間に1回行う処理はなるべく短時間で
      → Incremental yes で最近のアクセスログだけを処理
    • 1日に1回行う処理は時間がかかってもよい
      → Incremental no で1年間分のアクセスログを処理

前提条件としては,Apache のアクセスログを月毎に別ファイルとしてあることである。つまり,先月のログは access_log.200503,現在のログは access_log というファイル名で保存されていることが必要である(nlog(n): Apache のログを月別に保存したい)。

1時間毎の集計は,「Incremental yes」として access_log ファイル1つを対象に行えば短時間で処理が終わる。1日毎の処理については,新しく webalizer-daily.sh というシェルスクリプトを書いた(ファイル名は適当)。

#!/bin/sh

LOGNAME="/var/log/httpd/access_log"
OPTION="-i -c /etc/webalizer.conf"

LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -11 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -10 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -9 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -8 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -7 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -6 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -5 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -4 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -3 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -2 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -1 month" +%Y%m`"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi
LOG="$LOGNAME"
if [ -f $LOG ]; then LOGS="$LOGS $LOG"; fi

cat $LOGS | webalizer $OPTION -

Bourne Shell を使いたかったので,かなりの力技になっている。2005年4月現在では,2004年5月以降が集計対象になるので,対象となるログは access_log.200405, access_log.200406,..., access_log になる。また,ログが1年分ない場合にも対応している。例えば先月と今月だけの場合は,access_log.200503 と access_log の2つが集計対象になる。ファイル名の代わりに「-」を指定し,標準入力を対象の入力としている。起動オプション「-i」は,履歴を無視する指定である(Webalizer README)。ただし,このオプションを有効にするためには,webalizer.conf の中で「Incremental no」を指定しておかなければならない。これにより webalizer.conf の設定が過去の情報にも反映される。実行許可を与えて /etc/cron.daily に入れておけばよい。

ディスクが効率的に使えると言っても,1年間分はプレーンテキストのまま保存されるため,相当な量になる。より効率的に使うには,1か月前以前のログは gzip で圧縮してしまい,上記のスクリプトでは zcat を使うようにすればいいだろう。

1時間に1度更新するための cron 用スクリプトは,デフォルトで用意されている /etc/cron.hourly/00webalizer をそのまま使ってもいいし,上記のスクリプトと同じ様に次のように書いてもよい。「-p」オプションで「Incremental yes」を強制的に指定している。

#!/bin/sh

LOGNAME="/var/log/httpd/access_log"
OPTION="-p -c /etc/webalizer.conf"

LOG="$LOGNAME"
if [ -f $LOG ]; then
  cat $LOG | webalizer $OPTION -
fi

2006年2月14日追記:
前月用のファイル名を取得するために次の書式を使っていましたが,

LOG="$LOGNAME.`date -d '1 month ago' +%Y%m`"

月末に思ったように動作しない場合があることが分かりました(nlog(n): date コマンドのバグ)。この問題はコメントをいただいて解決しました。

LOG="$LOGNAME.`date -d "$(date +%Y-%m-01) -1 month" +%Y%m`"

ダブルクォートが入り乱れていますが,動きます。「%Y-%m-01」の「01」の部分は,「01」以外に「15」などにしても同じように前月の取得ができます。「31」にすると,前月が30日しかない場合に今月になります。

スクリプトの書き換えを行いました。

Posted by n at 2005-04-19 23:40 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?