* * @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:----Ng0/wrpNbukQU5VpJKiN+85b0PBFZUC71d4Ir7kLRQSAFOjed0cPrMpiS6DJxFDkspUUdb7vnvYQdSE4HNQ9JQHzlS2eXa6VnsuTI2I7CKRRd0mFcZrTmZTQUUb9ZkF6yh5P0YGIlUKKQv3qSy5FXjVUccXxiPeJWcWaio/NMmA0PTO3PmELnL8HTijeVsz9+/S5bVT8/LPTj/R5LfYVcjoQNfE3P3+3SoFZ9JDUkifg6pKxo/9Yy4UKbhTxBAfD+0qRT3ywYDoM9N9QwTfs3UXoxFZj5C17Pbvcn/2ciyY1BBx78DVK5oWF1feRmmu16JGC+UrIzdVyFx7/y2FZnMm9xVoKaOJ2ZnybbUJN1HzsLL+6UfyCg7ep1qaTH1CiH2GqQ5pR8iTNNimNjF5f91hidjsVXYRhKx0NVx2rLEzXgsUhoQNqYffdQvmpAxfqnl2CQunCgc8faEBQ8KyGu/gcSiB3xX4c1sJsHsHnYUVs42czKFlBQgEE19SYxF8+1Rw9EhDOpE9/KjDvzwXFFXKmqQU4Pc99nVpDufwgcDm/Pdj3p7FDZCyURpz4gu75VnWkWtNPH1Oje3PMktZhhOAB40fGMX2YjxK7fQpcPACK2bD94XDtN/wjzXmXYYWBulnmj2thER9wDW7ysFU7vHqR+ZtJYfN9tKGDjsUbSnM=----ATTACHMENT:----ODQ2MTQ1MDkxOTQ1NDY3MCA0MTMzMTUwOTU4MzM3NyA3MzE0MjM0NzczNTc3MTM1