ライターは、Zend_Log_Writer_Abstract
を継承したオブジェクトです。ライターの役割は、
ログのデータをバックエンドのストレージに記録することです。
Zend_Log_Writer_Stream
は、ログデータを
PHP のストリーム
に書き出します。
ログのデータを PHP の出力バッファに書き出すには、URL php://output
を使用します。一方、ログのデータを直接 STDERR
のようなストリームに送ることもできます (php://stderr
)。
$writer = new Zend_Log_Writer_Stream('php://output'); $logger = new Zend_Log($writer); $logger->info('Informational message');
データをファイルに書き出すには、 ファイルシステム URL のいずれかを使用します。
$writer = new Zend_Log_Writer_Stream('/path/to/logfile'); $logger = new Zend_Log($writer); $logger->info('Informational message');
デフォルトでは、ストリームを追記モード ("a") でオープンします。
別のモードでオープンするには、Zend_Log_Writer_Stream
のコンストラクタで二番目のオプション引数にモードを指定します。
Zend_Log_Writer_Stream
のコンストラクタには、
既存のストリームリソースを指定することもできます。
$stream = @fopen('/path/to/logfile', 'a', false); if (! $stream) { throw new Exception('ストリームのオープンに失敗しました'); } $writer = new Zend_Log_Writer_Stream($stream); $logger = new Zend_Log($writer); $logger->info('通知メッセージ');
既存のストリームリソースに対してモードを指定することはできません。
指定しようとすると Zend_Log_Exception
をスローします。
Zend_Log_Writer_Db
は、
Zend_Db
を使用してログ情報をデータベースに書き出します。
Zend_Log_Writer_Db
のコンストラクタには
Zend_Db_Adapter
のインスタンス、テーブル名
およびデータベースのカラムとイベントデータ項目との対応を指定します。
$params = array ('host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot'); $db = Zend_Db::factory('PDO_MYSQL', $params); $columnMapping = array('lvl' => 'priority', 'msg' => 'message'); $writer = new Zend_Log_Writer_Db($db, 'log_table_name', $columnMapping); $logger = new Zend_Log($writer); $logger->info('通知メッセージ');
上の例は、一行ぶんのログデータを 'log_table_name' という名前のテーブルに書き出します。データベースのカラム 'lvl' には優先度の番号が格納され、'msg' というカラムにログのメッセージが格納されます。
Zend_Log_Writer_Firebug
は、ログデータを
Firebug
コンソール
に送信します。
すべてのデータの送信には Zend_Wildfire_Channel_HttpHeaders
コンポーネントを使用します。これは HTTP ヘッダを使用するので、
ページのコンテンツには何も影響を及ぼしません。
この方式なら、AJAX リクエストのようにクリーンな JSON
および XML レスポンスを要求するリクエストのデバッグも行えます。
要件:
-
Firefox ブラウザ。バージョン 3 が最適ですがバージョン 2 にも対応しています。
-
Firebug 拡張。 https://addons.mozilla.org/ja/firefox/addon/1843 からダウンロードできます。
-
FirePHP 拡張。 https://addons.mozilla.org/ja/firefox/addon/6149 からダウンロードできます。
例569 Zend_Controller_Front を使ったログ記録
// 起動ファイルで、フロントコントローラのディスパッチの前に記述します $writer = new Zend_Log_Writer_Firebug(); $logger = new Zend_Log($writer); // モデル、ビューおよびコントローラのファイル内でこれを使用します $logger->log('This is a log message!', Zend_Log::INFO);
例570 Zend_Controller_Front を使わないログ記録
$writer = new Zend_Log_Writer_Firebug(); $logger = new Zend_Log($writer); $request = new Zend_Controller_Request_Http(); $response = new Zend_Controller_Response_Http(); $channel = Zend_Wildfire_Channel_HttpHeaders::getInstance(); $channel->setRequest($request); $channel->setResponse($response); // 出力バッファリングを開始します ob_start(); // ロガーをコールします $logger->log('This is a log message!', Zend_Log::INFO); // ログデータをブラウザに送ります $channel->flush(); $response->sendHeaders();
組み込みの優先度やユーザ定義の優先度を使うには
setPriorityStyle()
メソッドを使用します。
$logger->addPriority('FOO', 8); $writer->setPriorityStyle(8, 'TRACE'); $logger->foo('Foo Message');
ユーザ定義の優先度用のデフォルトのスタイルを設定するには
setDefaultPriorityStyle()
メソッドを使用します。
$writer->setDefaultPriorityStyle('TRACE');
サポートしているスタイルは次のとおりです。
表112 Firebug Logging Styles
スタイル | 説明 |
---|---|
LOG |
通常のログメッセージを表示します |
INFO |
情報ログメッセージを表示します |
WARN |
警告ログメッセージを表示します |
ERROR |
エラーログメッセージを表示し、Firebug のエラーカウントをひとつ増やします |
TRACE |
拡張スタックトレースつきのログメッセージを表示します |
EXCEPTION |
拡張スタックトレースつきのエラーログメッセージを表示します |
TABLE |
拡張テーブルつきのログメッセージを表示します |
任意の PHP の変数を組み込みの優先度でログに記録できますが、 特殊なログ形式を使う場合は、何らかの書式変換が必要となります。
LOG
、INFO
、WARN
、ERROR
そして TRACE
については特別な書式変換は不要です。
Zend_Exception
のログを記録するには、
単にその例外オブジェクトをロガーに渡すだけです。
設定している優先度やスタイルにかかわらず、
例外は自動的に例外と判断されます。
$exception = new Zend_Exception('Test exception'); $logger->err($exception);
ログを表形式で記録できます。カラムは自動検出され、 データの最初の行がヘッダと見なされます。
$writer->setPriorityStyle(8, 'TABLE'); $logger->addPriority('TABLE', 8); $table = array('Summary line for the table', array( array('Column 1', 'Column 2'), array('Row 1 c 1',' Row 1 c 2'), array('Row 2 c 1',' Row 2 c 2') ) ); $logger->table($table);
Zend_Log_Writer_Mail
は、
Zend_Mail
を使ってログエントリをメールのメッセージに書き出します。
Zend_Log_Writer_Mail
のコンストラクタは
Zend_Mail
オブジェクトを受け取り、
またオプションで Zend_Layout
オブジェクトを受け取ります。
Zend_Log_Writer_Mail
の主な使い道は、
開発者やシステム管理者など関係者に対して
PHP スクリプトで発生したエラーを通知することです。
「何か問題がおこったら、すぐに人間に通知しないとね。
そうすればすぐに適切な対応ができるわけだから」そんなアイデアを元に
Zend_Log_Writer_Mail
が誕生しました。
基本的な使い方は以下のとおりです。
$mail = new Zend_Mail(); $mail->setFrom('errors@example.org') ->addTo('project_developers@example.org'); $writer = new Zend_Log_Writer_Mail($mail); // 件名に使用するテキストを設定します。実際にメッセージを送信する前に、 // 発生したエラー数がこの件名に付け加えられます $writer->setSubjectPrependText('Errors with script foo.php'); // 警告レベル以上の場合にのみメールを送信します $writer->addFilter(Zend_Log::WARN); $log = new Zend_Log(); $log->addWriter($writer); // なにかが起こりました! $log->error('unable to connect to database'); // ライターの処理が終了すると Zend_Mail::send() が立ち上がり、 // 上の Zend_Log フィルタレベル以上のすべてのログメッセージが送信されます
Zend_Log_Writer_Mail
は、デフォルトで
メールの本文をプレーンテキスト形式でレンダリングします。
指定したフィルタレベル以上のすべてのログエントリが、 ひとつのメールにまとめて送られます。たとえば、 警告レベル以上を送信するよう設定しているときに 2 つの警告と 5 つのエラーが発生したら、 メールには 7 つのログエントリが含まれることになります。
Zend_Layout
のインスタンスを使用して、
マルチパートメールの HTML 部を作成できます。
Zend_Layout
のインスタンスが用いられた場合、
Zend_Log_Writer_Mail
は HTML をレンダリングするものとみなし、
Zend_Layout
がレンダリングした値をメッセージの本文
HTML として設定します。
Zend_Log_Writer_Mail
で
Zend_Layout
のインスタンスを使う場合には、
setLayoutFormatter()
メソッドで独自のフォーマッタを指定できます。
Zend_Layout
用のエントリフォーマッタを指定しなかった場合は、
現在使用中のものをそのまま使います。
Zend_Layout
で独自のフォーマッタを使用する方法を以下に示します。
$mail = new Zend_Mail(); $mail->setFrom('errors@example.org') ->addTo('project_developers@example.org'); // 件名は Zend_Mail のインスタンスには設定していないことに注意しましょう! // シンプルに、デフォルトの Zend_Layout のインスタンスを使用します $layout = new Zend_Layout(); // エントリを li タグで囲むフォーマッタを作成します $layoutFormatter = new Zend_Log_Formatter_Simple( '<li>' . Zend_Log_Formatter_Simple::DEFAULT_FORMAT . '</li>' ); $writer = new Zend_Log_Writer_Mail($mail, $layout); // Zend_Layout でレンダリングするための、エントリのフォーマッタを適用します $writer->setLayoutFormatter($layoutFormatter); $writer->setSubjectPrependText('Errors with script foo.php'); $writer->addFilter(Zend_Log::WARN); $log = new Zend_Log(); $log->addWriter($writer); // なにかが起こりました! $log->error('unable to connect to database'); // ライターの処理が終了すると Zend_Mail::send() が立ち上がり、 // 上の Zend_Log フィルタレベル以上のすべてのログメッセージが送信されます // メールは、プレーンテキストと HTML パートの両方を含む形式になります
setSubjectPrependText()
メソッドを
Zend_Mail::setSubject()
のかわりに使用すると、
メールを送信する直前に件名を動的に書き込むことができます。たとえば、
件名のテキストが "Errors from script" だとすると、
2 つの警告と 5 つのエラーが発生した場合に Zend_Log_Writer_Mail
が作成するメールの件名は "Errors from script (warn = 2;
error = 5)" となります。Zend_Log_Writer_Mail
で件名のテキストを設定しなかった場合、もし Zend_Mail
で設定されていればそれを使用します。
ログエントリをメールでおくるのは危険なこともあります。 スクリプト内でのエラー条件の処理が不適切だったり エラーレベルの使用法を間違えたりすると、 エラーの発生頻度によっては何百通何千通ものメールを送信してしまう可能性があります。
現時点では、Zend_Log_Writer_Mail
にはメッセージを抑制したりひとつにまとめたりする機能はありません。
そのような機能が必要な場合は自前で実装する必要があります。
もう一度言いますが、Zend_Log_Writer_Mail
の第一の目標は、人間に向けてエラーの情報を積極的に伝えることです。
これらのエラーがタイミングよく処理され、
このような状況が避けられるような機能が実装されたときには、
メールによるエラー通知は便利な道具となることでしょう。
Zend_Log_Writer_Syslog
は、
システムログ (syslog) にログ項目を書きます。
内部的には、それはPHPの
openlog()
やcloselog()
、
そしてsyslog()
関数の代わりです。
Zend_Log_Writer_Syslog
が役立つ例の1つは、
クラスター形成されたマシンからシステムログ機能を通して集計されるログです。
多くのシステムでは、システム・イベントをリモートでログ収集できます。
それにより、システム管理者が単一のログファイルでマシンのクラスタをモニターできるようになります。
デフォルトで、生成されるsyslogメッセージはすべて、 文字列「Zend_Log」という接頭辞が付きます。 コンストラクタ、またはアプリケーション・アクセッサにアプリケーション名を渡すことで、 そのようなログメッセージを特定する異なる「アプリケーション」名を指定するかもしれません。
//インスタンス生成時に任意で "application" キーを渡します。 $writer = new Zend_Log_Writer_Syslog(array('application' => 'FooBar')); //そのほかいつでも $writer->setApplicationName('BarBaz');
システムログでは "facility" やアプリケーション・タイプ、 またはログ収集メッセージを指定できます。 多くのシステム・ロガーは、実は機能毎に異なるログファイルを生成します。 それは、前と同じように、サーバ活動をモニターする管理者を助けます。
コンストラクタ、またはアクセッサでログ機能を指定するかもしれません。
それは、openlog() マニュアルで定義される
openlog()
定数のうちの1つでなければなりません。
//インスタンス生成時に任意で "facility" キーを渡します。 $writer = new Zend_Log_Writer_Syslog(array('facility' => LOG_AUTH)); //そのほかいつでも $writer->setFacility(LOG_USER);
ログ収集時に、デフォルトのZend_Log
優先度定数を使い続けるかもしれません。
内部的には、それらは適切なsyslog()
優先度定数にマップされます。
Zend_Log_Writer_ZendMonitor
では、Zend Server のモニター
API を介してイベントを記録できます。
これにより、アプリケーション環境全体のログ・メッセージを一箇所に集約できます。
内部的には、それは単に Zend モニター API 由来の
monitor_custom_event()
関数を使用します。
モニター API で特に役立つ機能は、 ログ・メッセージと一緒に任意のカスタム情報を指定できることです。 たとえば、例外を記録したい場合、まさにその例外メッセージを記録できません。 しかし、関数に例外オブジェクトを全て渡せます。 そして、Zend Server イベント・モニターの内部でオブジェクトを調査できます。
Zend モニターがインストールされ、使用可能にされなければいけません
このログ・ライタを使用するには、Zend モニターがインストールされ、使用可能にされなければなりません。
しかしながら、Zend モニターが検出されない場合、NULL
ロガーとして単純に動作するように設計されています。
ZendMonitor
ログ・ライタのインスタンス生成は特記するまでもありません。
$writer = new Zend_Log_Writer_ZendMonitor(); $log = new Zend_Log($writer);
それから、通常通り単純にメッセージを記録します。
$log->info('This is a message');
イベントと共に記録する追加の情報を指定したい場合は、 2番目の引数でその情報を渡します。
$log->info('Exception occurred', $e);
2番目の引数は、スカラー、オブジェクトまたは配列です。 情報の複数の部分を渡す必要があるならば、そうする最高の方法は連想配列を渡すことです。
$log->info('Exception occurred', array( 'request' => $request, 'exception' => $e, ));
Zend Server 内では、イベントは「カスタム・イベント」として記録されます。 「モニター」タブから「イベント」項目を選び、カスタム・イベントを見るために、「カスタム」上で絞り込みます。
Zend Server のモニター・ダッシュボードのイベント
このスクリーン・ショットで、一覧表示される最初の2つのイベントは、
ZendMonitor
ログ・ライタを通して記録されるカスタム・イベントです。
関連した情報を全て見るには、イベントをクリックします。
Zend Server のモニターのイベント詳細
「カスタム」タブをクリックすると、ログ収集メソッドに2番目の引数を渡して記録した
追加の情報を全て詳しく表示します。
この情報は、info
キーとして記録されます。
この例では、リクエスト・オブジェクトが記録されることを確認できます。
Zend_Application との統合
zf.sh と zf.bat コマンドは、デフォルトで
Zend_Application
ログ・リソース用の構成を追加します。
そして、それは ZendMonitor
ログ・ライタ用の構成を含みます。
さらに、ErrorController
は、アプリケーション例外を記録するために
構成されたロガーを使います。それは、デフォルトでZend モニター・イベント統合とともに提供します。
前述のように、モニター API が PHP インストールで検出されない場合、
ロガーは単純に NULL
ロガーとして動作します。
Zend_Log_Writer_Null
はスタブで、ログデータをどこにも書き出しません。
これは、ログ出力を無効にしたりテスト時などに便利です。
$writer = new Zend_Log_Writer_Null; $logger = new Zend_Log($writer); // どこにも出力されません $logger->info('通知メッセージ');
Zend_Log_Writer_Mock
は非常にシンプルなライターです。
受け取った生のデータを配列に格納し、それを public プロパティとして公開します。
$mock = new Zend_Log_Writer_Mock; $logger = new Zend_Log($mock); $logger->info('通知メッセージ'); var_dump($mock->events[0]); // Array // ( // [timestamp] => 2007-04-06T07:16:37-07:00 // [message] => 通知メッセージ // [priority] => 6 // [priorityName] => INFO // )
モックが記録したイベントを消去するには、単純に $mock->events = array() とします。
合成ライターオブジェクトはありません。
しかし、ログのインスタンスは任意の数のライターに書き出すことができます。そのためには
addWriter()
メソッドを使用します。
$writer1 = new Zend_Log_Writer_Stream('/path/to/first/logfile'); $writer2 = new Zend_Log_Writer_Stream('/path/to/second/logfile'); $logger = new Zend_Log(); $logger->addWriter($writer1); $logger->addWriter($writer2); // 両方のライターに書き出されます $logger->info('通知メッセージ');