unoh.github.com

PHPによるテキストファイルへのロギング

Thu May 10 02:47:55 -0700 2007

yamaokaです。

PHPでwebアプリケーションを作成するとき、 皆さんはロギング(ログの出力)をどうされているでしょうか。 今回は、テキストファイルへロギングする方法をいくつか紹介したいと思います。

error_log関数

PHPでは、標準の関数として error_log関数が用意されています。 使い方はとてもシンプルです。2番目の引数に「3」を指定することで、 テキストファイルにログを出力することができます。

error_log('message', 3, '/var/tmp/app.log');

syslog関数

また、syslog関数も 標準で用意されている関数です。syslog経由でテキストファイルにログを出力することができます。Windowsの場合は、イベントログでエミュレートされます。

define_syslog_variables();
openlog('App log', LOG_PID | LOG_PERROR, LOG_LOCAL0);
syslog(LOG_INFO, 'message');
closelog();

error_log関数とsyslog関数を紹介しましたが、 もちろん、通常のファイル書き込みと同じように ファイルシステム関数を利用してロギングしてもいいですね。 いずれにせよ、ログのフォーマットやログレベルの設定ができないので、 必要な場合は自分でライブラリとして実装しなくてはいけません。

PEAR::Log

PEARで利用できるロギングユーティリティとして、 PEAR::Logがあります。 テキストファイルへのロギングの他に、Eメールやデータベースなどへのロギングに対応しています。 ロギングのフォーマットによっては他のPEARライブラリに依存していることがあるので、注意が必要です。

$conf = array('mode' => 0644);
$log =& Log::singleton('file', '/var/tmp/app.log', 'ident', $conf, PEAR_LOG_INFO);
$log->log('message');

log4php

Javaにlog4jというロギングの定番ライブラリがありますが、 log4phpはそのPHP版です。 ApacheのLogging Service Projectで開発されています。 log4jと同じように、ログの出力フォーマットの制御を細かく行うことができるのが特徴です。 テキストファイルへのロギングの他に、Eメール、データベース、ソケット経由などへのロギングに対応しています。

// 設定
define('LOG4PHP_DIR', 'lib/log4php');
define('LOG4PHP_CONFIGURATION', './log4php.properties');

$logger =& LoggerManager::getLogger('App');

// ログ出力
$logger->info('message');

LoggerManager::shutdown();

ログの出力フォーマット、出力先などはすべて設定ファイル(上記例なら「log4php.properties」)で指定します。 設定ファイルの記述は以下のようになります。

# ログ出力設定(テキストファイル、ログレベルはDEBUG)
log4php.rootLogger=DEBUG, R

# サイズベースのテキストログローテート
log4php.appender.R=LoggerAppenderRollingFile
log4php.appender.R.File=app.log
log4php.appender.R.Append=true
log4php.appender.R.MaxBackupIndex=5
log4php.appender.R.MaxFileSize=1000
log4php.appender.R.layout=LoggerPatternLayout
log4php.appender.R.layout.ConversionPattern="%d %5p [%x] - %m%n"

Zend_Log

Zend Frameworkの中に、 Zend_Logというモジュールがあります。 テキストファイルへのロギングの他に、標準出力、データベースなどへのロギングに対応しています。 Zend Frameworkの1モジュールですが、単体でも問題なく利用することができます。 PHP5以上でないと動作しません。

ログレベルを自分で定義できたり、フォーマッタやフィルタの機能が備わっているので、 カスタマイズが自由にできるという点でいいかもしれません。 それぞれ用意されている抽象クラスを継承して、必要な実装をすれば自由に機能を追加することができます。

// 出力フォーマット
$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
$formatter = new Zend_Log_Formatter_Simple($format);

$writer = new Zend_Log_Writer_Stream('/var/tmp/app.log');
$writer->setFormatter($formatter);

// 出力レベル
$filter = new Zend_Log_Filter_Priority(Zend_Log::INFO);

$logger = new Zend_Log();
$logger->addWriter($writer);
$logger->addFilter($filter);

// ログ出力
$logger->info('message');

最後に

何かしらのフレームワークを利用する場合、 そのフレームワークに付属するロギングモジュールを利用することが多いかと思います。 しかし、PEAR::Logやlog4phpなどのようなロギングユーティリティを使うと、 よりきめ細かなロギングが可能になることもあるのではないでしょうか。 車輪の再発明をしないために、いくつかロギングユーティリティを知っておくのも悪くないと思います。

※syslog関数に関する記述を追記しました(2007年5月11日)。