=encoding euc-jp =head1 名前 Logfile - ログファイルからレポートを生成するためのPerl拡張 =head1 概要 use Logfile::Cern; $l = new Logfile::Cern File => 'cache.log.gz', Group => [Domain,File,Hour]; $l->report(Group => File, Sort => Records); $l->report(Group => Domain, Sort => Bytes); $l->report(Group => Hour, List => [Bytes, Records]); use Logfile::Wftp; [...] =head1 説明 Logfile拡張は各種のサーバーのログファイルからさまざまなレポートを 生成することを助けてくれます。通常、ログファイルからどんな情報を取り出すかに ついての制限はありません。 =head2 ファイルの読込 Cをサブクラス化することによってパッケージをカスタマイズすることができます。 サブクラスはファイルハンドルC<$self-E{Fh}>から次のレコードを 読み込み、C型のオブジェクトを返す関数Cを 提供しなければなりません。さらにさまざまなレコードフィールドを 標準化するためにCを指定することが出来ます。 以下にCクラスの短くされたバージョンを示します: package Logfile::Cern; @ISA = qw ( Logfile::Base ) ; sub next { my $self = shift; my $fh = $self->{Fh}; *S = $fh; my ($line,$host,$user,$pass,$rest,$date,$req,$code,$bytes); ($host,$user,$pass,$rest) = split ' ', $line, 4; ($rest =~ s!\[([^\]]+)\]\s*!!) && ($date = $1); ($rest =~ s!\"([^\"]+)\"\s*!!) && ($req = (split ' ', $1)[1]); ($code, $bytes) = split ' ', $rest; Logfile::Record->new(Host => $host, Date => $date, File => $req, Bytes => $bytes); } 上記で述べたように、一般的には自由にレコード内でフィールドとして 入力するものを選択することができます。しかし: =over 5 =item B これは適切な日付文字列でなければなりません。 エポック(=epoch)開始からの経過秒数に変換するために モジュールFとFが試されます。 もし両方ともCできなければ、crudeな組み込みモジュールが 使われます。 レコードコンストラクタはBを格納できるようにC形式に 置換します。またフィールドBもpadすることができます。 =item B Bを設定すると、完全に修飾されたドメイン名(ホスト名.ドメイン)の ドメインsuffix国の冗長な名前フィールドBも設定します。 CはCに対応付けられます。ドットが入っていない ホスト名はドメインBに結び付けられます。IP番号は ドメインBに結び付けられます。 ドメイン名での短い名前から長い名前への対応付けは、B拡張の 中で行われます。これは別の場面で便利かもしれません: use Net::Country; $germany = Net::Country::Name('de'); =item B これはCコンストラクタの中で常に1に設定されます。そのため このフィールドがC関数からの成功した戻り値の数を返します。 =back 以下にオプションのCメソッドの短くされたバージョンを示します: sub norm { my ($self, $key, $val) = @_; if ($key eq File) { $val =~ s/\?.*//; # remove query $val =~ s!%([\da-f][\da-f])!chr(hex($1))!eig; # decode escapes } $val; } コンストラクタはログファイルを読み込み、1つあるいは複数のインデックスを 組み立てます。 $l = new Logfile::Cern File => 'cache.log.gz', Group => [Host,Domain,File,Hour,Date]; 追加のインデックスを作成するためにはほとんど空間は要りませんが、 時間のオーバーヘッドはいくらかあります。もしBが与えられなければ、 Bが使われます。Groupパラメータはフィールド名あるいはフィールド名の リストへのリファレンスにすることができます。コンストラクタへの引数として 与えられたフィールド名だけが、レポート生成に使うことが出来ます。 =head2 レポート生成 レポートのために使われるインデックスはBパラメータで 与えられなければなりません。Bが与えられなければ、出力は インデックス・フィールドによってソートされます。また Bや Bによって出力を切り捨てることもできます。 レポート・ジェネレータは与えられたインデックスのフィールドBと Bをリストにします。オプションBは1つのフィールド名、 あるいはフィールド名の配列へのリストにすることができます。それは Bフィールドに加えてリストにされるフィールドを指定します。 Bのデフォルトはレコードです。 $l->report(Group => Domain, List => [Bytes, Records]) 出力はBによって上書きされなければ、Bフィールドによって ソートされます。デフォルトのソート順序は、BとBBの 昇順、そしてその他のフィールドの降順になります。この順番は、 Bオプションを使って逆にすることができます。 このコードは $l->report(Group => File, Sort => Records, Top => 10); 以下のように出力します: File Records ===================================== /htbin/SFgate 30 31.58% /freeWAIS-sf/* 22 23.16% /SFgate/SFgate 8 8.42% /SFgate/SFgate-small 7 7.37% /icons/* 4 4.21% /~goevert 3 3.16% /journals/SIGMOD 3 3.16% /SFgate/ciw 2 2.11% /search 1 1.05% /reports/96/ 1 1.05% 以下にもう一つ例を示します。これもFファイルも見てください: $l->report(Group => Domain, Sort => Bytes); Domain Records =============================== Germany 12 12.63% Unresolved 8 8.42% Israel 34 35.79% Denmark 4 4.21% Canada 3 3.16% Network 6 6.32% US Commercial 14 14.74% US Educational 8 8.42% Hong Kong 2 2.11% Sweden 2 2.11% Non-Profit 1 1.05% Local 1 1.05% $l->report(Group => Hour, List => [Bytes, Records]); Hour Bytes Records ====================================== 07 245093 17.66% 34 35.79% 08 438280 31.59% 19 20.00% 09 156730 11.30% 11 11.58% 10 255451 18.41% 16 16.84% 11 274521 19.79% 10 10.53% 12 17396 1.25% 5 5.26% =head2 レポートのオプション =over 5 =item B C<=E> I 必須。Iはコンストラクタに渡されたフィールドの1つでなければなりません。 =item B C<=E> I =item B C<=E> [I, I] Iのための集計を一覧にします。デフォルトはBです。 =item B C<=E> I. Iによって出力をソートします。デフォルトではBとBは昇順にソートされ、 その他のフィールドは降順にソートされます。 =item B C<=E 1> ソート順を逆にします。 =item B C<=E> I 先頭からI行の集計だけを出力します。 =item B C<=E> I Iよりも大きなBフィールドを持った集計だけを出力します (昇順の場合にはよりnumberよりも小さい数)。 =back 現在のところレポートは単純にSTDOUTに出力されます。 =head1 作者 Ulrich Pfeifer EFE =head1 ニュース perl 5.005用にstrict refsのバグを修正。 James Downsによって報告された含まれている日付解析への落ち込みでの バグを修正。 Fred Korzによって提案されたようにy2kバグを修正。私は2桁バージョンを 出来る限り後方互換性を持てるように選択しました。C<20>は明らかに 今からでは少ない年数です ;-) 出力カラムは今後、いかなる場合でも 空白によって分けられます。 =head1 参考資料 perl(1). =head1 翻訳者 川合孝典(GCD00051@nifty.ne.jp)