1<?php declare(strict_types=1);
2
3/*
4 * This file is part of the Monolog package.
5 *
6 * (c) Jordi Boggiano <j.boggiano@seld.be>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Monolog\Handler;
13
14use MongoDB\Driver\BulkWrite;
15use MongoDB\Driver\Manager;
16use MongoDB\Client;
17use Monolog\Logger;
18use Monolog\Formatter\FormatterInterface;
19use Monolog\Formatter\MongoDBFormatter;
20
21/**
22 * Logs to a MongoDB database.
23 *
24 * Usage example:
25 *
26 *   $log = new \Monolog\Logger('application');
27 *   $client = new \MongoDB\Client('mongodb://localhost:27017');
28 *   $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod');
29 *   $log->pushHandler($mongodb);
30 *
31 * The above examples uses the MongoDB PHP library's client class; however, the
32 * MongoDB\Driver\Manager class from ext-mongodb is also supported.
33 */
34class MongoDBHandler extends AbstractProcessingHandler
35{
36    /** @var \MongoDB\Collection */
37    private $collection;
38    /** @var Client|Manager */
39    private $manager;
40    /** @var string */
41    private $namespace;
42
43    /**
44     * Constructor.
45     *
46     * @param Client|Manager $mongodb    MongoDB library or driver client
47     * @param string         $database   Database name
48     * @param string         $collection Collection name
49     */
50    public function __construct($mongodb, string $database, string $collection, $level = Logger::DEBUG, bool $bubble = true)
51    {
52        if (!($mongodb instanceof Client || $mongodb instanceof Manager)) {
53            throw new \InvalidArgumentException('MongoDB\Client or MongoDB\Driver\Manager instance required');
54        }
55
56        if ($mongodb instanceof Client) {
57            $this->collection = $mongodb->selectCollection($database, $collection);
58        } else {
59            $this->manager = $mongodb;
60            $this->namespace = $database . '.' . $collection;
61        }
62
63        parent::__construct($level, $bubble);
64    }
65
66    protected function write(array $record): void
67    {
68        if (isset($this->collection)) {
69            $this->collection->insertOne($record['formatted']);
70        }
71
72        if (isset($this->manager, $this->namespace)) {
73            $bulk = new BulkWrite;
74            $bulk->insert($record["formatted"]);
75            $this->manager->executeBulkWrite($this->namespace, $bulk);
76        }
77    }
78
79    /**
80     * {@inheritDoc}
81     */
82    protected function getDefaultFormatter(): FormatterInterface
83    {
84        return new MongoDBFormatter;
85    }
86}
87