vendor/sentry/sentry/src/Monolog/Handler.php line 21

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sentry\Monolog;
  4. use Monolog\Handler\AbstractProcessingHandler;
  5. use Monolog\Logger;
  6. use Monolog\LogRecord;
  7. use Sentry\Event;
  8. use Sentry\EventHint;
  9. use Sentry\State\HubInterface;
  10. use Sentry\State\Scope;
  11. /**
  12.  * This Monolog handler logs every message to a Sentry's server using the given
  13.  * hub instance.
  14.  *
  15.  * @author Stefano Arlandini <sarlandini@alice.it>
  16.  */
  17. final class Handler extends AbstractProcessingHandler
  18. {
  19.     use CompatibilityProcessingHandlerTrait;
  20.     private const CONTEXT_EXCEPTION_KEY 'exception';
  21.     /**
  22.      * @var HubInterface
  23.      */
  24.     private $hub;
  25.     /**
  26.      * @var bool
  27.      */
  28.     private $fillExtraContext;
  29.     /**
  30.      * {@inheritdoc}
  31.      *
  32.      * @param HubInterface $hub The hub to which errors are reported
  33.      */
  34.     public function __construct(HubInterface $hub$level Logger::DEBUGbool $bubble truebool $fillExtraContext false)
  35.     {
  36.         parent::__construct($level$bubble);
  37.         $this->hub $hub;
  38.         $this->fillExtraContext $fillExtraContext;
  39.     }
  40.     /**
  41.      * @param array<string, mixed>|LogRecord $record
  42.      */
  43.     protected function doWrite($record): void
  44.     {
  45.         $event Event::createEvent();
  46.         $event->setLevel(self::getSeverityFromLevel($record['level']));
  47.         $event->setMessage($record['message']);
  48.         $event->setLogger(sprintf('monolog.%s'$record['channel']));
  49.         $hint = new EventHint();
  50.         if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) {
  51.             $hint->exception $record['context']['exception'];
  52.         }
  53.         $this->hub->withScope(function (Scope $scope) use ($record$event$hint): void {
  54.             $scope->setExtra('monolog.channel'$record['channel']);
  55.             $scope->setExtra('monolog.level'$record['level_name']);
  56.             $monologContextData $this->getMonologContextData($record['context']);
  57.             if ([] !== $monologContextData) {
  58.                 $scope->setExtra('monolog.context'$monologContextData);
  59.             }
  60.             $monologExtraData $this->getMonologExtraData($record['extra']);
  61.             if ([] !== $monologExtraData) {
  62.                 $scope->setExtra('monolog.extra'$monologExtraData);
  63.             }
  64.             $this->hub->captureEvent($event$hint);
  65.         });
  66.     }
  67.     /**
  68.      * @param mixed[] $context
  69.      *
  70.      * @return mixed[]
  71.      */
  72.     private function getMonologContextData(array $context): array
  73.     {
  74.         if (!$this->fillExtraContext) {
  75.             return [];
  76.         }
  77.         $contextData = [];
  78.         foreach ($context as $key => $value) {
  79.             // We skip the `exception` field because it goes in its own context
  80.             if (self::CONTEXT_EXCEPTION_KEY === $key) {
  81.                 continue;
  82.             }
  83.             $contextData[$key] = $value;
  84.         }
  85.         return $contextData;
  86.     }
  87.     /**
  88.      * @param mixed[] $context
  89.      *
  90.      * @return mixed[]
  91.      */
  92.     private function getMonologExtraData(array $context): array
  93.     {
  94.         if (!$this->fillExtraContext) {
  95.             return [];
  96.         }
  97.         $extraData = [];
  98.         foreach ($context as $key => $value) {
  99.             $extraData[$key] = $value;
  100.         }
  101.         return $extraData;
  102.     }
  103. }