PHPでよく使われるMonologのHandlerの書き方
基本
Monolog は 各種 Handler を追加することで、ログの出力先を追加・変更する事が出来る仕組みになっている。
Handlerを追加する際には pushHandler
メソドを利用する。
$monolog->pushHandler($handler);
似たようなメソドにsetHandler
メソドがあるが、これは既存のハンドラセットを配列で置き換えるもの。
$monolog->setHandler([$handler]);
Handler について
Handler は \Monolog\Handler\HandlerInterface
を継承する事が求められるが、
コレを実装するのは何かと手間なので、自分でHandlerを作成する時には\Monolog\Handler\AbstractHandler
を実装すると良い。
\Monolog\Handler\AbstractHandler
はhandle(array $record)
の実装が必要で、
通常はこの中でエラーレベルによるハンドラ実行有無の判定を行い、戻り値としてbool型の$bubbling
を返す。
$bubbling
がtrueの場合、Monolog はスタックに続く他のhandlerの起動を棄却する。
シンプルなhandlerの例としては
がわかりやすい。
また 単純にwrite(array $record)
のみを実行すれば足る\Monolog\Handler\AbstractProcessingHandler
も用意されている。
標準出力に書き込む
Herokuとかで必要な奴
$handler = new StreamHandler('php://stdout',Logger::WARNING);
$monolog->pushHandler($handler);
return $log;
Databaseに書き込む
PDOHandlerの例がドキュメントに記載されている。
<?php
use Monolog\Logger;
use Monolog\Handler\AbstractProcessingHandler;
class PDOHandler extends AbstractProcessingHandler
{
private $initialized = false;
private $pdo;
private $statement;
public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
{
$this->pdo = $pdo;
parent::__construct($level, $bubble);
}
protected function write(array $record)
{
if (!$this->initialized) {
$this->initialize();
}
$this->statement->execute(array(
'channel' => $record['channel'],
'level' => $record['level'],
'message' => $record['formatted'],
'time' => $record['datetime']->format('U'),
));
}
private function initialize()
{
$this->pdo->exec(
'CREATE TABLE IF NOT EXISTS monolog '
.'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
);
$this->statement = $this->pdo->prepare(
'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
);
$this->initialized = true;
}
}