PluginProbe
DecaLog / 3.0.2
DecaLog v3.0.2
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / processors / class-introspectionprocessor.php

class-introspectionprocessor.php in DecaLog 3.0.2, at includes/processors/class-introspectionprocessor.php

148 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1);
2 /**
3 * PHP introspection records processing
4 *
5 * Adds PHP specific record, after removing unneeded traces.
6 *
7 * @package Processors
8 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
9 * @since 2.4.0
10 */
11
12 namespace Decalog\Processor;
13
14 use Decalog\System\PHP;
15 use Monolog\Logger;
16 use Monolog\Processor\ProcessorInterface;
17
18 /**
19 * Define the backtrace processor functionality.
20 *
21 * Adds backtrace specific record.
22 *
23 * @package Processors
24 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
25 * @since 2.4.0
26 */
27 class IntrospectionProcessor implements ProcessorInterface {
28
29 /**
30 * Minimum logging level.
31 *
32 * @since 2.4.0
33 * @var integer $level Minimum logging level.
34 */
35 private $level;
36
37 /**
38 * Classes to exclude.
39 *
40 * @since 2.4.0
41 * @var array $skip_classes List of class partials.
42 */
43 private $skip_classes = [
44 'Monolog\\',
45 'Decalog\\',
46 'DecaLog\\',
47 'System\\Logger',
48 'Feature\\DecaLog',
49 'Feature\\Capture',
50 ];
51
52 /**
53 * Functions to exclude.
54 *
55 * @since 2.4.0
56 * @var array $skip_functions List of functions.
57 */
58 private $skip_functions = [
59 'call_user_func',
60 'call_user_func_array',
61 ];
62
63 /**
64 * Initializes the class and set its properties.
65 *
66 * @param string|int $level The minimum logging level at which this Processor will be triggered
67 * @since 2.4.0
68 */
69 public function __construct( $level = Logger::DEBUG ) {
70 $this->level = Logger::toMonologLevel( $level );
71 }
72
73 /**
74 * Invocation of the processor.
75 *
76 * @param array $record Array or added records.
77 * @return array The modified records.
78 * @since 2.4.0
79 */
80 public function __invoke( array $record ): array {
81 if ( $record['level'] < $this->level ) {
82 return $record;
83 }
84 if ( array_key_exists( 'context', $record ) && array_key_exists( 'phase', $record['context'] ) && 'bootstrap' === (string) $record['context']['phase'] ) {
85 $file = null;
86 $line = null;
87 if ( isset( $record['message'] ) && preg_match( '/ at `\.\/(.*):([0-9]*)`\./iU', $record['message'], $matches ) ) {
88 $file = $matches[1];
89 $line = $matches[2];
90 }
91 $record['extra'] = array_merge(
92 $record['extra'],
93 [
94 'file' => $file,
95 'line' => $line,
96 'class' => null,
97 'function' => null,
98 ]
99 );
100 return $record;
101 }
102 // phpcs:ignore
103 $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
104 array_shift( $trace );
105 array_shift( $trace );
106 $i = 0;
107 while ( $this->is_skipped( $trace, $i ) ) {
108 if ( isset( $trace[ $i ]['class'] ) ) {
109 foreach ( $this->skip_classes as $part ) {
110 if ( strpos( $trace[ $i ]['class'], $part ) !== false ) {
111 $i++;
112 continue 2;
113 }
114 }
115 } elseif ( in_array( $trace[ $i ]['function'], $this->skip_functions, true ) ) {
116 $i++;
117 continue;
118 }
119 break;
120 }
121 $record['extra'] = array_merge(
122 $record['extra'],
123 [
124 'file' => $trace[ $i - 1 ]['file'] ?? null,
125 'line' => $trace[ $i - 1 ]['line'] ?? null,
126 'class' => $trace[ $i ]['class'] ?? null,
127 'function' => $trace[ $i ]['function'] ?? null,
128 ]
129 );
130 return $record;
131 }
132
133 /**
134 * Verify if a trace must be skipped.
135 *
136 * @param array $trace The trace to verify.
137 * @param integer $index The index of the trace to verify.
138 * @return boolean True if the record must be skipped, false otherwise.
139 * @since 2.4.0
140 */
141 private function is_skipped( array $trace, int $index ) {
142 if ( ! isset( $trace[ $index ] ) ) {
143 return false;
144 }
145 return isset( $trace[ $index ]['class'] ) || in_array( $trace[ $index ]['function'], $this->skip_functions, true );
146 }
147 }
148