最近サボり気味

[Zend Framework]Zend_Logでログのローテーション

4月 21st, 2009 Posted in Zend Framework

勉強会で話したZend_Logを拡張してログのローテーションをできるようにしたものです。
log4jやlog4phpを参考にしながら、基本的な機能の部分をZend_Logに合わせて作りました。

前回の記事でも書きましたが、logrotateなどを使用してサーバー側でローテーションできないような場合(junichiroさんがコメントで仰っているようにレンタルサーバーなど)に、使用するといいかもしれません。

ソースはこちら

■ 特徴

  • 特定の期間やログのサイズをもとにローテーションを行うことができる
  • ローテーションの方法を自由に拡張できる
  • Zend_Logを使っていれば、writerを変更するだけで設定ができる

■ 構成

Wads/
  Log/
    Writer/
      RotationFile.php
    RotationFile/
      Writer/
        Interface.php
      Policy/
        Abstract.php
        Datetime.php
        Size.php
    RotationFile.php

Wads_Log_Writer_RotationFile クラスが、既存のZend_Log_Writer を拡張してローテーションに対応させたものです。これに、Wads_Log_RotationFile というローテーションを行うクラスを設定して使用します。

また、Wads/Log/RotationFile/Policy 以下にあるクラスでどのようにローテーションを行うか決めています。

現在は、ログファイルのサイズでローテーションを行うWads_Log_RotationFile_Policy_Sizeと、日付や時間、曜日でローテーションを行うWads_Log_RotationFile_Policy_Datetime の2つを用意しています。

■ 使用方法

  1. Wads_Log_RotationFileクラスのオブジェクトを生成する
  2. 1で生成したオブジェクト指定してWads_Log_Writer_RotationFileのオブジェクトを生成する
  3. Wads_Log_Writer_RotationFileのオブジェクトをZend_Logに追加する
  4. Zend_Logのlog()関数などを使ってログを書き出す

3以降は通常のZend_Logの使い方と同じです。

使用例です。

// ログファイル名
$logfile = "/var/log/foo/test.log";
 
// ローテーション方法指定
$opt = array(
    'policy' => 'size', // Wads_Log_RotationFile_Policy_Size使用する
    'backupindex' => 3,
    'size' => 40
);
 
// 1(上の■ 使用方法 の番号)
$lotation = new Wads_Log_Rotation($logfile, $opt);
 
// 2 ('a' は fopen の mode)
$writer = new Wads_Log_Writer_RotationFile($logfile, 'a', $lotation); 
 
// 3
$log = new Zend_Log();
$log->addWriter($writer);
 
/* ...その他フィルターなどZend_Logの設定 */
 
// 4
$log->log("test");

Wads_Log_RotationFileのコンストラクタ内で Wads/Log/RotationFile/Policy 以下のクラスを生成しています。

どのクラスを使用するかはオプション($opt)のpolicyで指定します。

Wads_Log_RotationFile_Policy_Size なら 'policy' => 'size'
Wads_Log_RotationFile_Policy_Datetime なら 'policy' => 'datetime'

その他のオプションは主に Wads/Log/RotationFile/Policy 以下のクラスで使用しています。

■ Wads_Log_RotationFile_Policy_Size を使用する場合

ログファイルが指定したサイズに達した場合にローテーションを行います。以下のオプションが指定できます。

・file
ログファイル名を指定します。
指定しない場合は、Wads_Log_Rotationの第1引数で指定したログファイル名が使用されます。

・size
ログファイルの最大サイズを指定します。このサイズを超えるとローテーションが行われます(デフォルトは10M)。

また、サイズはKB、MB、GBの指定ができます。

・backupindex
ファイルのバックアップを行う世代数を決定します(デフォルトは1)。

世代ごとにファイル名の後ろに、.1、.2のように番号が付与されます。

たとえば、

file        : /var/log/foo/test.log
backupindex : 3

の場合、以下のようになります

/var/log/foo/test.log      … 現在書き込みが行われているファイル
/var/log/foo/test.log.1   … 一つ前に書きこみが行われていたファイル
/var/log/foo/test.log.2   … 一番古いファイル。次のローテーション時に削除される

■ Wads_Log_RotationFile_Policy_Datetime を使用する場合

日付や時間に応じてローテーションを行います。以下のオプションが指定できます。

・file
ログファイル名を指定します。
指定しない場合は、Wads_Log_Rotationの第1引数で指定したログファイル名が使用されます。

パスを除いたファイル名の部分が、nameformatの%file%の部分に置き換えられます。

・dateformat
date()関数の第一引数に指定するフォーマットを指定できます(デフォルトはYmd)。
これでローテーションを行うタイミングや、ファイル名が決定されます。

もし、Y-m-d指定した場合、日毎のローテーションを行い、nameformatの%date%の部分が「2009-04-20」のように置き換えられます。

また、YmdHとすれば、時間毎でのローテーションを行います。

・nameformat
%file% と %date% を使ってパス名を除いたログファイルの名前の部分を決定します(デフォルトは%file%_%date%)。

%file%がfileで指定した値に、%date%がdateformatで指定した値に置き換えられます。

file       : /var/log/foo/test.log
deteformat : Ymd
nameformat : %file.%date

の場合

/var/log/foo/test.log.20090420

となります

■ Wads_Log_RotationFileを指定しない場合

もし、Wads_Log_RotationFileをWads_Log_Writer_File設定しなければ(コンストラクタの第三引数を指定しない)、Zend_Log_Writer_Streamで、ファイルをオープンした場合と同等の機能で使用できます。

そのほかの関数については、あまり複雑ではないので直接ソースを見ていただくといいです。

■ 設計的なところ

Wads/Log/RotationFile 以下に Policyディレクトリを作らずに、直接クラスを配置したほうがすっきりするかもしれません。

こんな感じです

Wads/
  Log/
    RotationFile/
      Abstract.php
      Datetime.php
      Size.php

もともとWads/Log/RotationFile 以下は

RotationFile/
 Trigger/
 Policy/

となっていました。

これはlog4jに倣って、ローテーションのきっかけとなる条件を定義するトリガークラスなるものと、ローテーションの方法を定義するポリシークラスに分けていたためです。

ただし、途中で設計を変更して、今回はシンプルにするために2つをあわせてポリシーとしました。

今回は使い方について書きましたが、次回は拡張する場合の方法や、関連する部分の仕組みを書いてみようと思います。

Post a Comment