* * @phpstan-import-type Level from \Monolog\Logger * @phpstan-import-type LevelName from \Monolog\Logger */ class IntrospectionProcessor implements ProcessorInterface { /** @var int */ private $level; /** @var string[] */ private $skipClassesPartials; /** @var int */ private $skipStackFramesCount; /** @var string[] */ private $skipFunctions = [ 'call_user_func', 'call_user_func_array', ]; /** * @param string|int $level The minimum logging level at which this Processor will be triggered * @param string[] $skipClassesPartials * * @phpstan-param Level|LevelName|LogLevel::* $level */ public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0) { $this->level = Logger::toMonologLevel($level); $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials); $this->skipStackFramesCount = $skipStackFramesCount; } /** * {@inheritDoc} */ public function __invoke(array $record): array { // return if the level is not high enough if ($record['level'] < $this->level) { return $record; } $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // skip first since it's always the current method array_shift($trace); // the call_user_func call is also skipped array_shift($trace); $i = 0; while ($this->isTraceClassOrSkippedFunction($trace, $i)) { if (isset($trace[$i]['class'])) { foreach ($this->skipClassesPartials as $part) { if (strpos($trace[$i]['class'], $part) !== false) { $i++; continue 2; } } } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) { $i++; continue; } break; } $i += $this->skipStackFramesCount; // we should have the call source now $record['extra'] = array_merge( $record['extra'], [ 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, 'callType' => isset($trace[$i]['type']) ? $trace[$i]['type'] : null, 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, ] ); return $record; } /** * @param array[] $trace */ private function isTraceClassOrSkippedFunction(array $trace, int $index): bool { if (!isset($trace[$index])) { return false; } return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions); } } __halt_compiler();----SIGNATURE:----V1omaCweeHMjdwm9Ab2jdAyNww0VR5aQwqkKlIwSSjBN7ItDyPyZ6nYLXFlT8b6KW2BJo2erpwT14NKnL1LmLYswqmV4kh3+abUDNk2mZiSCC73jD0M698vuyfUVq43dJJ7A+cAp8uExIZtGjtoRcD1enpYUkQNE+/Tnqvt1cuTZ7F5TmNtIdffU/5wD+x5hkcsEWF1CxXmd+ea/u5OwO++iu+eao0dzLbWTC+rRRWX17wn/V5aA6TAHP+uS3WCUGlViJ7dqgpNC+gQNTkTVvp7KvT+2O/a5xAXq0uhi4QkTMfmjHSpY4UFKgU2wF8gBPM6jWQCsUgysZRKdGrdsg73i3Y2WcEgVXTR1cJiW8XjPB2sO+qC+4aAVWcZ4AKXjlwN2xZvp029aJ0z4P5pir8WPfoh+F39/5/4oXvpEKSPZVtU8tkMnXZzC5hrMc7kv7biHdr6Zln7nhZpp3k0m1t5tqROryE6//8cGKQuv87SNR0uxf4Knpf4ll23/hibjHsLkE8Gg1mRUg/OhH7IymtZNF8MO55kwmrejHcVEsyF+U+xswOqNiJWuMN4Jyl+NWyx5iss9+4RD0ybBcRAFpGiSn471I9xR0H9zqeq40M2c78lqxx8Wn7sWxTI5WSRhIDVrrUfvD8GAmRgD8Cal9IiImbqydFL1kJo1NthrSN4=----ATTACHMENT:----NDcwNzU3NTQyMDY3NjQ2NSA3MzgxMTI1MjA3OTY1ODUyIDk0MTgwNDg5NDMxNzY4Mw==