Apacheのログをソート

私が管理しているWebサイトでは外部からのHTTPリクエストを2つのApacheで受けていて、DNSラウンドロビンで負荷を分散させています。なので当然アクセスログは、両方のApacheに記録されるのですがアクセス解析のために、その2つのログファイルを統合する必要があります。

使っているアクセス解析ソフトは与えられるCLFログファイルは日付、時間順にソートされていることを期待しているので、2つのログをcatした上でsortしてあげる必要があります。

以前pythonの勉強がてらCLFでソートしてくれるスクリプトを書いたのですが、それ以来順調にアクセス数が増えているようで、とうとうどうやってもメモリ不測でソートが動作しなくなっちまいました。

で、どうやろうかなと悩んでいるのですが、週一でアクセス解析をしてあげないといけないので、とりあえずはRDMSにログファイルを突っ込んで、SQLでsortすることに。

DBにテーブルをつくる。

PostgreSQLを使いました。こんな感じで。

create table logs (
    time_stamp date ,
    strings text 
)

perlDBIを使って突っ込む。

日付部分だけを切り出して、上記でつくったtime_stampのカラムへ投入します。ログファイル全部をotherへ入れちゃいます。スクリプトはこんなの。

#!/usr/local/bin/perl

use DBI;

%attr = (
    PrintError => 1,
    RaiseError => 0
);

$dbh = DBI->connect("dbi:Pg:dbname=apache_log","postgres","",\%attr)
        or die "Cannot connect PostgreSQL database $DBI:errstr\n" ;

while(<>) {
    @words = split() ;
    $time_stamp = $words[3]." ".$words[4];
    $time_stamp =~ s/[\[\]]//g ;
#    print $time_stamp,"\n";
    $str = $dbh->do("insert into logs values (
        '$time_stamp' ,
        '$_' )") or warn "Cannot insert :$_" ;
}

$dbh->disconnect() ;

投入していると、HTTPリクエストのところにシングルクオートが含まれているものがあり、そこでエラーになります。ま、5000万行以上もあるので10行やそこらはムシムシ。

DBからログファイルを抜き出す。

でもってSQLでログファイルを取り出します。

$ psql apache_log
apache_log=# \t
Showing only tuples.
apache_log=# select strings from logs order by time_stamp desc ;

Apacheはsyslogにログを吐き出すことが出来るみたい。これを使えば単一のファイルのログを書くことができそうです。明日以降研究しなきゃ。