Virtual Hostごとに取ったlogrotateの日付単位のログをanalogで解析する

さてlogroateができたので実は今週からlabs.とtrac.は自宅サーバに向けてます。まだアクセスはまばらですがanalogを使ってログの解析を実施したいと思います。

analog自体は先日のlogrotateの際に

# sudo port install analog

にてインストールしていましたが、何一つ設定をしていませんでした。

analogはXREAでも使われていますが、apacheのlogファイルを解析してレポートをhtmlで生成してくれるツールです。読み込むlogファイルはファイル単体でもできますし、*を使って複数ファイルをまたいで解析することも可能です。

どのlogファイルを読み込むのか、どこにreportファイルを生成するのかどのレポートを作成するのかというのはすべて設定ファイルに記述することができます。デフォルトではこの設定ファイルは/etc/analog.cfgになるそうです。

# analog

を実行すると/etc/analog.cfgに基づいてレポートが出力されます。

リアルタイムでレポートを出力したい場合はcronで10分おきとかににanalogを実行すれば良さそうです。

しかし一つの設定ファイルで複数のレポートを作成することはできません。virtual hostを複数作成し、virtual hostごとにlogファイルを出力している場合は当然レポートもvirtual hostごとに作成したくなると思います。

この場合、

analog -G +ghoge.cfg

と書くことで設定ファイル(ここではhoge.cfg)を指定して動作させることができます。

(-Gはデフォルト設定ファイルの無視、+gは設定ファイル指定のパラメータ)
というわけでvirtual hostごとcfgファイルを用意すれば実現できそうです。今回は日ごとに作成している日単位のlogに対するレポートと、すべてのlogのレポートを作成するような設定を構築してみます。

現在自宅サーバではapacheのlogファイルが

sub1.domain-access.log
sub1.domain-error.log
sub2.domain-access.log
sub2.domain-error.log
...
subN.domain-access.log
subN.domain-error.log

というようにvirtual hostごとに出力させています。

これらのlogは一日の終わりにlogrotateがcronで実行され

sub1.domain-access.log -> sub1.domain-access.log.1

というようにファイルがrenameされ一日分のlogファイルになります。

さらにlogrotate内のスクリプトで日付ごとにファイル名をつけているので

sub1.domain-access.log.1 -> sub1.domain-access.log.YYYYMMDD

というように再度renameが行われます。

logファイル名に日付がついてしまうとanalogのconfigファイルでの入力logファイルの指定が面倒になるので

sub1.domain-access.log.1

に狙いを絞ってレポートをはかせます。

このためlogroate内のスクリプトで

sub1.domain-access.log.1 -> sub1.domain-access.log.YYYYMMDD

のrenameが実行される直前にanalogを実行させます。

logrotateの設定ファイルは以下のようになりました。

/opt/local/apache2/logs/*.domain-*log {
daily
rotate 4
size 0
create
noolddir
ifempty
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /opt/local/apache2/logs/httpd.pid 2>/dev/null` 2> /dev/null || true
#    EXT=`date +%Y%m%d`
EXT=`/opt/local/bin/php /opt/local/etc/logrotate.d/yesterday`
for f in $1;
do
if test -f $f.cfg; then
/opt/local/bin/analog -G +g$f.cfg;
mv $f.html $f.$EXT.html;
mv $f.$EXT.html /opt/local/apache2/logs/reports;
fi
mv $f.1 $f.$EXT;
mv $f.$EXT /opt/local/apache2/logs/logs;
done
endscript
}

porstroate – endscript内で
sub1.domain-access_log.cfgファイルが存在すれば

analog -G +g sub1.domain-access_log.cfg

が実行されるようになっています。

さらに実行後に

sub1.domain-access_log.html -> sub1.domain-access_log.YYYYDMMDD.html

にrenameさせレポートファイル名にも日付がつくようにしています。

cfgファイルでは入力ファイルが

sub1.domain-access_log.1

出力ファイルが

sub1.domain-access_log.html

になっており、レポートファイル名に日付をつけるのはlogrotateに任せています。

またファイルが多くなるとディレクトリが見にくいのでとりあえずlogファイルはlogs/へレポートファイルはreports/へそれぞれ移動させています。

なおanalogにはレポートをグラフ画像で作ってくれる機能がありますが、どうしても画像ファイル名がバッティングしてしまうのでグラフレポート機能はOFFにしています。これらの画像ファイルも日付をつけてrenameしてさらにレポートhtmlをrenameした画像ファイルに対応するように書き換えるスクリプトを作成すれば対応も可能ですがさすがにそこまでやろうとは思いませんでした。

最終的にはlogrotateによって

logs/sub1.domain-access_log.20070101
reports/sub1.domain-access_log.20070101.html

というファイルが作成されます。

これらのレポートを閲覧するためにとりあえずreportsにalias張っています。またurlを指定するのが大変なので閲覧用にレポートファイルが存在すればリンクを張ってリスト表示するような簡単なphpファイルを作成しました。

他に便利なやり方があるのかよく知りませんが、logrotate内でanalogを実行させることでわざわざanalog用にcronを設定しなくて良いこと、(rotateされる)logファイルと同期してレポートが出力されるというメリットがあります。

過去すべてのログのレポートを作成する場合には別の専用の設定ファイルを用意し、そのファイルでは
入力ファイルを /logs/sub1.domain-access_log.*
出力ファイルを /reports/sub1.domain-access_log.all.html
としています。

これはlogrotateのスクリプト内ではやらずに別途cronでanalogを実行させています。現状自宅サーバへのアクセスはほとんどないのですべてのログを読み込ませてもたいした負荷ではありませんが、ログが多い場合は入力ファイル絞った方が良いと思います。

リアルタイムのログを見るためには
入力ファイルを sub1.domain-access_log
出力ファイルを /reports/sub1.domain-access_log.realtime.html
みたいにしてcronで実行させても良いかもしれません。

analogの設定もできてようやく自宅サーバで設定しておきたい項目がすべてできました。これでプログラムが心おきなくかけます。^^