CakePHPでlog4phpを利用しようと思ったところ、
3.x以降に対応したドキュメントがなく苦戦しました。
CakePHP本体のインストールについてはこちらを参照してください
動作環境
- CakePHP 3.3
- PHP 7.0.11
- log4php 2.3
インストール
CakePHP3からコンポーザを利用してインストールするようになったので、
log4phpのインストールでもコンポーザを利用します。
composer.json
"require": {
"apache/log4php": "2.3.0"
},
コンポーザを利用すればクラスマップにも自動的に反映されるため、
requireを意識しなくてもlog4phpを利用できるようになります。
log4phpの設定ファイルを作成する
configディレクトリに設定ファイルを作成します。
logsディレクトリにYYYYMMDD.log形式のログファイルが作成されます。
config/log4php.xml
<configuration xmlns="http://logging.apache.org/log4php/">
<appender name="myFileAppender" class="LoggerAppenderDailyFile">
<layout class="LoggerLayoutPattern">
<param name="ConversionPattern" value="%d [%p] %m %n" />
</layout>
<param name="file" value="../logs/%s.log" />
</appender>
<logger name="C1">
<level value="DEBUG" />
<appender_ref ref="myFileAppender" />
</logger>
</configuration>
動作確認
ここで一旦、log4phpが利用できるかどうか確認しておきましょう。
// 設定ファイルの読み込み
\Logger::configure(CONFIG.'log4php.xml');
$logger = \Logger::getLogger('C1');
$logger->info( 'ログ確認。' );
/* 出力例
2016-10-30T10:20:30+09:00 [INFO] ログ確認。
*/
カスタムロガーの作成
CakePHPのロガーとlog4phpを繋ぐためのロガーを作成します。
logメソッドを上書きして、CakePHPのエラーレベルをlog4phpのレベルに置き換えて呼び出します。
src/CustomLogger.php
<?php
namespace App;
use Cake\Log\Engine\BaseLog;
class CustomLogger extends BaseLog {
/**
* ログ出力
*/
public function log( $level, $message, array $context = array() ) {
// メッセージを成型
$message = $this->_format( $message, $context );
// エラーレベルをlog4phpのものに置換
switch ( $level ) {
case LOG_EMERG:
case LOG_ALERT:
case LOG_CRIT:
$level = \LoggerLevel::getLevelFatal();
break;
case LOG_ERR:
$level = \LoggerLevel::getLevelError();
break;
case LOG_WARNING:
case LOG_NOTICE:
$level = \LoggerLevel::getLevelWarn();
break;
case LOG_INFO:
$level = \LoggerLevel::getLevelInfo();
break;
case LOG_DEBUG:
$level = \LoggerLevel::getLevelDebug();
break;
default:
$level = \LoggerLevel::getLevelInfo();
break;
}
// ログ出力
$logger = \Logger::getLogger('C1');
$logger->log( $level, $message );
}
}
Cake\Log\Engine\BaseLogを継承しないと「Psr\Log\LoggerInterfaceを実装しろ」というエラーが出ます。
素直にPsr\Log\LoggerInterfaceを実装するよりもCake\Log\Engine\BaseLogを継承したほうが実装の手間が少ないので、logメソッドだけを上書きするところに落ち着きました。
ロガーの置き換え
config/bootstrap.php
// 設定ファイルの読み込み
\Logger::configure(CONFIG.'log4php.xml');
// 既存の設定をコメントアウト
// Log::config(Configure::consume('Log'));
// カスタムロガーを設定
require_once (APP.'CostomLogger.php');
Log::config('log4php', ['className' => '\App\CostomLogger']);
// 既存のロガーの設定を削除
Log::drop('debug');
Log::drop('error');
再度動作確認
今度はCakePHPのログ出力メソッドでログが出力できるか確認します。
// Controller, Component, View等
$this->log( 'ログ確認。', 'info' );
/* 出力例
2016-10-30T15:30:45+09:00 [INFO] ログ確認。
*/