LoginSignup
2
2

More than 5 years have passed since last update.

CakePHP3.xのログをlog4phpを利用して出力する

Posted at

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] ログ確認。
*/
2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2