• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

The-oGlow / ezlogging / 26412564711

25 May 2026 05:33PM UTC coverage: 95.506%. Remained the same
26412564711

push

github

ollily
Merge branch 'develop' of https://github.com/The-oGlow/ezlogging into develop

170 of 178 relevant lines covered (95.51%)

14.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/src/Monolog/Processor/PaddingProcessor.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of ezlogging
7
 *
8
 * (c) 2025 Oliver Glowa, coding.glowa.com
9
 *
10
 * This source file is subject to the Apache-2.0 license that is bundled
11
 * with this source code in the file LICENSE.
12
 */
13

14
namespace Monolog\Processor;
15

16
use Monolog\Logger;
17

18
/**
19
 * Class PaddingProcessor.
20
 *
21
 * Use Introspection from @see IntrospectionProcessor.
22
 *
23
 * @see     IntrospectionProcessor
24
 *
25
 * @phpstan-import-type Level from \Monolog\Logger
26
 * @phpstan-import-type LevelName from \Monolog\Logger
27
 *
28
 * @phpstan-type Record array<mixed,mixed>
29
 */
30
class PaddingProcessor implements ProcessorInterface
31
{
32
    private int $level;
33

34
    /** @var array<string> */
35
    private array $skipClassesPartials;
36

37
    private int $skipStackFramesCount;
38

39
    /** @var array<string> */
40
    private array $skipFunctions = [
41
        'call_user_func',
42
        'call_user_func_array',
43
    ];
44

45
    /**
46
     * @param mixed         $level                The minimum logging level at which this Processor will be triggered
47
     * @param array<string> $skipClassesPartials
48
     * @param int           $skipStackFramesCount
49
     *
50
     * @SuppressWarnings("PHPMD.StaticAccess")
51
     */
52
    public function __construct(mixed $level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
22✔
53
    {
54
        $this->level                = Logger::toMonologLevel($level);
22✔
55
        $this->skipClassesPartials  = array_merge(
22✔
56
            [
22✔
57
                'Monolog\\',
22✔
58
            ],
22✔
59
            $skipClassesPartials
22✔
60
        );
22✔
61
        $this->skipStackFramesCount = $skipStackFramesCount;
22✔
62
    }
63

64
    /**
65
     * @param array $record A record
66
     *
67
     * @phpstan-param Record $record A record
68
     *
69
     * @return array The processed record
70
     *
71
     * @phpstan-return Record
72
     *
73
     * @phpstan-ignore method.childReturnType
74
     */
75
    #[\Override]
76
    public function __invoke(array $record): array
3✔
77
    {
78
        $record                   = $this->__invokeIntrospection($record);
3✔
79
        $record['level_name_pad'] = str_pad($record['level_name'], 8, ' ', STR_PAD_RIGHT);
3✔
80

81
        return $record;
3✔
82
    }
83

84
    /**
85
     * @param array<mixed,mixed> $record
86
     *
87
     * @return array<mixed,mixed>
88
     */
89
    private function __invokeIntrospection(array $record): array // NOSONAR: php:S100
3✔
90
    {
91
        // return if the level is not high enough
92
        if ($record['level'] < $this->level) {
3✔
93
            return $record;
×
94
        }
95

96
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
3✔
97

98
        // skip first since it's always the current method
99
        array_shift($trace);
3✔
100
        // the call_user_func call is also skipped
101
        array_shift($trace);
3✔
102

103
        $index = 0;
3✔
104

105
        while ($this->isTraceClassOrSkippedFunction($trace, $index)) {
3✔
106
            if (isset($trace[$index]['class'])) {
3✔
107
                foreach ($this->skipClassesPartials as $part) {
3✔
108
                    if (str_contains($trace[$index]['class'], $part)) {
3✔
109
                        $index++;
3✔
110

111
                        continue 2;
3✔
112
                    }
113
                }
114
            } elseif (in_array($trace[$index]['function'], $this->skipFunctions, true)) {
×
115
                $index++;
×
116

117
                continue;
×
118
            } else {
119
                break;
×
120
            }
121
            break;
3✔
122
        }
123

124
        $index += $this->skipStackFramesCount;
3✔
125

126
        // we should have the call source now
127
        if ($index > 0 && $index < count($trace)) {
3✔
128
            $curTrace  = $trace[$index];
3✔
129
            $prevTrace = $trace[$index - 1];
3✔
130
            $xDetails  = [
3✔
131
                'xFile'     => $prevTrace['file'] ?? null,
3✔
132
                'xLine'     => $prevTrace['line'] ?? null,
3✔
133
                'xClass'    => $curTrace['class'] ?? null,
3✔
134
                'xCallType' => $curTrace['type'] ?? null,
3✔
135
                'xFunction' => $curTrace['function'],
3✔
136
            ];
3✔
137
            $record    = array_merge($record, $xDetails);
3✔
138
        }
139

140
        return $record;
3✔
141
    }
142

143
    /**
144
     * @param array<mixed,mixed> $trace
145
     * @param int                $index
146
     *
147
     * @return bool
148
     */
149
    private function isTraceClassOrSkippedFunction(array $trace, int $index): bool
3✔
150
    {
151
        if (!isset($trace[$index])) {
3✔
152
            return false;
×
153
        }
154

155
        return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions, true);
3✔
156
    }
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc