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\Processor;
13
 
14
use Monolog\Logger;
15
use Psr\Log\LogLevel;
16
 
17
/**
18
 * Injects line/file:class/function where the log message came from
19
 *
20
 * Warning: This only works if the handler processes the logs directly.
21
 * If you put the processor on a handler that is behind a FingersCrossedHandler
22
 * for example, the processor will only be called once the trigger level is reached,
23
 * and all the log records will have the same file/line/.. data from the call that
24
 * triggered the FingersCrossedHandler.
25
 *
26
 * @author Jordi Boggiano <j.boggiano@seld.be>
27
 *
28
 * @phpstan-import-type Level from \Monolog\Logger
29
 * @phpstan-import-type LevelName from \Monolog\Logger
30
 */
31
class IntrospectionProcessor implements ProcessorInterface
32
{
33
    /** @var int */
34
    private $level;
35
    /** @var string[] */
36
    private $skipClassesPartials;
37
    /** @var int */
38
    private $skipStackFramesCount;
39
    /** @var string[] */
40
    private $skipFunctions = [
41
        'call_user_func',
42
        'call_user_func_array',
43
    ];
44
 
45
    /**
46
     * @param string|int $level               The minimum logging level at which this Processor will be triggered
47
     * @param string[]   $skipClassesPartials
48
     *
49
     * @phpstan-param Level|LevelName|LogLevel::* $level
50
     */
51
    public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
52
    {
53
        $this->level = Logger::toMonologLevel($level);
54
        $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials);
55
        $this->skipStackFramesCount = $skipStackFramesCount;
56
    }
57
 
58
    /**
59
     * {@inheritDoc}
60
     */
61
    public function __invoke(array $record): array
62
    {
63
        // return if the level is not high enough
64
        if ($record['level'] < $this->level) {
65
            return $record;
66
        }
67
 
68
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
69
 
70
        // skip first since it's always the current method
71
        array_shift($trace);
72
        // the call_user_func call is also skipped
73
        array_shift($trace);
74
 
75
        $i = 0;
76
 
77
        while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
78
            if (isset($trace[$i]['class'])) {
79
                foreach ($this->skipClassesPartials as $part) {
80
                    if (strpos($trace[$i]['class'], $part) !== false) {
81
                        $i++;
82
 
83
                        continue 2;
84
                    }
85
                }
86
            } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) {
87
                $i++;
88
 
89
                continue;
90
            }
91
 
92
            break;
93
        }
94
 
95
        $i += $this->skipStackFramesCount;
96
 
97
        // we should have the call source now
98
        $record['extra'] = array_merge(
99
            $record['extra'],
100
            [
101
                'file'      => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null,
102
                'line'      => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null,
103
                'class'     => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
104
                'callType'  => isset($trace[$i]['type']) ? $trace[$i]['type'] : null,
105
                'function'  => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
106
            ]
107
        );
108
 
109
        return $record;
110
    }
111
 
112
    /**
113
     * @param array[] $trace
114
     */
115
    private function isTraceClassOrSkippedFunction(array $trace, int $index): bool
116
    {
117
        if (!isset($trace[$index])) {
118
            return false;
119
        }
120
 
121
        return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions);
122
    }
123
}