3 Monolog is fully extensible, allowing you to adapt your logger to your needs.
5 ## Writing your own handler
7 Monolog provides many built-in handlers. But if the one you need does not
8 exist, you can write it and use it in your logger. The only requirement is
9 to implement `Monolog\Handler\HandlerInterface`.
11 Let's write a PDOHandler to log records to a database. We will extend the
12 abstract class provided by Monolog to keep things DRY.
18 use Monolog\Handler\AbstractProcessingHandler;
20 class PDOHandler extends AbstractProcessingHandler
22 private $initialized = false;
26 public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
29 parent::__construct($level, $bubble);
32 protected function write(array $record)
34 if (!$this->initialized) {
38 $this->statement->execute(array(
39 'channel' => $record['channel'],
40 'level' => $record['level'],
41 'message' => $record['formatted'],
42 'time' => $record['datetime']->format('U'),
46 private function initialize()
49 'CREATE TABLE IF NOT EXISTS monolog '
50 .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
52 $this->statement = $this->pdo->prepare(
53 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
56 $this->initialized = true;
61 You can now use this handler in your logger:
66 $logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')));
68 // You can now use your logger
69 $logger->addInfo('My logger is now ready');
72 The `Monolog\Handler\AbstractProcessingHandler` class provides most of the
73 logic needed for the handler, including the use of processors and the formatting
74 of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``).
76 ← [Utility classes](03-utilities.md)