テレビ朝日メディアプレックス

BLOGブログ

CodeIgniterのログ出力にlog4phpを使う方法

どうも、鈴木です。久々の投稿となってしまいました。

本日はPHPフレームワークの中でも比較的簡単で扱いやすいCodeIgniterに強力なログ機能をもつlog4phpを使う方法を記事にしようと思います。

log4phpはログレベルを分けることでログの出し分けすることはもちろん、一度のログ書き込み処理で複数の出力先にログを出力してくれるのが素晴らしいですよね。
これによりerrorとかfatalの時だけメール送信したりすることが出来ます。

CodeIgniterとlog4phpの連携方法で検索すると、CodeIgniter内にうまく組み込んでいるソースをよく見るのですが、どれもlog4phpのインスタンスのラッパークラスとかを作ってラッパー越しにログ関数を叩いていたりします。この方法だとexceptionをログに含める時にそのログ関数のスタック情報なども含まれてしまいます。出来ればlog4phpインスタンスを直接叩きたいと思いました。
あと、ログ関数ってどこからでも使いたいので、1回のロードであとはどこからでも使いまわせるようにしたいところです。

というわけで、今回はlog4phpのインスタンスをCodeIgniterのコントローラー・モデル内のどこからでも呼び出す方法を紹介します。

log4phpをcomposerからインストールとロード

(composerを既にインストールしている方やcomposerを使わない方は読み飛ばして下さい。composerを使わなくても手動でlog4phpのLogger.phpをrequireするだけで十分動きます。)
CodeIgniterを使っているディレクトリで

curl -s http://getcomposer.org/installer | php

をして、composer.phar をダウンロードします。
CodeIgniterにはデフォルトでcomposer.jsonが入っていたので、requireのところにlog4phpを追記します。

"require": {
  "apache/log4php": "2.3.0"
}

これによりvendorディレクトリにapache/log4phpがダウンロードされます。
composerでダウンロードしたソースはvendor/autoload.phpをrequireすることで使えるようになりますが、
CodeIgniterはconfigファイルの中にその項目があるのでそこで記述します。いいですね。

log4phpをロードするには、application/config.phpの中で「composer_autoload」という設定を、FALSEからautoload.phpへのパスに変えておきます。
また、後でCodeIgniterの機能でもあるフックを使うので、「enable_hooks」という設定もここでTRUEにしておきましょう。

$config['composer_autoload'] = realpath("../../vendor/autoload.php");

$config['enable_hooks'] = TRUE;

log4phpを扱う自作ライブラリMY_Log.phpの設置

application/libraries に、MY_Log.phpを設置します。命名規則CodeIgniterのお手本に則っています。
この自作ライブラリをロギングしたいところで呼び出します。

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Description of MY_Log
 * ログライブラリのlog4phpをどこからでも呼び出せるようにしたクラス
 * @author taksuzuki
 */
class MY_Log {

  static $app = null; // static Logger instance

  static function setup($configFilePath) {
    // log4phpの構成を読み込みます。
    Logger::configure($configFilePath);
    // このインスタンスのメソッドでログを書き込みます
    self::$app = Logger::getLogger('qatar');
  }

}

// この関数をフック使って呼び出してインスタンス化します
function setup_mylog() {
  $configFilePath = realpath(__DIR__ . "/../config/log4php_config.php");
  MY_Log::setup($configFilePath);
}

log4php_config.phpの作成

application/config に、log4phpの設定ファイル用の log4php_config.phpを設置します。
ここを編集することで、log4phpのログ出力方法を色々変更出来ます。
とりあえずはlog4phpのサイトに記載されているように設定データの配列を返却するphpにします。

<?php

return [
    'rootLogger' => [
        'appenders' => ['default'],
    ],
    'appenders' => [
        'default' => [
            'class' => 'LoggerAppenderFile',
            'layout' => [
                'class' => 'LoggerLayoutSimple'
            ],
            'params' => [
                'file' => FCPATH . 'application/logs/my.log',
                'append' => true
            ]
        ]
    ]
];

フックで呼び出し

先程作成したMY_Logのsetup_mylogを呼び出す為にhooks.phpに追記します。
pre_controller で呼び出すことで全コントローラーの呼び出し前からセットアップが完了し、log4phpインスタンスが使えるようになります。

$hook['pre_controller'] = array(
  'class'    => '', // 手続き型関数を呼び出す時は空文字
  'function' => 'setup_mylog',
  'filename' => 'MY_Log.php',
  'filepath' => 'libraries',
);

CodeIgniterのautoloadで呼び出し

MY_log自体もコントローラーやモデルから呼べるようにしたいので、config/autoload.phpに追記しちゃいます。

$autoload['libraries'] = array("MY_Log");

使ってみる

以上のことを実装すれば、コントローラーが呼び出される前にlog4phpのインスタンスを作って、staticメンバ変数なのでどこからでも呼び出す事が出来ます。
あとは適宜ロギングしたいところで、

MY_Log::$app->info("ログ書き込み");

というような呼び出し方で直接log4phpのインスタンスからロギング出来ます。

現場からは以上です。

関連する記事

記事を書いた人

スズキ

好きなもの:GORIのハンバーグ、嫌いなもの:通勤
なるべく多くの言語を習得したいエンジニアです。