Logfile-0.302 > Logfile

名前

Logfile - ログファイルからレポートを生成するためのPerl拡張

概要

  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;

  [...]

説明

Logfile拡張は各種のサーバーのログファイルからさまざまなレポートを 生成することを助けてくれます。通常、ログファイルからどんな情報を取り出すかに ついての制限はありません。

ファイルの読込

Logfileをサブクラス化することによってパッケージをカスタマイズすることができます。

サブクラスはファイルハンドル$self->{Fh}から次のレコードを 読み込み、Logfile::Record型のオブジェクトを返す関数nextを 提供しなければなりません。さらにさまざまなレコードフィールドを 標準化するためにnormを指定することが出来ます。

以下にLogfile::Cernクラスの短くされたバージョンを示します:

  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);
  }

上記で述べたように、一般的には自由にレコード内でフィールドとして 入力するものを選択することができます。しかし:

Date

これは適切な日付文字列でなければなりません。 エポック(=epoch)開始からの経過秒数に変換するために モジュールGetDateDate::DateParseが試されます。 もし両方ともuseできなければ、crudeな組み込みモジュールが 使われます。

レコードコンストラクタはDateを格納できるようにyymmdd形式に 置換します。またフィールドHourもpadすることができます。

Host

Hostを設定すると、完全に修飾されたドメイン名(ホスト名.ドメイン)の ドメインsuffix国の冗長な名前フィールドDomainも設定します。 foo.bar.PGPapua Newに対応付けられます。ドットが入っていない ホスト名はドメインLocalに結び付けられます。IP番号は ドメインUnresolvedに結び付けられます。 ドメイン名での短い名前から長い名前への対応付けは、Net::Country拡張の 中で行われます。これは別の場面で便利かもしれません:

  use Net::Country;
  $germany = Net::Country::Name('de');
Records

これはRecordコンストラクタの中で常に1に設定されます。そのため このフィールドがnext関数からの成功した戻り値の数を返します。

以下にオプションのnormメソッドの短くされたバージョンを示します:

  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];

追加のインデックスを作成するためにはほとんど空間は要りませんが、 時間のオーバーヘッドはいくらかあります。もしFileが与えられなければ、 STDINが使われます。Groupパラメータはフィールド名あるいはフィールド名の リストへのリファレンスにすることができます。コンストラクタへの引数として 与えられたフィールド名だけが、レポート生成に使うことが出来ます。

レポート生成

レポートのために使われるインデックスはGroupパラメータで 与えられなければなりません。Sortが与えられなければ、出力は インデックス・フィールドによってソートされます。また TopLimitによって出力を切り捨てることもできます。

レポート・ジェネレータは与えられたインデックスのフィールドBytesRecordsをリストにします。オプションListは1つのフィールド名、 あるいはフィールド名の配列へのリストにすることができます。それは Groupフィールドに加えてリストにされるフィールドを指定します。 Listのデフォルトはレコードです。

  $l->report(Group => Domain, List => [Bytes, Records])

出力はSortによって上書きされなければ、Groupフィールドによって ソートされます。デフォルトのソート順序は、DateHourHourの 昇順、そしてその他のフィールドの降順になります。この順番は、 Reverseオプションを使って逆にすることができます。

このコードは

  $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% 

以下にもう一つ例を示します。これもt/*ファイルも見てください:

  $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% 

レポートのオプション

Group => field

必須。fieldはコンストラクタに渡されたフィールドの1つでなければなりません。

List => field
List => [field, field]

fieldのための集計を一覧にします。デフォルトはRecordsです。

Sort => field.

fieldによって出力をソートします。デフォルトではDateHourは昇順にソートされ、 その他のフィールドは降順にソートされます。

Reverse => 1

ソート順を逆にします。

Top => number

先頭からnumber行の集計だけを出力します。

Limit => number

numberよりも大きなSortフィールドを持った集計だけを出力します (昇順の場合にはよりnumberよりも小さい数)。

現在のところレポートは単純にSTDOUTに出力されます。

作者

Ulrich Pfeifer <pfeifer@wait.de>

ニュース

perl 5.005用にstrict refsのバグを修正。

James Downsによって報告された含まれている日付解析への落ち込みでの バグを修正。

Fred Korzによって提案されたようにy2kバグを修正。私は2桁バージョンを 出来る限り後方互換性を持てるように選択しました。20は明らかに 今からでは少ない年数です ;-) 出力カラムは今後、いかなる場合でも 空白によって分けられます。

参考資料

perl(1).

翻訳者

川合孝典(GCD00051@nifty.ne.jp)