Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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
 
12
namespace Monolog\Handler;
13
 
14
use Monolog\Logger;
15
use Monolog\ResettableInterface;
16
use Monolog\Formatter\FormatterInterface;
17
 
18
/**
19
 * Buffers all records until closing the handler and then pass them as batch.
20
 *
21
 * This is useful for a MailHandler to send only one mail per request instead of
22
 * sending one per log message.
23
 *
24
 * @author Christophe Coevoet <stof@notk.org>
25
 *
26
 * @phpstan-import-type Record from \Monolog\Logger
27
 */
28
class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
29
{
30
    use ProcessableHandlerTrait;
31
 
32
    /** @var HandlerInterface */
33
    protected $handler;
34
    /** @var int */
35
    protected $bufferSize = 0;
36
    /** @var int */
37
    protected $bufferLimit;
38
    /** @var bool */
39
    protected $flushOnOverflow;
40
    /** @var Record[] */
41
    protected $buffer = [];
42
    /** @var bool */
43
    protected $initialized = false;
44
 
45
    /**
46
     * @param HandlerInterface $handler         Handler.
47
     * @param int              $bufferLimit     How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
48
     * @param bool             $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
49
     */
50
    public function __construct(HandlerInterface $handler, int $bufferLimit = 0, $level = Logger::DEBUG, bool $bubble = true, bool $flushOnOverflow = false)
51
    {
52
        parent::__construct($level, $bubble);
53
        $this->handler = $handler;
54
        $this->bufferLimit = $bufferLimit;
55
        $this->flushOnOverflow = $flushOnOverflow;
56
    }
57
 
58
    /**
59
     * {@inheritDoc}
60
     */
61
    public function handle(array $record): bool
62
    {
63
        if ($record['level'] < $this->level) {
64
            return false;
65
        }
66
 
67
        if (!$this->initialized) {
68
            // __destructor() doesn't get called on Fatal errors
69
            register_shutdown_function([$this, 'close']);
70
            $this->initialized = true;
71
        }
72
 
73
        if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
74
            if ($this->flushOnOverflow) {
75
                $this->flush();
76
            } else {
77
                array_shift($this->buffer);
78
                $this->bufferSize--;
79
            }
80
        }
81
 
82
        if ($this->processors) {
83
            /** @var Record $record */
84
            $record = $this->processRecord($record);
85
        }
86
 
87
        $this->buffer[] = $record;
88
        $this->bufferSize++;
89
 
90
        return false === $this->bubble;
91
    }
92
 
93
    public function flush(): void
94
    {
95
        if ($this->bufferSize === 0) {
96
            return;
97
        }
98
 
99
        $this->handler->handleBatch($this->buffer);
100
        $this->clear();
101
    }
102
 
103
    public function __destruct()
104
    {
105
        // suppress the parent behavior since we already have register_shutdown_function()
106
        // to call close(), and the reference contained there will prevent this from being
107
        // GC'd until the end of the request
108
    }
109
 
110
    /**
111
     * {@inheritDoc}
112
     */
113
    public function close(): void
114
    {
115
        $this->flush();
116
 
117
        $this->handler->close();
118
    }
119
 
120
    /**
121
     * Clears the buffer without flushing any messages down to the wrapped handler.
122
     */
123
    public function clear(): void
124
    {
125
        $this->bufferSize = 0;
126
        $this->buffer = [];
127
    }
128
 
129
    public function reset()
130
    {
131
        $this->flush();
132
 
133
        parent::reset();
134
 
135
        $this->resetProcessors();
136
 
137
        if ($this->handler instanceof ResettableInterface) {
138
            $this->handler->reset();
139
        }
140
    }
141
 
142
    /**
143
     * {@inheritDoc}
144
     */
145
    public function setFormatter(FormatterInterface $formatter): HandlerInterface
146
    {
147
        if ($this->handler instanceof FormattableHandlerInterface) {
148
            $this->handler->setFormatter($formatter);
149
 
150
            return $this;
151
        }
152
 
153
        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
154
    }
155
 
156
    /**
157
     * {@inheritDoc}
158
     */
159
    public function getFormatter(): FormatterInterface
160
    {
161
        if ($this->handler instanceof FormattableHandlerInterface) {
162
            return $this->handler->getFormatter();
163
        }
164
 
165
        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
166
    }
167
}