6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CodeIgniterのログを独自カテゴリーに分けて出力する

Posted at

CodeIgniterにはログファイルを簡単に作成してくれる関数が用意されています。

エラー処理-log_message
http://codeigniter.jp/user_guide/3/general/errors.html?highlight=%E3%83%AD%E3%82%B0#log_message

この関数、CodeIgniterが読み込まれている範囲であればどこでも、

log_message('debug', 'デバックメッセージ');

と書けば、application/logsの中にlog-2018-10-05.phpのような形でファイルが作成され、中身に

log-2018-10-05.php
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>

DEBUG - 2018-10-05 17:33:35 --> デバックメッセージ

というようなログが溜まっていきます(ただし、config/config.phpの設定やapplication/logsへApacheの書き込み権限設定が必要)。

しかしこのログ、自分で仕込んだlog_message()以外にもCodeIgniterのコア部分で多用されていることもあり、CodeIgniterが起動する度に結構なメッセージが書き込まれていきます。

時系列に沿って書き込まれていくとはいえ、欲を言えばカテゴリー別にログが取れればもっと便利にログを使えそうです。

なので作りました。

※対象はCodeIgniterの3系です。

Logクラスを拡張する

コアシステムクラスの作成-システムクラス一覧

だいたいのCodeIgniterのコアクラスは自作のクラスで代替可能です。

ただし公式マニュアルが口酸っぱく警告しているとおり、ほとんどの場合はクラスを継承してメソッドをオーバーライドしていくほうが簡単かつ安全でしょう。

今回の拡張もLog.phpを継承したMY_Log.phpを作成することにします。

以下がクラスの全貌です。

MY_Log.php

class MY_Log extends CI_Log {

  private function _write_log($level, $msg)
  {
    $category = isset($this->_levels[$level]) ? '' : $level.'-';

    $filepath = $this->_log_path.'log-'.$category.date('Y-m-d').'.'.$this->_file_ext;
    $message = '';

    if ( ! file_exists($filepath))
    {
      $newfile = TRUE;
      // Only add protection to php files
      if ($this->_file_ext === 'php')
      {
        $message .= "<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>\n\n";
      }
    }

    if ( ! $fp = @fopen($filepath, 'ab'))
    {
      return FALSE;
    }

    flock($fp, LOCK_EX);

    // Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
    if (strpos($this->_date_fmt, 'u') !== FALSE)
    {
      $microtime_full = microtime(TRUE);
      $microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
      $date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full));
      $date = $date->format($this->_date_fmt);
    }
    else
    {
      $date = date($this->_date_fmt);
    }

    $message .= $this->_format_line($level, $date, $msg);

    for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result)
    {
      if (($result = fwrite($fp, self::substr($message, $written))) === FALSE)
      {
        break;
      }
    }

    flock($fp, LOCK_UN);
    fclose($fp);

    if (isset($newfile) && $newfile === TRUE)
    {
      chmod($filepath, $this->_file_permissions);
    }

    return is_int($result);
  }

  /**
   * Write Log File
   *
   * Generally this function will be called using the global log_message() function
   *
   * @param	string	$level 	The error level: 'error', 'debug' or 'info'
   * @param	string	$msg 	The error message
   * @return	bool
   */
  public function write_log($level, $msg)
  {
    if ($this->_enabled === FALSE)
    {
      return FALSE;
    }

    $level = strtoupper($level);

    if ( ! isset($this->_levels[$level]))
    {
      return $this->_write_log($level, $msg);
    }

    if (
      isset($this->_levels[$level])
      && (($this->_levels[$level] > $this->_threshold))
      && ! isset($this->_threshold_array[$this->_levels[$level]])
    )
    {
      return FALSE;
    }

    return $this->_write_log($level, $msg);
  }

}

このコードをapplication/core/MY_Log.phpの位置に配置すると拡張処理が動作します。

どんなものが出力されるのか

先述のように、

log_message('debug', 'デバックメッセージ');

と書いても拡張前と書き出されるログは変わりません。
第一引数が「error」「debug」「info」の場合は変わらず、設定ファイルに設定できるしきい値に応じてデフォルトのログファイルに出力されたりされなかったりします。

今回の拡張が役立つのは第一引数にそれら以外の文字列を設定した場合です。

log_message('custome', 'カスタムメッセージ');
log-custome-2018-10-05.php
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>

DEBUG - 2018-10-05 17:36:15 --> カスタムメッセージ

上述のように第一引数をcustomeと設定すると、デフォルトのログファイル名中、__log__と__日付__の間に第一引数と同じ文字列が挿入されたファイルが作成され、以後同じ第一引数が設定されたlog_message()関数はそのファイルへログを追記します。

こうすることでログの種類によってログファイルをカテゴリー分けできるのです。

6
2
0

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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?