スポンサード リンク
|
スポンサード リンク
CakePHPのログをLog4phpに切り替える 
ロギング処理をLog4JのPHP版であるLog4phpに切り替えます。
CakePHPのログはファイルに出力する単純な機能しかないので、ローテーションの設定などが本番運用時に必要と思われるので、Log4phpを導入することにします。
- Log4jについては、下記のページを参照してください。
Log4phpのインストール 
CakePHP標準のロギング処理を修正 
- 下記のファイルにロギング処理が書かれているので修正します。
cake/libs/cake_log.php
<?php
if (!class_exists('File')) {
uses('file');
}
/*** log4phpのプロパティファイルの設定とインクルードを行うように追加 ***/
if (!defined('LOG4PHP_CONFIGURATION')) {
if (!defined('APP_DIR')) {
define('LOG4PHP_CONFIGURATION', dirname(dirname(__FILE__)) . DS .'config' .DS .'log4php.properties');
} else {
define('LOG4PHP_CONFIGURATION', ROOT . DS . APP_DIR . DS .'config' .DS .'log4php.properties');
}
}
require_once(VENDORS.'log4php/LoggerManager.php');
/*** ここまで ***/
class CakeLog{
/*** デストラクタをObjectクラスの真似をして用意する ***/
function CakeLog() {
$args = func_get_args();
if (method_exists($this, '__destruct')) {
register_shutdown_function (array(&$this, '__destruct'));
}
}
function __destruct() {
// log4phpのLoggerをシャットダウンする
LoggerManager::shutdown();
}
/*** ここまで ***/
function write($type, $msg) {
/*** Log4phpを使用する場合のみ ***/
if (defined('LOG4PHP_ENABLE') && LOG4PHP_ENABLE == 1) {
$logger =& LoggerManager::getLogger(basename($_SERVER['SCRIPT_NAME']));
$output = sprintf('[%s] %s', session_id(), $msg);
switch ($type) {
case 'debug':
$logger->debug($output);
break;
case 'error':
$logger->error($output);
break;
}
return true;
}
/*** ここまで ***/
$filename = LOGS . $type . '.log';
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $msg . "\n";
$log = new File($filename);
return $log->append($output);
}
}
?>
※log4phpの本体をvendorsフォルダに移動したため、そこからインクルードするようにした。
※log4phpのLoggerをシャットダウンしないといけないようなので、デストラクタを作って対応した。
※セッションIDもログメッセージに付加するようにした。
Log4phpのエラー対策 
- そのままだと、Log4phpでエラーになります。
画面に下記のようなメッセージが表示される。
Notice: Only variable references should be returned by reference in
C:\eclipse_pdt\workspace\cakeshop\cake\libs\log4php\LoggerAppender.php on line 73
- もしかしたら、php4の場合だけかもしれませんが、同じような現象が、下記のスレッドに書かれていたので、対応します。
[s2container-php5:53] Re: [質問]S2DaoのMetaDataクラスとログ出力について
- log4php\LoggerAppender.phpの60行目
function &singleton($name, $class = '')
↓
function singleton($name, $class = '')
- log4php\LoggerPropertyConfigurator.phpの509行目
function &parseCategory($props, &$logger, $optionKey, $loggerName, $value)
↓
function &parseCategory($props, &$logger, $optionKey, $loggerName, $value)
- log4php\LoggerPropertyConfigurator.phpの574行目
$appender =& LoggerAppender::singleton($appenderName);
↓
$appender = LoggerAppender::singleton($appenderName);
- log4php\LoggerPropertyConfigurator.phpの587行目
$appender =& LoggerAppender::singleton($appenderName, $appenderClass);
↓
$appender = LoggerAppender::singleton($appenderName, $appenderClass);
アプリケーション毎の設定 
グローバル定数 
Log4phpの設定 
- Log4phpの設定は、propertiesファイルとして作成します。
日付毎にファイルを切り替えるようにする設定
app/config/log4php.properties
#---------------------------------
# @rotete daily
# @logfile ./log/error_log_%s.txt
# @pattern %d [%t] %-5p %c - %m%n
#---------------------------------
log4php.rootLogger=DEBUG, R
log4php.appender.R=LoggerAppenderDailyFile
log4php.appender.R.file=../tmp/logs/error_log_%s.txt
log4php.appender.R.layout=LoggerPatternLayout
log4php.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
設定方法は、Log4Jと同じです。
ログの出力ファイルは、とりあえず
app/tmp/logs/error_log_日付.txt
にしています。
- ファイルサイズによってローリングする設定
log4php.rootLogger=DEBUG, R
log4php.appender.R=LoggerAppenderRollingFile
log4php.appender.R.file=../tmp/logs/error_log.txt
log4php.appender.R.layout=LoggerPatternLayout
log4php.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4php.appender.R.MaxFileSize=10240
log4php.appender.R.MaxBackupIndex=3
この場合は、error_log.txt.1、error_log.txt.2とファイル名の後ろに数字が付加されてバックアップが3つまで残る設定です。
ログの出力方法 
SQLのログもlog4phpでファイルに出力する 
- SQLのログは、DEBUGを2にしておくと画面に表示されますが、ログの内容をファイルに保存したいと思います。
- クエリーでエラーが発生した場合は、errorで出力し、その他は、debugで出力するようにします。
- 下記のソースを修正します。
cake/libs/model/datasources/dbo_source.php
function logQuery($sql) {
$this->_queriesCnt++;
$this->_queriesTime += $this->took;
$this->_queriesLog[] = array('query' => $sql,
'error' => $this->error,
'affected' => $this->affected,
'numRows' => $this->numRows,
'took' => $this->took
);
// SQLのクエリーログを出力する
$logMessage = 'queryLog = '.print_r($this->_queriesLog[count($this->_queriesLog) - 1], true);
if ($this->error) {
$this->log($logMessage, LOG_ERROR);
} else {
$this->log($logMessage, LOG_DEBUG);
}
// ここまで
if (count($this->_queriesLog) > $this->_queriesLogMax) {
array_pop($this->_queriesLog);
}
if ($this->error) {
return false;
}
}
これで、何かSQLの異常が発生した場合に、ログファイルで確認できるようになります。
通常のロギング処理でのエラー対策 
ログファイルの監視ソフト 
関連ページ 
コメント 
スポンサード リンク
|