includeStackTraces = $includeStackTraces; $this->traceDepth = $traceDepth; } /** * Verarbeitet einen Log-Record und extrahiert Exception-Informationen */ public function processRecord(LogRecord $record): LogRecord { $context = $record->getContext(); // Prüfen, ob eine Exception im Kontext vorhanden ist if (isset($context['exception']) && $context['exception'] instanceof \Throwable) { $exception = $context['exception']; $exceptionData = $this->formatException($exception); // Exception-Daten zu Extra-Daten hinzufügen $record->addExtra('exception', $exceptionData); } return $record; } /** * Formatiert eine Exception für das Logging */ private function formatException(\Throwable $exception): array { $result = [ 'class' => get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), 'file' => $exception->getFile(), 'line' => $exception->getLine(), ]; // Stack-Trace hinzufügen, wenn aktiviert if ($this->includeStackTraces) { $result['trace'] = $this->formatTrace($exception); } // Bei verschachtelten Exceptions auch die vorherige Exception formatieren if ($exception->getPrevious()) { $result['previous'] = $this->formatException($exception->getPrevious()); } return $result; } /** * Formatiert den Stack-Trace einer Exception */ private function formatTrace(\Throwable $exception): array { $trace = $exception->getTrace(); $result = []; // Tiefe begrenzen $trace = array_slice($trace, 0, $this->traceDepth); foreach ($trace as $frame) { $entry = [ 'file' => $frame['file'] ?? 'unknown', 'line' => $frame['line'] ?? 0, ]; if (isset($frame['function'])) { $function = ''; if (isset($frame['class'])) { $function .= $frame['class'] . $frame['type']; } $function .= $frame['function']; $entry['function'] = $function; } $result[] = $entry; } return $result; } /** * Gibt die Priorität des Processors zurück */ public function getPriority(): int { return self::PRIORITY; } /** * Gibt einen eindeutigen Namen für den Processor zurück */ public function getName(): string { return 'exception'; } }