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\Formatter;
13
 
14
use MongoDB\BSON\Type;
15
use MongoDB\BSON\UTCDateTime;
16
use Monolog\Utils;
17
 
18
/**
19
 * Formats a record for use with the MongoDBHandler.
20
 *
21
 * @author Florian Plattner <me@florianplattner.de>
22
 */
23
class MongoDBFormatter implements FormatterInterface
24
{
25
    /** @var bool */
26
    private $exceptionTraceAsString;
27
    /** @var int */
28
    private $maxNestingLevel;
29
    /** @var bool */
30
    private $isLegacyMongoExt;
31
 
32
    /**
33
     * @param int  $maxNestingLevel        0 means infinite nesting, the $record itself is level 1, $record['context'] is 2
34
     * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings
35
     */
36
    public function __construct(int $maxNestingLevel = 3, bool $exceptionTraceAsString = true)
37
    {
38
        $this->maxNestingLevel = max($maxNestingLevel, 0);
39
        $this->exceptionTraceAsString = $exceptionTraceAsString;
40
 
41
        $this->isLegacyMongoExt = extension_loaded('mongodb') && version_compare((string) phpversion('mongodb'), '1.1.9', '<=');
42
    }
43
 
44
    /**
45
     * {@inheritDoc}
46
     *
47
     * @return mixed[]
48
     */
49
    public function format(array $record): array
50
    {
51
        /** @var mixed[] $res */
52
        $res = $this->formatArray($record);
53
 
54
        return $res;
55
    }
56
 
57
    /**
58
     * {@inheritDoc}
59
     *
60
     * @return array<mixed[]>
61
     */
62
    public function formatBatch(array $records): array
63
    {
64
        $formatted = [];
65
        foreach ($records as $key => $record) {
66
            $formatted[$key] = $this->format($record);
67
        }
68
 
69
        return $formatted;
70
    }
71
 
72
    /**
73
     * @param  mixed[]        $array
74
     * @return mixed[]|string Array except when max nesting level is reached then a string "[...]"
75
     */
76
    protected function formatArray(array $array, int $nestingLevel = 0)
77
    {
78
        if ($this->maxNestingLevel > 0 && $nestingLevel > $this->maxNestingLevel) {
79
            return '[...]';
80
        }
81
 
82
        foreach ($array as $name => $value) {
83
            if ($value instanceof \DateTimeInterface) {
84
                $array[$name] = $this->formatDate($value, $nestingLevel + 1);
85
            } elseif ($value instanceof \Throwable) {
86
                $array[$name] = $this->formatException($value, $nestingLevel + 1);
87
            } elseif (is_array($value)) {
88
                $array[$name] = $this->formatArray($value, $nestingLevel + 1);
89
            } elseif (is_object($value) && !$value instanceof Type) {
90
                $array[$name] = $this->formatObject($value, $nestingLevel + 1);
91
            }
92
        }
93
 
94
        return $array;
95
    }
96
 
97
    /**
98
     * @param  mixed          $value
99
     * @return mixed[]|string
100
     */
101
    protected function formatObject($value, int $nestingLevel)
102
    {
103
        $objectVars = get_object_vars($value);
104
        $objectVars['class'] = Utils::getClass($value);
105
 
106
        return $this->formatArray($objectVars, $nestingLevel);
107
    }
108
 
109
    /**
110
     * @return mixed[]|string
111
     */
112
    protected function formatException(\Throwable $exception, int $nestingLevel)
113
    {
114
        $formattedException = [
115
            'class' => Utils::getClass($exception),
116
            'message' => $exception->getMessage(),
117
            'code' => (int) $exception->getCode(),
118
            'file' => $exception->getFile() . ':' . $exception->getLine(),
119
        ];
120
 
121
        if ($this->exceptionTraceAsString === true) {
122
            $formattedException['trace'] = $exception->getTraceAsString();
123
        } else {
124
            $formattedException['trace'] = $exception->getTrace();
125
        }
126
 
127
        return $this->formatArray($formattedException, $nestingLevel);
128
    }
129
 
130
    protected function formatDate(\DateTimeInterface $value, int $nestingLevel): UTCDateTime
131
    {
132
        if ($this->isLegacyMongoExt) {
133
            return $this->legacyGetMongoDbDateTime($value);
134
        }
135
 
136
        return $this->getMongoDbDateTime($value);
137
    }
138
 
139
    private function getMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
140
    {
141
        return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000));
142
    }
143
 
144
    /**
145
     * This is needed to support MongoDB Driver v1.19 and below
146
     *
147
     * See https://github.com/mongodb/mongo-php-driver/issues/426
148
     *
149
     * It can probably be removed in 2.1 or later once MongoDB's 1.2 is released and widely adopted
150
     */
151
    private function legacyGetMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
152
    {
153
        $milliseconds = floor(((float) $value->format('U.u')) * 1000);
154
 
155
        $milliseconds = (PHP_INT_SIZE == 8) //64-bit OS?
156
            ? (int) $milliseconds
157
            : (string) $milliseconds;
158
 
159
        // @phpstan-ignore-next-line
160
        return new UTCDateTime($milliseconds);
161
    }
162
}