From 18724f128fdf285fff12f352ee5bbcbb267b28e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 24 Jul 2023 18:22:13 +0200 Subject: [PATCH] [MonologBridge] Remove support for monolog < 3 --- UPGRADE-7.0.md | 5 ++ composer.json | 2 +- src/Symfony/Bridge/Monolog/CHANGELOG.md | 5 ++ .../Monolog/Command/ServerLogCommand.php | 17 ++++- .../Formatter/CompatibilityFormatter.php | 51 --------------- .../Monolog/Formatter/ConsoleFormatter.php | 61 ++++++++---------- .../Monolog/Formatter/VarDumperFormatter.php | 8 +-- .../Monolog/Handler/CompatibilityHandler.php | 51 --------------- .../CompatibilityProcessingHandler.php | 51 --------------- .../Bridge/Monolog/Handler/ConsoleHandler.php | 64 ++++--------------- .../Handler/ElasticsearchLogstashHandler.php | 13 +--- .../HttpCodeActivationStrategy.php | 8 +-- .../NotFoundActivationStrategy.php | 8 +-- .../Bridge/Monolog/Handler/MailerHandler.php | 31 +++------ .../Monolog/Handler/NotifierHandler.php | 18 +++--- .../Monolog/Handler/ServerLogHandler.php | 44 +++---------- .../Processor/AbstractTokenProcessor.php | 10 ++- .../Processor/CompatibilityProcessor.php | 51 --------------- .../Processor/ConsoleCommandProcessor.php | 8 +-- .../Monolog/Processor/DebugProcessor.php | 36 ++++------- .../Monolog/Processor/RouteProcessor.php | 6 +- .../Tests/Formatter/ConsoleFormatterTest.php | 4 +- .../Tests/Handler/ConsoleHandlerTest.php | 35 +++++----- .../ElasticsearchLogstashHandlerTest.php | 12 ++-- .../HttpCodeActivationStrategyTest.php | 28 ++++---- .../NotFoundActivationStrategyTest.php | 22 +++---- .../Tests/Handler/MailerHandlerTest.php | 24 +++---- .../Tests/Handler/ServerLogHandlerTest.php | 10 +-- .../Bridge/Monolog/Tests/LoggerTest.php | 2 +- .../Tests/Processor/DebugProcessorTest.php | 13 ++-- .../Tests/Processor/RouteProcessorTest.php | 25 +++++--- .../Tests/Processor/WebProcessorTest.php | 4 +- .../Bridge/Monolog/Tests/RecordFactory.php | 36 ++++------- src/Symfony/Bridge/Monolog/composer.json | 2 +- 34 files changed, 230 insertions(+), 535 deletions(-) delete mode 100644 src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php delete mode 100644 src/Symfony/Bridge/Monolog/Handler/CompatibilityHandler.php delete mode 100644 src/Symfony/Bridge/Monolog/Handler/CompatibilityProcessingHandler.php delete mode 100644 src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php diff --git a/UPGRADE-7.0.md b/UPGRADE-7.0.md index 54bf4c1ce1d7b..de7d3d682440d 100644 --- a/UPGRADE-7.0.md +++ b/UPGRADE-7.0.md @@ -185,6 +185,11 @@ Mime * Remove `Email::attachPart()` method, use `Email::addPart()` instead * Require explicit argument when calling `Message::setBody()` +MonologBridge +------------- + + * Drop support for monolog < 3.0 + PropertyAccess -------------- diff --git a/composer.json b/composer.json index b91c622653603..799d35ebad2b4 100644 --- a/composer.json +++ b/composer.json @@ -135,7 +135,7 @@ "guzzlehttp/promises": "^1.4", "league/html-to-markdown": "^5.0", "masterminds/html5": "^2.7.2", - "monolog/monolog": "^1.25.1|^2", + "monolog/monolog": "^3.0", "nyholm/psr7": "^1.0", "pda/pheanstalk": "^4.0", "php-http/discovery": "^1.15", diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index d0480252cb8ee..7cd25461b90f7 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.0 +--- + + * Drop support for monolog < 3.0 + 6.4 --- diff --git a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php index fe24cdda5dee2..6aae6156bb7fd 100644 --- a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php +++ b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php @@ -13,7 +13,8 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Handler\HandlerInterface; -use Monolog\Logger; +use Monolog\Level; +use Monolog\LogRecord; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; use Symfony\Bridge\Monolog\Handler\ConsoleHandler; use Symfony\Component\Console\Attribute\AsCommand; @@ -86,7 +87,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->handler = new ConsoleHandler($output, true, [ - OutputInterface::VERBOSITY_NORMAL => Logger::DEBUG, + OutputInterface::VERBOSITY_NORMAL => Level::Debug, ]); $this->handler->setFormatter(new ConsoleFormatter([ @@ -153,6 +154,18 @@ private function displayLog(OutputInterface $output, int $clientId, array $recor $logBlock = sprintf(' ', self::BG_COLOR[$clientId % 8]); $output->write($logBlock); + $record = new LogRecord( + $record['datetime'], + $record['channel'], + Level::fromValue($record['level']), + $record['message'], + // We wrap context and extra, because they have been already dumped. + // So they are instance of Symfony\Component\VarDumper\Cloner\Data + // But LogRecord expects array + ['data' => $record['context']], + ['data' => $record['extra']], + ); + $this->handler->handle($record); } } diff --git a/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php deleted file mode 100644 index aa374445b08c2..0000000000000 --- a/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Monolog\Formatter; - -use Monolog\Logger; -use Monolog\LogRecord; - -if (Logger::API >= 3) { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityFormatter - { - abstract private function doFormat(array|LogRecord $record): mixed; - - public function format(LogRecord $record): mixed - { - return $this->doFormat($record); - } - } -} else { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityFormatter - { - abstract private function doFormat(array|LogRecord $record): mixed; - - public function format(array $record): mixed - { - return $this->doFormat($record); - } - } -} diff --git a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php index 430bfaffd00f0..c0ca68cfeaccd 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -12,7 +12,7 @@ namespace Symfony\Bridge\Monolog\Formatter; use Monolog\Formatter\FormatterInterface; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\VarDumper\Cloner\Data; @@ -28,20 +28,18 @@ */ final class ConsoleFormatter implements FormatterInterface { - use CompatibilityFormatter; - public const SIMPLE_FORMAT = "%datetime% %start_tag%%level_name%%end_tag% [%channel%] %message%%context%%extra%\n"; public const SIMPLE_DATE = 'H:i:s'; private const LEVEL_COLOR_MAP = [ - Logger::DEBUG => 'fg=white', - Logger::INFO => 'fg=green', - Logger::NOTICE => 'fg=blue', - Logger::WARNING => 'fg=cyan', - Logger::ERROR => 'fg=yellow', - Logger::CRITICAL => 'fg=red', - Logger::ALERT => 'fg=red', - Logger::EMERGENCY => 'fg=white;bg=red', + Level::Debug->value => 'fg=white', + Level::Info->value => 'fg=green', + Level::Notice->value => 'fg=blue', + Level::Warning->value => 'fg=cyan', + Level::Error->value => 'fg=yellow', + Level::Critical->value => 'fg=red', + Level::Alert->value => 'fg=red', + Level::Emergency->value => 'fg=white;bg=red', ]; private array $options; @@ -98,34 +96,31 @@ public function formatBatch(array $records): mixed return $records; } - private function doFormat(array|LogRecord $record): mixed + public function format(LogRecord $record): mixed { - if ($record instanceof LogRecord) { - $record = $record->toArray(); - } $record = $this->replacePlaceHolder($record); - if (!$this->options['ignore_empty_context_and_extra'] || !empty($record['context'])) { - $context = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($record['context']); + if (!$this->options['ignore_empty_context_and_extra'] || !empty($record->context)) { + $context = $record->context; + $context = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($context); } else { $context = ''; } - if (!$this->options['ignore_empty_context_and_extra'] || !empty($record['extra'])) { - $extra = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($record['extra']); + if (!$this->options['ignore_empty_context_and_extra'] || !empty($record->extra)) { + $extra = $record->extra; + $extra = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($extra); } else { $extra = ''; } $formatted = strtr($this->options['format'], [ - '%datetime%' => $record['datetime'] instanceof \DateTimeInterface - ? $record['datetime']->format($this->options['date_format']) - : $record['datetime'], - '%start_tag%' => sprintf('<%s>', self::LEVEL_COLOR_MAP[$record['level']]), - '%level_name%' => sprintf($this->options['level_name_format'], $record['level_name']), + '%datetime%' => $record->datetime->format($this->options['date_format']), + '%start_tag%' => sprintf('<%s>', self::LEVEL_COLOR_MAP[$record->level->value]), + '%level_name%' => sprintf($this->options['level_name_format'], $record->level->getName()), '%end_tag%' => '', - '%channel%' => $record['channel'], - '%message%' => $this->replacePlaceHolder($record)['message'], + '%channel%' => $record->channel, + '%message%' => $this->replacePlaceHolder($record)->message, '%context%' => $context, '%extra%' => $extra, ]); @@ -160,15 +155,15 @@ public function castObject(mixed $v, array $a, Stub $s, bool $isNested): array return $a; } - private function replacePlaceHolder(array $record): array + private function replacePlaceHolder(LogRecord $record): LogRecord { - $message = $record['message']; + $message = $record->message; if (!str_contains($message, '{')) { return $record; } - $context = $record['context']; + $context = $record->context; $replacements = []; foreach ($context as $k => $v) { @@ -178,9 +173,7 @@ private function replacePlaceHolder(array $record): array $replacements['{'.$k.'}'] = sprintf('%s', $v); } - $record['message'] = strtr($message, $replacements); - - return $record; + return $record->with(message: strtr($message, $replacements)); } private function dumpData(mixed $data, bool $colors = null): string @@ -195,7 +188,9 @@ private function dumpData(mixed $data, bool $colors = null): string $this->dumper->setColors($colors); } - if (!$data instanceof Data) { + if (($data['data'] ?? null) instanceof Data) { + $data = $data['data']; + } elseif (!$data instanceof Data) { $data = $this->cloner->cloneVar($data); } $data = $data->withRefHandles(false); diff --git a/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php index dd640db785415..08af56ebbc0a8 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php @@ -20,8 +20,6 @@ */ final class VarDumperFormatter implements FormatterInterface { - use CompatibilityFormatter; - private VarCloner $cloner; public function __construct(VarCloner $cloner = null) @@ -29,11 +27,9 @@ public function __construct(VarCloner $cloner = null) $this->cloner = $cloner ?? new VarCloner(); } - private function doFormat(array|LogRecord $record): mixed + public function format(LogRecord $record): mixed { - if ($record instanceof LogRecord) { - $record = $record->toArray(); - } + $record = $record->toArray(); $record['context'] = $this->cloner->cloneVar($record['context']); $record['extra'] = $this->cloner->cloneVar($record['extra']); diff --git a/src/Symfony/Bridge/Monolog/Handler/CompatibilityHandler.php b/src/Symfony/Bridge/Monolog/Handler/CompatibilityHandler.php deleted file mode 100644 index 051698f06515c..0000000000000 --- a/src/Symfony/Bridge/Monolog/Handler/CompatibilityHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Monolog\Handler; - -use Monolog\Logger; -use Monolog\LogRecord; - -if (Logger::API >= 3) { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityHandler - { - abstract private function doHandle(array|LogRecord $record): bool; - - public function handle(LogRecord $record): bool - { - return $this->doHandle($record); - } - } -} else { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityHandler - { - abstract private function doHandle(array|LogRecord $record): bool; - - public function handle(array $record): bool - { - return $this->doHandle($record); - } - } -} diff --git a/src/Symfony/Bridge/Monolog/Handler/CompatibilityProcessingHandler.php b/src/Symfony/Bridge/Monolog/Handler/CompatibilityProcessingHandler.php deleted file mode 100644 index e15a00286da83..0000000000000 --- a/src/Symfony/Bridge/Monolog/Handler/CompatibilityProcessingHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Monolog\Handler; - -use Monolog\Logger; -use Monolog\LogRecord; - -if (Logger::API >= 3) { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityProcessingHandler - { - abstract private function doWrite(array|LogRecord $record): void; - - protected function write(LogRecord $record): void - { - $this->doWrite($record); - } - } -} else { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityProcessingHandler - { - abstract private function doWrite(array|LogRecord $record): void; - - protected function write(array $record): void - { - $this->doWrite($record); - } - } -} diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index 5840bcf5bdb0e..6fcd9e88a940d 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -14,7 +14,7 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Monolog\Handler\AbstractProcessingHandler; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; use Symfony\Component\Console\ConsoleEvents; @@ -25,42 +25,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\VarDumper\Dumper\CliDumper; -if (Logger::API >= 3) { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityIsHandlingHandler - { - abstract private function doIsHandling(array|LogRecord $record): bool; - - public function isHandling(LogRecord $record): bool - { - return $this->doIsHandling($record); - } - } -} else { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityIsHandlingHandler - { - abstract private function doIsHandling(array|LogRecord $record): bool; - - public function isHandling(array $record): bool - { - return $this->doIsHandling($record); - } - } -} - /** * Writes logs to the console output depending on its verbosity setting. * @@ -80,17 +44,13 @@ public function isHandling(array $record): bool */ final class ConsoleHandler extends AbstractProcessingHandler implements EventSubscriberInterface { - use CompatibilityHandler; - use CompatibilityIsHandlingHandler; - use CompatibilityProcessingHandler; - private ?OutputInterface $output; private array $verbosityLevelMap = [ - OutputInterface::VERBOSITY_QUIET => Logger::ERROR, - OutputInterface::VERBOSITY_NORMAL => Logger::WARNING, - OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE, - OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO, - OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG, + OutputInterface::VERBOSITY_QUIET => Level::Error, + OutputInterface::VERBOSITY_NORMAL => Level::Warning, + OutputInterface::VERBOSITY_VERBOSE => Level::Notice, + OutputInterface::VERBOSITY_VERY_VERBOSE => Level::Info, + OutputInterface::VERBOSITY_DEBUG => Level::Debug, ]; private array $consoleFormatterOptions; @@ -103,7 +63,7 @@ final class ConsoleHandler extends AbstractProcessingHandler implements EventSub */ public function __construct(OutputInterface $output = null, bool $bubble = true, array $verbosityLevelMap = [], array $consoleFormatterOptions = []) { - parent::__construct(Logger::DEBUG, $bubble); + parent::__construct(Level::Debug, $bubble); $this->output = $output; if ($verbosityLevelMap) { @@ -113,12 +73,12 @@ public function __construct(OutputInterface $output = null, bool $bubble = true, $this->consoleFormatterOptions = $consoleFormatterOptions; } - private function doIsHandling(array|LogRecord $record): bool + public function isHandling(LogRecord $record): bool { return $this->updateLevel() && parent::isHandling($record); } - private function doHandle(array|LogRecord $record): bool + public function handle(LogRecord $record): bool { // we have to update the logging level each time because the verbosity of the // console output might have changed in the meantime (it is not immutable) @@ -173,10 +133,10 @@ public static function getSubscribedEvents(): array ]; } - private function doWrite(array|LogRecord $record): void + protected function write(LogRecord $record): void { // at this point we've determined for sure that we want to output the record, so use the output's own verbosity - $this->output->write((string) $record['formatted'], false, $this->output->getVerbosity()); + $this->output->write((string) $record->formatted, false, $this->output->getVerbosity()); } protected function getDefaultFormatter(): FormatterInterface @@ -209,7 +169,7 @@ private function updateLevel(): bool if (isset($this->verbosityLevelMap[$verbosity])) { $this->setLevel($this->verbosityLevelMap[$verbosity]); } else { - $this->setLevel(Logger::DEBUG); + $this->setLevel(Level::Debug); } return true; diff --git a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php index cc411e1f07088..a86ac18229178 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php @@ -17,7 +17,6 @@ use Monolog\Handler\FormattableHandlerTrait; use Monolog\Handler\ProcessableHandlerTrait; use Monolog\Level; -use Monolog\Logger; use Monolog\LogRecord; use Symfony\Component\HttpClient\HttpClient; use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; @@ -44,8 +43,6 @@ */ final class ElasticsearchLogstashHandler extends AbstractHandler { - use CompatibilityHandler; - use FormattableHandlerTrait; use ProcessableHandlerTrait; @@ -59,7 +56,7 @@ final class ElasticsearchLogstashHandler extends AbstractHandler */ private \SplObjectStorage $responses; - public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, string|int|Level $level = Logger::DEBUG, bool $bubble = true, string $elasticsearchVersion = '1.0.0') + public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, string|int|Level $level = Level::Debug, bool $bubble = true, string $elasticsearchVersion = '1.0.0') { if (!interface_exists(HttpClientInterface::class)) { throw new \LogicException(sprintf('The "%s" handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__)); @@ -73,7 +70,7 @@ public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $ $this->elasticsearchVersion = $elasticsearchVersion; } - private function doHandle(array|LogRecord $record): bool + public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; @@ -95,12 +92,6 @@ public function handleBatch(array $records): void protected function getDefaultFormatter(): FormatterInterface { - // Monolog 1.X - if (\defined(LogstashFormatter::class.'::V1')) { - return new LogstashFormatter('application', null, null, 'ctxt_', LogstashFormatter::V1); - } - - // Monolog 2.X return new LogstashFormatter('application'); } diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php index da48f08933289..0f7fd757e3505 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php @@ -42,18 +42,18 @@ public function __construct( } } - public function isHandlerActivated(array|LogRecord $record): bool + public function isHandlerActivated(LogRecord $record): bool { $isActivated = $this->inner->isHandlerActivated($record); if ( $isActivated - && isset($record['context']['exception']) - && $record['context']['exception'] instanceof HttpException + && isset($record->context['exception']) + && $record->context['exception'] instanceof HttpException && ($request = $this->requestStack->getMainRequest()) ) { foreach ($this->exclusions as $exclusion) { - if ($record['context']['exception']->getStatusCode() !== $exclusion['code']) { + if ($record->context['exception']->getStatusCode() !== $exclusion['code']) { continue; } diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php index b825ef81164f9..b2b78a8d56f28 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php @@ -35,15 +35,15 @@ public function __construct( $this->exclude = '{('.implode('|', $excludedUrls).')}i'; } - public function isHandlerActivated(array|LogRecord $record): bool + public function isHandlerActivated(LogRecord $record): bool { $isActivated = $this->inner->isHandlerActivated($record); if ( $isActivated - && isset($record['context']['exception']) - && $record['context']['exception'] instanceof HttpException - && 404 == $record['context']['exception']->getStatusCode() + && isset($record->context['exception']) + && $record->context['exception'] instanceof HttpException + && 404 == $record->context['exception']->getStatusCode() && ($request = $this->requestStack->getMainRequest()) ) { return !preg_match($this->exclude, $request->getPathInfo()); diff --git a/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php index 178cffeb79d9a..868bdebba668b 100644 --- a/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php @@ -16,7 +16,6 @@ use Monolog\Formatter\LineFormatter; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Level; -use Monolog\Logger; use Monolog\LogRecord; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Email; @@ -26,12 +25,10 @@ */ final class MailerHandler extends AbstractProcessingHandler { - use CompatibilityProcessingHandler; - private MailerInterface $mailer; private \Closure|Email $messageTemplate; - public function __construct(MailerInterface $mailer, callable|Email $messageTemplate, string|int|Level $level = Logger::DEBUG, bool $bubble = true) + public function __construct(MailerInterface $mailer, callable|Email $messageTemplate, string|int|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); @@ -43,21 +40,11 @@ public function handleBatch(array $records): void { $messages = []; - if (Logger::API >= 3) { - /** @var LogRecord $record */ - foreach ($records as $record) { - if ($record->level->isLowerThan($this->level)) { - continue; - } - $messages[] = $this->processRecord($record); - } - } else { - foreach ($records as $record) { - if ($record['level'] < $this->level) { - continue; - } - $messages[] = $this->processRecord($record); + foreach ($records as $record) { + if ($record->level->isLowerThan($this->level)) { + continue; } + $messages[] = $this->processRecord($record); } if ($messages) { @@ -65,9 +52,9 @@ public function handleBatch(array $records): void } } - private function doWrite(array|LogRecord $record): void + protected function write(LogRecord $record): void { - $this->send((string) $record['formatted'], [$record]); + $this->send((string) $record->formatted, [$record]); } /** @@ -132,11 +119,11 @@ protected function buildMessage(string $content, array $records): Email return $message; } - protected function getHighestRecord(array $records): array|LogRecord + protected function getHighestRecord(array $records): LogRecord { $highestRecord = null; foreach ($records as $record) { - if (null === $highestRecord || $highestRecord['level'] < $record['level']) { + if (null === $highestRecord || $highestRecord->level->isLowerThan($record->level)) { $highestRecord = $record; } } diff --git a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php index 37e98cfc6befc..7a4a1f566887e 100644 --- a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php @@ -25,18 +25,16 @@ */ final class NotifierHandler extends AbstractHandler { - use CompatibilityHandler; - private NotifierInterface $notifier; - public function __construct(NotifierInterface $notifier, string|int|Level $level = Logger::ERROR, bool $bubble = true) + public function __construct(NotifierInterface $notifier, string|int|Level $level = Level::Error, bool $bubble = true) { $this->notifier = $notifier; - parent::__construct(Logger::toMonologLevel($level) < Logger::ERROR ? Logger::ERROR : $level, $bubble); + parent::__construct(Logger::toMonologLevel($level)->isLowerThan(Level::Error) ? Level::Error : $level, $bubble); } - private function doHandle(array|LogRecord $record): bool + public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; @@ -57,13 +55,13 @@ public function handleBatch(array $records): void private function notify(array $records): void { $record = $this->getHighestRecord($records); - if (($record['context']['exception'] ?? null) instanceof \Throwable) { - $notification = Notification::fromThrowable($record['context']['exception']); + if (($record->context['exception'] ?? null) instanceof \Throwable) { + $notification = Notification::fromThrowable($record->context['exception']); } else { - $notification = new Notification($record['message']); + $notification = new Notification($record->message); } - $notification->importanceFromLogLevelName(Logger::getLevelName($record['level'])); + $notification->importanceFromLogLevelName($record->level->getName()); $this->notifier->send($notification, ...$this->notifier->getAdminRecipients()); } @@ -72,7 +70,7 @@ private function getHighestRecord(array $records): array|LogRecord { $highestRecord = null; foreach ($records as $record) { - if (null === $highestRecord || $highestRecord['level'] < $record['level']) { + if (null === $highestRecord || $highestRecord->level->isLowerThan($record->level)) { $highestRecord = $record; } } diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index 66b3c7d11bc10..440afa7943f91 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -13,44 +13,16 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Handler\AbstractProcessingHandler; -use Monolog\Handler\FormattableHandlerTrait; use Monolog\Level; -use Monolog\Logger; use Monolog\LogRecord; use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter; -if (trait_exists(FormattableHandlerTrait::class)) { - final class ServerLogHandler extends AbstractProcessingHandler - { - use CompatibilityHandler; - use CompatibilityProcessingHandler; - use ServerLogHandlerTrait; - - protected function getDefaultFormatter(): FormatterInterface - { - return new VarDumperFormatter(); - } - } -} else { - final class ServerLogHandler extends AbstractProcessingHandler - { - use CompatibilityHandler; - use CompatibilityProcessingHandler; - use ServerLogHandlerTrait; - - protected function getDefaultFormatter() - { - return new VarDumperFormatter(); - } - } -} - /** * @author Grégoire Pineau * * @internal */ -trait ServerLogHandlerTrait +final class ServerLogHandler extends AbstractProcessingHandler { private string $host; @@ -64,7 +36,7 @@ trait ServerLogHandlerTrait */ private $socket; - public function __construct(string $host, string|int|Level $level = Logger::DEBUG, bool $bubble = true, array $context = []) + public function __construct(string $host, string|int|Level $level = Level::Debug, bool $bubble = true, array $context = []) { parent::__construct($level, $bubble); @@ -76,7 +48,7 @@ public function __construct(string $host, string|int|Level $level = Logger::DEBU $this->context = stream_context_create($context); } - private function doHandle(array|LogRecord $record): bool + public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; @@ -95,7 +67,7 @@ private function doHandle(array|LogRecord $record): bool return parent::handle($record); } - private function doWrite(array|LogRecord $record): void + protected function write(LogRecord $record): void { $recordFormatted = $this->formatRecord($record); @@ -134,13 +106,13 @@ private function createSocket() return $socket; } - private function formatRecord(array|LogRecord $record): string + private function formatRecord(LogRecord $record): string { - $recordFormatted = $record['formatted']; + $recordFormatted = $record->formatted; foreach (['log_uuid', 'uuid', 'uid'] as $key) { - if (isset($record['extra'][$key])) { - $recordFormatted['log_id'] = $record['extra'][$key]; + if (isset($record->extra[$key])) { + $recordFormatted['log_id'] = $record->extra[$key]; break; } } diff --git a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php index 5d92298fea6fc..2f8e278a98591 100644 --- a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php @@ -25,8 +25,6 @@ */ abstract class AbstractTokenProcessor { - use CompatibilityProcessor; - public function __construct( protected TokenStorageInterface $tokenStorage, ) { @@ -36,17 +34,17 @@ abstract protected function getKey(): string; abstract protected function getToken(): ?TokenInterface; - private function doInvoke(array|LogRecord $record): array|LogRecord + public function __invoke(LogRecord $record): LogRecord { - $record['extra'][$this->getKey()] = null; + $record->extra[$this->getKey()] = null; if (null !== $token = $this->getToken()) { - $record['extra'][$this->getKey()] = [ + $record->extra[$this->getKey()] = [ 'authenticated' => method_exists($token, 'isAuthenticated') ? $token->isAuthenticated(false) : (bool) $token->getUser(), 'roles' => $token->getRoleNames(), ]; - $record['extra'][$this->getKey()]['user_identifier'] = $token->getUserIdentifier(); + $record->extra[$this->getKey()]['user_identifier'] = $token->getUserIdentifier(); } return $record; diff --git a/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php b/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php deleted file mode 100644 index 2f337b29febcf..0000000000000 --- a/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Monolog\Processor; - -use Monolog\Logger; -use Monolog\LogRecord; - -if (Logger::API >= 3) { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityProcessor - { - abstract private function doInvoke(array|LogRecord $record): array|LogRecord; - - public function __invoke(LogRecord $record): LogRecord - { - return $this->doInvoke($record); - } - } -} else { - /** - * The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records. - * - * @author Jordi Boggiano - * - * @internal - */ - trait CompatibilityProcessor - { - abstract private function doInvoke(array|LogRecord $record): array|LogRecord; - - public function __invoke(array $record): array - { - return $this->doInvoke($record); - } - } -} diff --git a/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php b/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php index 9b157cd7f2ef0..e2f4b59511ddb 100644 --- a/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php @@ -24,8 +24,6 @@ */ final class ConsoleCommandProcessor implements EventSubscriberInterface, ResetInterface { - use CompatibilityProcessor; - private array $commandData; private bool $includeArguments; private bool $includeOptions; @@ -36,10 +34,10 @@ public function __construct(bool $includeArguments = true, bool $includeOptions $this->includeOptions = $includeOptions; } - private function doInvoke(array|LogRecord $record): array|LogRecord + public function __invoke(LogRecord $record): LogRecord { - if (isset($this->commandData) && !isset($record['extra']['command'])) { - $record['extra']['command'] = $this->commandData; + if (isset($this->commandData) && !isset($record->extra['command'])) { + $record->extra['command'] = $this->commandData; } return $record; diff --git a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php index 698d44539c686..a551ac5fa25b2 100644 --- a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php @@ -11,7 +11,7 @@ namespace Symfony\Bridge\Monolog\Processor; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -20,8 +20,6 @@ class DebugProcessor implements DebugLoggerInterface, ResetInterface { - use CompatibilityProcessor; - private array $records = []; private array $errorCount = []; private ?RequestStack $requestStack; @@ -31,38 +29,26 @@ public function __construct(RequestStack $requestStack = null) $this->requestStack = $requestStack; } - private function doInvoke(array|LogRecord $record): array|LogRecord + public function __invoke(LogRecord $record): LogRecord { $key = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_id($request) : ''; - $timestampRfc3339 = false; - if ($record['datetime'] instanceof \DateTimeInterface) { - $timestamp = $record['datetime']->getTimestamp(); - $timestampRfc3339 = $record['datetime']->format(\DateTimeInterface::RFC3339_EXTENDED); - } elseif (false !== $timestamp = strtotime($record['datetime'])) { - $timestampRfc3339 = (new \DateTimeImmutable($record['datetime']))->format(\DateTimeInterface::RFC3339_EXTENDED); - } - $this->records[$key][] = [ - 'timestamp' => $timestamp, - 'timestamp_rfc3339' => $timestampRfc3339, - 'message' => $record['message'], - 'priority' => $record['level'], - 'priorityName' => $record['level_name'], - 'context' => $record['context'], - 'channel' => $record['channel'] ?? '', + 'timestamp' => $record->datetime->getTimestamp(), + 'timestamp_rfc3339' => $record->datetime->format(\DateTimeInterface::RFC3339_EXTENDED), + 'message' => $record->message, + 'priority' => $record->level->value, + 'priorityName' => $record->level->getName(), + 'context' => $record->context, + 'channel' => $record->channel ?? '', ]; if (!isset($this->errorCount[$key])) { $this->errorCount[$key] = 0; } - switch ($record['level']) { - case Logger::ERROR: - case Logger::CRITICAL: - case Logger::ALERT: - case Logger::EMERGENCY: - ++$this->errorCount[$key]; + if ($record->level->isHigherThan(Level::Warning)) { + ++$this->errorCount[$key]; } return $record; diff --git a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php index bec88e3ed0e14..c5b238d18e35a 100644 --- a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php @@ -36,10 +36,10 @@ public function __construct(bool $includeParams = true) $this->reset(); } - public function __invoke(array|LogRecord $record): array|LogRecord + public function __invoke(LogRecord $record): LogRecord { - if ($this->routeData && !isset($record['extra']['requests'])) { - $record['extra']['requests'] = array_values($this->routeData); + if ($this->routeData && !isset($record->extra['requests'])) { + $record->extra['requests'] = array_values($this->routeData); } return $record; diff --git a/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php b/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php index bf754f435e734..db0d1150d0f8c 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php @@ -47,8 +47,8 @@ public static function providerFormatTests(): array 'record' => [ 'message' => 'test', 'context' => [], - 'level' => Logger::WARNING, - 'level_name' => Logger::getLevelName(Logger::WARNING), + 'level' => Level::Warning, + 'level_name' => Logger::getLevelName(Level::Warning), 'channel' => 'test', 'datetime' => '2019-01-01T00:42:00+00:00', 'extra' => [], diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index b2f8a79f965a7..5656447afbd70 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler; +use Monolog\Level; use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; @@ -85,21 +86,21 @@ public function testVerbosityMapping($verbosity, $level, $isHandling, array $map public static function provideVerbosityMappingTests() { return [ - [OutputInterface::VERBOSITY_QUIET, Logger::ERROR, true], - [OutputInterface::VERBOSITY_QUIET, Logger::WARNING, false], - [OutputInterface::VERBOSITY_NORMAL, Logger::WARNING, true], - [OutputInterface::VERBOSITY_NORMAL, Logger::NOTICE, false], - [OutputInterface::VERBOSITY_VERBOSE, Logger::NOTICE, true], - [OutputInterface::VERBOSITY_VERBOSE, Logger::INFO, false], - [OutputInterface::VERBOSITY_VERY_VERBOSE, Logger::INFO, true], - [OutputInterface::VERBOSITY_VERY_VERBOSE, Logger::DEBUG, false], - [OutputInterface::VERBOSITY_DEBUG, Logger::DEBUG, true], - [OutputInterface::VERBOSITY_DEBUG, Logger::EMERGENCY, true], - [OutputInterface::VERBOSITY_NORMAL, Logger::NOTICE, true, [ - OutputInterface::VERBOSITY_NORMAL => Logger::NOTICE, + [OutputInterface::VERBOSITY_QUIET, Level::Error, true], + [OutputInterface::VERBOSITY_QUIET, Level::Warning, false], + [OutputInterface::VERBOSITY_NORMAL, Level::Warning, true], + [OutputInterface::VERBOSITY_NORMAL, Level::Notice, false], + [OutputInterface::VERBOSITY_VERBOSE, Level::Notice, true], + [OutputInterface::VERBOSITY_VERBOSE, Level::Info, false], + [OutputInterface::VERBOSITY_VERY_VERBOSE, Level::Info, true], + [OutputInterface::VERBOSITY_VERY_VERBOSE, Level::Debug, false], + [OutputInterface::VERBOSITY_DEBUG, Level::Debug, true], + [OutputInterface::VERBOSITY_DEBUG, Level::Emergency, true], + [OutputInterface::VERBOSITY_NORMAL, Level::Notice, true, [ + OutputInterface::VERBOSITY_NORMAL => Level::Notice, ]], - [OutputInterface::VERBOSITY_DEBUG, Logger::NOTICE, true, [ - OutputInterface::VERBOSITY_NORMAL => Logger::NOTICE, + [OutputInterface::VERBOSITY_DEBUG, Level::Notice, true, [ + OutputInterface::VERBOSITY_NORMAL => Level::Notice, ]], ]; } @@ -116,10 +117,10 @@ public function testVerbosityChanged() ) ; $handler = new ConsoleHandler($output); - $this->assertFalse($handler->isHandling(RecordFactory::create(Logger::NOTICE)), + $this->assertFalse($handler->isHandling(RecordFactory::create(Level::Notice)), 'when verbosity is set to quiet, the handler does not handle the log' ); - $this->assertTrue($handler->isHandling(RecordFactory::create(Logger::NOTICE)), + $this->assertTrue($handler->isHandling(RecordFactory::create(Level::Notice)), 'since the verbosity of the output increased externally, the handler is now handling the log' ); } @@ -150,7 +151,7 @@ public function testWritingAndFormatting() $handler = new ConsoleHandler(null, false); $handler->setOutput($output); - $infoRecord = RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); + $infoRecord = RecordFactory::create(Level::Info, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); $this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.'); } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php index 3e8dde6d4bbda..37f1e5f7a4ae1 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php @@ -13,7 +13,7 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LogstashFormatter; -use Monolog\Logger; +use Monolog\Level; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\ElasticsearchLogstashHandler; use Symfony\Bridge\Monolog\Tests\RecordFactory; @@ -51,7 +51,7 @@ public function testHandle() $handler = new ElasticsearchLogstashHandler('http://es:9200', 'log', new MockHttpClient($responseFactory)); $handler->setFormatter($this->getDefaultFormatter()); - $record = RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')); + $record = RecordFactory::create(Level::Info, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')); $handler->handle($record); @@ -84,10 +84,10 @@ public function testHandleWithElasticsearch8() return new MockResponse(); }; - $handler = new ElasticsearchLogstashHandler('http://es:9200', 'log', new MockHttpClient($responseFactory), Logger::DEBUG, true, '8.0.0'); + $handler = new ElasticsearchLogstashHandler('http://es:9200', 'log', new MockHttpClient($responseFactory), Level::Debug, true, '8.0.0'); $handler->setFormatter($this->getDefaultFormatter()); - $record = RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')); + $record = RecordFactory::create(Level::Info, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')); $handler->handle($record); @@ -127,8 +127,8 @@ public function testHandleBatch() $handler->setFormatter($this->getDefaultFormatter()); $records = [ - RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')), - RecordFactory::create(Logger::WARNING, 'My second message', 'php', datetime: new \DateTimeImmutable('2020-01-01T00:00:01+01:00')), + RecordFactory::create(Level::Info, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')), + RecordFactory::create(Level::Warning, 'My second message', 'php', datetime: new \DateTimeImmutable('2020-01-01T00:00:01+01:00')), ]; $handler->handleBatch($records); diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php index 37286d39e080c..5c96b392d4521 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php @@ -12,7 +12,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler\FingersCrossed; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; -use Monolog\Logger; +use Monolog\Level; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy; use Symfony\Bridge\Monolog\Tests\RecordFactory; @@ -25,13 +25,13 @@ class HttpCodeActivationStrategyTest extends TestCase public function testExclusionsWithoutCode() { $this->expectException(\LogicException::class); - new HttpCodeActivationStrategy(new RequestStack(), [['urls' => []]], new ErrorLevelActivationStrategy(Logger::WARNING)); + new HttpCodeActivationStrategy(new RequestStack(), [['urls' => []]], new ErrorLevelActivationStrategy(Level::Warning)); } public function testExclusionsWithoutUrls() { $this->expectException(\LogicException::class); - new HttpCodeActivationStrategy(new RequestStack(), [['code' => 404]], new ErrorLevelActivationStrategy(Logger::WARNING)); + new HttpCodeActivationStrategy(new RequestStack(), [['code' => 404]], new ErrorLevelActivationStrategy(Level::Warning)); } /** @@ -50,7 +50,7 @@ public function testIsActivated($url, $record, $expected) ['code' => 405, 'urls' => []], ['code' => 400, 'urls' => ['^/400/a', '^/400/b']], ], - new ErrorLevelActivationStrategy(Logger::WARNING) + new ErrorLevelActivationStrategy(Level::Warning) ); self::assertEquals($expected, $strategy->isHandlerActivated($record)); @@ -59,16 +59,16 @@ public function testIsActivated($url, $record, $expected) public static function isActivatedProvider(): array { return [ - ['/test', RecordFactory::create(Logger::ERROR), true], - ['/400', RecordFactory::create(Logger::ERROR, context: self::getContextException(400)), true], - ['/400/a', RecordFactory::create(Logger::ERROR, context: self::getContextException(400)), false], - ['/400/b', RecordFactory::create(Logger::ERROR, context: self::getContextException(400)), false], - ['/400/c', RecordFactory::create(Logger::ERROR, context: self::getContextException(400)), true], - ['/401', RecordFactory::create(Logger::ERROR, context: self::getContextException(401)), true], - ['/403', RecordFactory::create(Logger::ERROR, context: self::getContextException(403)), false], - ['/404', RecordFactory::create(Logger::ERROR, context: self::getContextException(404)), false], - ['/405', RecordFactory::create(Logger::ERROR, context: self::getContextException(405)), false], - ['/500', RecordFactory::create(Logger::ERROR, context: self::getContextException(500)), true], + ['/test', RecordFactory::create(Level::Error), true], + ['/400', RecordFactory::create(Level::Error, context: self::getContextException(400)), true], + ['/400/a', RecordFactory::create(Level::Error, context: self::getContextException(400)), false], + ['/400/b', RecordFactory::create(Level::Error, context: self::getContextException(400)), false], + ['/400/c', RecordFactory::create(Level::Error, context: self::getContextException(400)), true], + ['/401', RecordFactory::create(Level::Error, context: self::getContextException(401)), true], + ['/403', RecordFactory::create(Level::Error, context: self::getContextException(403)), false], + ['/404', RecordFactory::create(Level::Error, context: self::getContextException(404)), false], + ['/405', RecordFactory::create(Level::Error, context: self::getContextException(405)), false], + ['/500', RecordFactory::create(Level::Error, context: self::getContextException(500)), true], ]; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php index 36c448c7df0ab..48a1347421c05 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php @@ -12,7 +12,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler\FingersCrossed; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy; @@ -31,7 +31,7 @@ public function testIsActivated(string $url, array|LogRecord $record, bool $expe $requestStack = new RequestStack(); $requestStack->push(Request::create($url)); - $strategy = new NotFoundActivationStrategy($requestStack, ['^/foo', 'bar'], new ErrorLevelActivationStrategy(Logger::WARNING)); + $strategy = new NotFoundActivationStrategy($requestStack, ['^/foo', 'bar'], new ErrorLevelActivationStrategy(Level::Warning)); self::assertEquals($expected, $strategy->isHandlerActivated($record)); } @@ -39,15 +39,15 @@ public function testIsActivated(string $url, array|LogRecord $record, bool $expe public static function isActivatedProvider(): array { return [ - ['/test', RecordFactory::create(Logger::DEBUG), false], - ['/foo', RecordFactory::create(Logger::DEBUG, context: self::getContextException(404)), false], - ['/baz/bar', RecordFactory::create(Logger::ERROR, context: self::getContextException(404)), false], - ['/foo', RecordFactory::create(Logger::ERROR, context: self::getContextException(404)), false], - ['/foo', RecordFactory::create(Logger::ERROR, context: self::getContextException(500)), true], - - ['/test', RecordFactory::create(Logger::ERROR), true], - ['/baz', RecordFactory::create(Logger::ERROR, context: self::getContextException(404)), true], - ['/baz', RecordFactory::create(Logger::ERROR, context: self::getContextException(500)), true], + ['/test', RecordFactory::create(Level::Debug), false], + ['/foo', RecordFactory::create(Level::Debug, context: self::getContextException(404)), false], + ['/baz/bar', RecordFactory::create(Level::Error, context: self::getContextException(404)), false], + ['/foo', RecordFactory::create(Level::Error, context: self::getContextException(404)), false], + ['/foo', RecordFactory::create(Level::Error, context: self::getContextException(500)), true], + + ['/test', RecordFactory::create(Level::Error), true], + ['/baz', RecordFactory::create(Level::Error, context: self::getContextException(404)), true], + ['/baz', RecordFactory::create(Level::Error, context: self::getContextException(500)), true], ]; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php index a59ced55d9d36..2540cd5ba8e77 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php @@ -13,11 +13,11 @@ use Monolog\Formatter\HtmlFormatter; use Monolog\Formatter\LineFormatter; +use Monolog\Level; use Monolog\LogRecord; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\MailerHandler; -use Symfony\Bridge\Monolog\Logger; use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Email; @@ -40,7 +40,7 @@ public function testHandle() ->method('send') ->with($this->callback(fn (Email $email) => 'Alert: WARNING message' === $email->getSubject() && null === $email->getHtmlBody())) ; - $handler->handle($this->getRecord(Logger::WARNING, 'message')); + $handler->handle($this->getRecord(Level::Warning, 'message')); } public function testHandleBatch() @@ -65,11 +65,11 @@ public function testMessageCreationIsLazyWhenUsingCallback() $callback = function () { throw new \RuntimeException('Email creation callback should not have been called in this test'); }; - $handler = new MailerHandler($this->mailer, $callback, Logger::ALERT); + $handler = new MailerHandler($this->mailer, $callback, Level::Alert); $records = [ - $this->getRecord(Logger::DEBUG), - $this->getRecord(Logger::INFO), + $this->getRecord(Level::Debug), + $this->getRecord(Level::Info), ]; $handler->handleBatch($records); } @@ -83,10 +83,10 @@ public function testHtmlContent() ->method('send') ->with($this->callback(fn (Email $email) => 'Alert: WARNING message' === $email->getSubject() && null === $email->getTextBody())) ; - $handler->handle($this->getRecord(Logger::WARNING, 'message')); + $handler->handle($this->getRecord(Level::Warning, 'message')); } - protected function getRecord($level = Logger::WARNING, $message = 'test', $context = []): array|LogRecord + protected function getRecord($level = Level::Warning, $message = 'test', $context = []): array|LogRecord { return RecordFactory::create($level, $message, context: $context); } @@ -94,11 +94,11 @@ protected function getRecord($level = Logger::WARNING, $message = 'test', $conte protected function getMultipleRecords(): array { return [ - $this->getRecord(Logger::DEBUG, 'debug message 1'), - $this->getRecord(Logger::DEBUG, 'debug message 2'), - $this->getRecord(Logger::INFO, 'information'), - $this->getRecord(Logger::WARNING, 'warning'), - $this->getRecord(Logger::ERROR, 'error'), + $this->getRecord(Level::Debug, 'debug message 1'), + $this->getRecord(Level::Debug, 'debug message 2'), + $this->getRecord(Level::Info, 'information'), + $this->getRecord(Level::Warning, 'warning'), + $this->getRecord(Level::Error, 'error'), ]; } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php index cade0b80ec9fd..9d652892e3914 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php @@ -12,7 +12,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler; use Monolog\Formatter\JsonFormatter; -use Monolog\Logger; +use Monolog\Level; use Monolog\Processor\ProcessIdProcessor; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter; @@ -37,8 +37,8 @@ public function testFormatter() public function testIsHandling() { - $handler = new ServerLogHandler('tcp://127.0.0.1:9999', Logger::INFO); - $this->assertFalse($handler->isHandling(RecordFactory::create(Logger::DEBUG)), '->isHandling returns false when no output is set'); + $handler = new ServerLogHandler('tcp://127.0.0.1:9999', Level::Info); + $this->assertFalse($handler->isHandling(RecordFactory::create(Level::Debug)), '->isHandling returns false when no output is set'); } public function testGetFormatter() @@ -52,10 +52,10 @@ public function testGetFormatter() public function testWritingAndFormatting() { $host = 'tcp://127.0.0.1:9999'; - $handler = new ServerLogHandler($host, Logger::INFO, false); + $handler = new ServerLogHandler($host, Level::Info, false); $handler->pushProcessor(new ProcessIdProcessor()); - $infoRecord = RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); + $infoRecord = RecordFactory::create(Level::Info, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); $socket = stream_socket_server($host, $errno, $errstr); $this->assertIsResource($socket, sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno)); diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php index e862d780e7eb9..7ef7c6558acea 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php @@ -78,7 +78,7 @@ public function testGetLogsWithDebugProcessor2() [$record] = $logger->getLogs(); $this->assertEquals('test', $record['message']); - $this->assertEquals(Logger::INFO, $record['priority']); + $this->assertEquals(200, $record['priority']); } public function testGetLogsWithDebugProcessor3() diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php index 6e4b67e265d1d..0c9b57d245316 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php @@ -9,12 +9,13 @@ * file that was distributed with this source code. */ -namespace Symfony\Bridge\Monolog\Tests\Processor; +namespace Symfony\Bridge\Monolog; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\DebugProcessor; +use Symfony\Bridge\Monolog\Tests\Processor\ClassThatInheritDebugProcessor; use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -47,7 +48,7 @@ public function testDebugProcessor() { $processor = new DebugProcessor(); $processor(self::getRecord()); - $processor(self::getRecord(Logger::ERROR)); + $processor(self::getRecord(Level::Error)); $this->assertCount(2, $processor->getLogs()); $this->assertSame(1, $processor->countErrors()); @@ -66,7 +67,7 @@ public function testWithRequestStack() $stack = new RequestStack(); $processor = new DebugProcessor($stack); $processor(self::getRecord()); - $processor(self::getRecord(Logger::ERROR)); + $processor(self::getRecord(Level::Error)); $this->assertCount(2, $processor->getLogs()); $this->assertSame(1, $processor->countErrors()); @@ -75,7 +76,7 @@ public function testWithRequestStack() $stack->push($request); $processor(self::getRecord()); - $processor(self::getRecord(Logger::ERROR)); + $processor(self::getRecord(Level::Error)); $this->assertCount(4, $processor->getLogs()); $this->assertSame(2, $processor->countErrors()); @@ -99,7 +100,7 @@ public function testInheritedClassCallCountErrorsWithoutArgument() $this->assertEquals(0, $debugProcessorChild->countErrors()); } - private static function getRecord($level = Logger::WARNING, $message = 'test'): array|LogRecord + private static function getRecord($level = Level::Warning, $message = 'test'): LogRecord { return RecordFactory::create($level, $message); } diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/RouteProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/RouteProcessorTest.php index 6e6afa92c4409..42d54d0df2312 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/RouteProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/RouteProcessorTest.php @@ -11,8 +11,10 @@ namespace Symfony\Bridge\Monolog\Tests\Processor; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\RouteProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; @@ -31,7 +33,7 @@ public function testProcessor() $processor = new RouteProcessor(); $processor->addRouteData($this->getRequestEvent($request)); - $record = $processor(['extra' => []]); + $record = $processor($this->createRecord()); $this->assertArrayHasKey('requests', $record['extra']); $this->assertCount(1, $record['extra']['requests']); @@ -47,7 +49,7 @@ public function testProcessorWithoutParams() $processor = new RouteProcessor(false); $processor->addRouteData($this->getRequestEvent($request)); - $record = $processor(['extra' => []]); + $record = $processor($this->createRecord()); $this->assertArrayHasKey('requests', $record['extra']); $this->assertCount(1, $record['extra']['requests']); @@ -67,7 +69,7 @@ public function testProcessorWithSubRequests() $processor->addRouteData($this->getRequestEvent($mainRequest)); $processor->addRouteData($this->getRequestEvent($subRequest, HttpKernelInterface::SUB_REQUEST)); - $record = $processor(['extra' => []]); + $record = $processor($this->createRecord()); $this->assertArrayHasKey('requests', $record['extra']); $this->assertCount(2, $record['extra']['requests']); @@ -90,7 +92,7 @@ public function testFinishRequestRemovesRelatedEntry() $processor->addRouteData($this->getRequestEvent($mainRequest)); $processor->addRouteData($this->getRequestEvent($subRequest, HttpKernelInterface::SUB_REQUEST)); $processor->removeRouteData($this->getFinishRequestEvent($subRequest)); - $record = $processor(['extra' => []]); + $record = $processor($this->createRecord()); $this->assertArrayHasKey('requests', $record['extra']); $this->assertCount(1, $record['extra']['requests']); @@ -100,7 +102,7 @@ public function testFinishRequestRemovesRelatedEntry() ); $processor->removeRouteData($this->getFinishRequestEvent($mainRequest)); - $record = $processor(['extra' => []]); + $record = $processor($this->createRecord()); $this->assertArrayNotHasKey('requests', $record['extra']); } @@ -111,16 +113,16 @@ public function testProcessorWithEmptyRequest() $processor = new RouteProcessor(); $processor->addRouteData($this->getRequestEvent($request)); - $record = $processor(['extra' => []]); - $this->assertEquals(['extra' => []], $record); + $record = $processor($this->createRecord()); + $this->assertEquals($this->createRecord(), $record); } public function testProcessorDoesNothingWhenNoRequest() { $processor = new RouteProcessor(); - $record = $processor(['extra' => []]); - $this->assertEquals(['extra' => []], $record); + $record = $processor($this->createRecord()); + $this->assertEquals($this->createRecord(), $record); } private function getRequestEvent(Request $request, int $requestType = HttpKernelInterface::MAIN_REQUEST): RequestEvent @@ -154,4 +156,9 @@ private function mockRequest(array $attributes): Request return $request; } + + private function createRecord(): LogRecord + { + return RecordFactory::create(datetime: new \DateTimeImmutable('2023-07-25 00:00:00')); + } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php index 3ae74658097de..619aea0279b81 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php @@ -11,7 +11,7 @@ namespace Symfony\Bridge\Monolog\Tests\Processor; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\WebProcessor; @@ -96,7 +96,7 @@ private function createRequestEvent(array $additionalServerParameters = []): arr return [$event, $server]; } - private function getRecord(int $level = Logger::WARNING, string $message = 'test'): array|LogRecord + private function getRecord(Level $level = Level::Warning, string $message = 'test'): LogRecord { return RecordFactory::create($level, $message); } diff --git a/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php b/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php index 8f7b5a1f78357..b9bd1f6675d55 100644 --- a/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php +++ b/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php @@ -11,35 +11,21 @@ namespace Symfony\Bridge\Monolog\Tests; -use Monolog\Logger; +use Monolog\Level; use Monolog\LogRecord; +use Monolog\Logger; class RecordFactory { - public static function create(int|string $level = 'warning', string|\Stringable $message = 'test', string $channel = 'test', array $context = [], \DateTimeImmutable $datetime = new \DateTimeImmutable(), array $extra = []): LogRecord|array + public static function create(int|string|Level $level = 'warning', string|\Stringable $message = 'test', string $channel = 'test', array $context = [], \DateTimeImmutable $datetime = new \DateTimeImmutable(), array $extra = []): LogRecord { - $level = Logger::toMonologLevel($level); - - if (Logger::API >= 3) { - return new LogRecord( - message: (string) $message, - context: $context, - level: $level, - channel: $channel, - datetime: $datetime, - extra: $extra, - ); - } - - return [ - 'message' => $message, - 'context' => $context, - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'channel' => $channel, - // Monolog 1 had no support for DateTimeImmutable - 'datetime' => Logger::API >= 2 ? $datetime : \DateTime::createFromImmutable($datetime), - 'extra' => $extra, - ]; + return new LogRecord( + message: (string) $message, + context: $context, + level: Logger::toMonologLevel($level), + channel: $channel, + datetime: $datetime, + extra: $extra, + ); } } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 327080914d662..50a23a5876931 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=8.2", - "monolog/monolog": "^1.25.1|^2|^3", + "monolog/monolog": "^3", "symfony/service-contracts": "^2.5|^3", "symfony/http-kernel": "^6.4|^7.0" },