CodeIgniterでlog4phpを使ってログ出力

# 背景
CodeIgniterの標準機能でログ出力する場合はlog_message()を使います。

```
log_message('info', 'message');    
```

log4jに慣れ親しんできた元Java屋からすると、log4jと同じようなインターフェースでログ出力したい！
そこでlog4jと同等の利用方法ができそうなApache log4phpを使ってログ出力できるようにします。

今回は下記のようにログ出力するように実装したいと思います。ログファイルにはセッションIDとサーバホスト名も出力します。

```php:application/controllers/Welcome.php
$this->my_logger->info('test1');
$this->my_logger->warn('test2');
$this->my_logger->error('test3', new Exception('EX'));
```

```:application/logs/my.log.20180716
2018-07-16 00:03:48,581 [INFO ] c3p7jabj3qvvhb71v03ap5bqsa3t8l64 localhost.localdomain test1
2018-07-16 00:03:48,596 [WARN ] c3p7jabj3qvvhb71v03ap5bqsa3t8l64 localhost.localdomain test2
2018-07-16 00:03:48,596 [ERROR] c3p7jabj3qvvhb71v03ap5bqsa3t8l64 localhost.localdomain test3
Exception: EX in /vagrant/public/application/controllers/Welcome.php:25
Stack trace:
#0 /vagrant/public/system/core/CodeIgniter.php(532): Welcome->index()
#1 /vagrant/public/index.php(315): require_once('/vagrant/public...')
#2 {main}
```

# CodeIgniterでApache log4phpを使う

Composerからインストールします。

```json:composer.json
{
    "require": {
        "apache/log4php": "2.3.0"
    }
}
```

composer installしたら、CodeIgniterから利用できるようにconfig.phpを設定します。

```php:application/config/config.php
$config['composer_autoload'] = __DIR__ . '/../../../vendor/autoload.php';
```

インストールしたlog4phpを使ったライブラリを作成していきます。
まずはログ出力内容を設定します。
今回はPHPで設定していますが、LoggerAppenderDailyFileで日毎にファイルを切り替えています。

```php:application/config/log4php.php
<?php
return [
    'rootLogger' => [
        'appenders' => ['default'],
    ],
    'appenders' => [
        'default' => [
            'class' => 'LoggerAppenderDailyFile',
            'params' => [
                'file' => FCPATH . 'application/logs/my.log.%s',
            ],
            'layout' => [
                'class' => 'LoggerLayoutPattern',
                'params' => [
                    'conversionPattern' => '%date{Y-m-d H:i:s,u} [%-5level] %sessionid %msg%n%throwable',
                ]
            ]
        ]
    ]
];
```

ログ出力クラスを作成していきます。
メッセージフォーマットを独自に実装できるため、今回はホスト名を出力するようにしました。

```php:application/libraries/MY_Logger.php
<?php
class MY_Logger {
	protected $logger;
	protected $hostname;

	public function __construct()
	{
		$this->hostname = php_uname("n");
		$config = realpath(__DIR__ . "/../config/log4php.php");
		Logger::configure($config);
		$this->logger = Logger::getLogger("main");
	}

	public function fatal($message, $throwable = null)
	{
		$this->logger->fatal($this->format($message), $throwable);
	}

	public function error($message, $throwable = null)
	{
		$this->logger->error($this->format($message), $throwable);
	}

	public function warn($message, $throwable = null)
	{
		$this->logger->warn($this->format($message), $throwable);
	}

	public function info($message, $throwable = null)
	{
		$this->logger->info($this->format($message), $throwable);
	}

	public function debug($message, $throwable = null)
	{
		$this->logger->debug($this->format($message), $throwable);
	}

	public function trace($message, $throwable = null)
	{
		$this->logger->trace($this->format($message), $throwable);
	}

	protected function format($message)
	{
		return $this->hostname . ' ' . $message;
	}
}
```

作成したライブラリをautoloadに登録します。

```php:application/config/autoload.php
$autoload['libraries'] = array('my_logger');
```

これでコントローラークラスなどからログ出力ができるようになりました。
ログは運用を見据えると必須の仕組みです。未知の障害を見据えてきちんとログを取るように習慣づけましょう。