勉強会で話したZend_Logを拡張してログのローテーションをできるようにしたものです。
log4jやlog4phpを参考にしながら、基本的な機能の部分をZend_Logに合わせて作りました。
前回の記事でも書きましたが、logrotateなどを使用してサーバー側でローテーションできないような場合(junichiroさんがコメントで仰っているようにレンタルサーバーなど)に、使用するといいかもしれません。
■ 特徴
- 特定の期間やログのサイズをもとにローテーションを行うことができる
- ローテーションの方法を自由に拡張できる
- Zend_Logを使っていれば、writerを変更するだけで設定ができる
■ 構成
1 2 3 4 5 6 7 8 9 10 11 12 |
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つを用意しています。
■ 使用方法
- Wads_Log_RotationFileクラスのオブジェクトを生成する
- 1で生成したオブジェクト指定してWads_Log_Writer_RotationFileのオブジェクトを生成する
- Wads_Log_Writer_RotationFileのオブジェクトをZend_Logに追加する
- Zend_Logのlog()関数などを使ってログを書き出す
3以降は通常のZend_Logの使い方と同じです。
使用例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// ログファイル名 $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で指定します。
1 2 |
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のように番号が付与されます。
たとえば、
1 2 |
file : /var/log/foo/test.log backupindex : 3 |
の場合、以下のようになります
1 2 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で指定した値に置き換えられます。
1 2 3 |
file : /var/log/foo/test.log deteformat : Ymd nameformat : %file.%date |
の場合
1 |
/var/log/foo/test.log.20090420 |
となります
■ Wads_Log_RotationFileを指定しない場合
もし、Wads_Log_RotationFileをWads_Log_Writer_File設定しなければ(コンストラクタの第三引数を指定しない)、Zend_Log_Writer_Streamで、ファイルをオープンした場合と同等の機能で使用できます。
そのほかの関数については、あまり複雑ではないので直接ソースを見ていただくといいです。
■ 設計的なところ
Wads/Log/RotationFile 以下に Policyディレクトリを作らずに、直接クラスを配置したほうがすっきりするかもしれません。
こんな感じです
1 2 3 4 5 6 |
Wads/ Log/ RotationFile/ Abstract.php Datetime.php Size.php |
もともとWads/Log/RotationFile 以下は
1 2 3 |
RotationFile/ Trigger/ Policy/ |
となっていました。
これはlog4jに倣って、ローテーションのきっかけとなる条件を定義するトリガークラスなるものと、ローテーションの方法を定義するポリシークラスに分けていたためです。
ただし、途中で設計を変更して、今回はシンプルにするために2つをあわせてポリシーとしました。
今回は使い方について書きましたが、次回は拡張する場合の方法や、関連する部分の仕組みを書いてみようと思います。
One thought on “[Zend Framework]Zend_Logでログのローテーション”