diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index 14c0e5882d015..0da84bd616c93 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.1 +--- + + * Add support for Monolog 3 + 6.0 --- diff --git a/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php new file mode 100644 index 0000000000000..08cd70983b3ba --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Formatter/CompatibilityFormatter.php @@ -0,0 +1,57 @@ + + * + * 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; + + /** + * {@inheritdoc} + */ + 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; + + /** + * {@inheritdoc} + */ + 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 5b04c4a62434f..b8ed640e9c4aa 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -13,6 +13,7 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\Stub; @@ -24,9 +25,13 @@ * * @author Tobias Schultze * @author Grégoire Pineau + * + * @final since Symfony 6.1 */ 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'; @@ -98,11 +103,11 @@ public function formatBatch(array $records): mixed return $records; } - /** - * {@inheritdoc} - */ - public function format(array $record): mixed + private function doFormat(array|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'])) { diff --git a/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php index e745afec13650..92cf6c3e887b4 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/VarDumperFormatter.php @@ -12,13 +12,18 @@ namespace Symfony\Bridge\Monolog\Formatter; use Monolog\Formatter\FormatterInterface; +use Monolog\LogRecord; use Symfony\Component\VarDumper\Cloner\VarCloner; /** * @author Grégoire Pineau + * + * @final since Symfony 6.1 */ class VarDumperFormatter implements FormatterInterface { + use CompatibilityFormatter; + private VarCloner $cloner; public function __construct(VarCloner $cloner = null) @@ -26,11 +31,12 @@ public function __construct(VarCloner $cloner = null) $this->cloner = $cloner ?? new VarCloner(); } - /** - * {@inheritdoc} - */ - public function format(array $record): mixed + private function doFormat(array|LogRecord $record): mixed { + if ($record instanceof LogRecord) { + $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 new file mode 100644 index 0000000000000..dbeb59e4feb3b --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Handler/CompatibilityHandler.php @@ -0,0 +1,57 @@ + + * + * 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; + + /** + * {@inheritdoc} + */ + 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; + + /** + * {@inheritdoc} + */ + 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 new file mode 100644 index 0000000000000..c84c457859d52 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Handler/CompatibilityProcessingHandler.php @@ -0,0 +1,57 @@ + + * + * 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; + + /** + * {@inheritdoc} + */ + 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; + + /** + * {@inheritdoc} + */ + 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 3c911f3cfa91d..88936ff2bfbd8 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -15,6 +15,7 @@ use Monolog\Formatter\LineFormatter; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; @@ -24,6 +25,48 @@ 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; + + /** + * {@inheritdoc} + */ + 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; + + /** + * {@inheritdoc} + */ + public function isHandling(array $record): bool + { + return $this->doIsHandling($record); + } + } +} + /** * Writes logs to the console output depending on its verbosity setting. * @@ -40,9 +83,15 @@ * This mapping can be customized with the $verbosityLevelMap constructor parameter. * * @author Tobias Schultze + * + * @final since Symfony 6.1 */ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscriberInterface { + use CompatibilityHandler; + use CompatibilityIsHandlingHandler; + use CompatibilityProcessingHandler; + private ?OutputInterface $output; private array $verbosityLevelMap = [ OutputInterface::VERBOSITY_QUIET => Logger::ERROR, @@ -75,7 +124,7 @@ public function __construct(OutputInterface $output = null, bool $bubble = true, /** * {@inheritdoc} */ - public function isHandling(array $record): bool + private function doIsHandling(array|LogRecord $record): bool { return $this->updateLevel() && parent::isHandling($record); } @@ -83,7 +132,7 @@ public function isHandling(array $record): bool /** * {@inheritdoc} */ - public function handle(array $record): bool + private function doHandle(array|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) @@ -141,10 +190,7 @@ public static function getSubscribedEvents(): array ]; } - /** - * {@inheritdoc} - */ - protected function write(array $record): void + private function doWrite(array|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()); diff --git a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php index 86af1d21bd02d..18e64d23e1584 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php @@ -16,7 +16,10 @@ use Monolog\Handler\AbstractHandler; use Monolog\Handler\FormattableHandlerTrait; use Monolog\Handler\ProcessableHandlerTrait; +use Monolog\Level; +use Monolog\LevelName; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Component\HttpClient\HttpClient; use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -39,9 +42,13 @@ * stack is recommended. * * @author Grégoire Pineau + * + * @final since Symfony 6.1 */ class ElasticsearchLogstashHandler extends AbstractHandler { + use CompatibilityHandler; + use FormattableHandlerTrait; use ProcessableHandlerTrait; @@ -54,7 +61,7 @@ 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 = Logger::DEBUG, bool $bubble = true) + public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, string|int|Level|LevelName $level = Logger::DEBUG, bool $bubble = true) { if (!interface_exists(HttpClientInterface::class)) { throw new \LogicException(sprintf('The "%s" handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__)); @@ -67,7 +74,7 @@ public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $ $this->responses = new \SplObjectStorage(); } - public function handle(array $record): bool + private function doHandle(array|LogRecord $record): bool { if (!$this->isHandling($record)) { return false; diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php index fc78f2dc32c49..da48f08933289 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Monolog\Handler\FingersCrossed; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use Monolog\LogRecord; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -41,7 +42,7 @@ public function __construct( } } - public function isHandlerActivated(array $record): bool + public function isHandlerActivated(array|LogRecord $record): bool { $isActivated = $this->inner->isHandlerActivated($record); diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php index 808d863cec663..b825ef81164f9 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Monolog\Handler\FingersCrossed; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use Monolog\LogRecord; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -34,7 +35,7 @@ public function __construct( $this->exclude = '{('.implode('|', $excludedUrls).')}i'; } - public function isHandlerActivated(array $record): bool + public function isHandlerActivated(array|LogRecord $record): bool { $isActivated = $this->inner->isHandlerActivated($record); diff --git a/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php index f0446b09f3169..25a0e1d04f176 100644 --- a/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php @@ -15,19 +15,26 @@ use Monolog\Formatter\HtmlFormatter; use Monolog\Formatter\LineFormatter; use Monolog\Handler\AbstractProcessingHandler; +use Monolog\Level; +use Monolog\LevelName; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Email; /** * @author Alexander Borisov + * + * @final since Symfony 6.1 */ class MailerHandler extends AbstractProcessingHandler { + use CompatibilityProcessingHandler; + private MailerInterface $mailer; private \Closure|Email $messageTemplate; - public function __construct(MailerInterface $mailer, callable|Email $messageTemplate, string|int $level = Logger::DEBUG, bool $bubble = true) + public function __construct(MailerInterface $mailer, callable|Email $messageTemplate, string|int|Level|LevelName $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); @@ -42,11 +49,21 @@ public function handleBatch(array $records): void { $messages = []; - foreach ($records as $record) { - if ($record['level'] < $this->level) { - continue; + 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); } - $messages[] = $this->processRecord($record); } if (!empty($messages)) { @@ -57,7 +74,7 @@ public function handleBatch(array $records): void /** * {@inheritdoc} */ - protected function write(array $record): void + private function doWrite(array|LogRecord $record): void { $this->send((string) $record['formatted'], [$record]); } @@ -125,7 +142,7 @@ protected function buildMessage(string $content, array $records): Email return $message; } - protected function getHighestRecord(array $records): array + protected function getHighestRecord(array $records): array|LogRecord { $highestRecord = null; foreach ($records as $record) { diff --git a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php index a129085c905e5..ecffbef254dc8 100644 --- a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php @@ -13,6 +13,7 @@ use Monolog\Handler\AbstractHandler; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Component\Notifier\Notification\Notification; use Symfony\Component\Notifier\Notifier; use Symfony\Component\Notifier\NotifierInterface; @@ -21,19 +22,23 @@ * Uses Notifier as a log handler. * * @author Fabien Potencier + * + * @final since Symfony 6.1 */ class NotifierHandler extends AbstractHandler { + use CompatibilityHandler; + private NotifierInterface $notifier; - public function __construct(NotifierInterface $notifier, string|int $level = Logger::ERROR, bool $bubble = true) + public function __construct(NotifierInterface $notifier, string|int|Level|LevelName $level = Logger::ERROR, bool $bubble = true) { $this->notifier = $notifier; parent::__construct(Logger::toMonologLevel($level) < Logger::ERROR ? Logger::ERROR : $level, $bubble); } - public function handle(array $record): bool + private function doHandle(array|LogRecord $record): bool { if (!$this->isHandling($record)) { return false; diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index b14d8e241cf13..c06828cac0b93 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -14,12 +14,20 @@ use Monolog\Formatter\FormatterInterface; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Handler\FormattableHandlerTrait; +use Monolog\Level; +use Monolog\LevelName; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter; if (trait_exists(FormattableHandlerTrait::class)) { + /** + * @final since Symfony 6.1 + */ class ServerLogHandler extends AbstractProcessingHandler { + use CompatibilityHandler; + use CompatibilityProcessingHandler; use ServerLogHandlerTrait; /** @@ -31,8 +39,13 @@ protected function getDefaultFormatter(): FormatterInterface } } } else { + /** + * @final since Symfony 6.1 + */ class ServerLogHandler extends AbstractProcessingHandler { + use CompatibilityHandler; + use CompatibilityProcessingHandler; use ServerLogHandlerTrait; /** @@ -47,6 +60,8 @@ protected function getDefaultFormatter() /** * @author Grégoire Pineau + * + * @internal since Symfony 6.1 */ trait ServerLogHandlerTrait { @@ -62,7 +77,7 @@ trait ServerLogHandlerTrait */ private $socket; - public function __construct(string $host, string|int $level = Logger::DEBUG, bool $bubble = true, array $context = []) + public function __construct(string $host, string|int|Level|LevelName $level = Logger::DEBUG, bool $bubble = true, array $context = []) { parent::__construct($level, $bubble); @@ -74,10 +89,7 @@ public function __construct(string $host, string|int $level = Logger::DEBUG, boo $this->context = stream_context_create($context); } - /** - * {@inheritdoc} - */ - public function handle(array $record): bool + private function doHandle(array|LogRecord $record): bool { if (!$this->isHandling($record)) { return false; @@ -96,7 +108,7 @@ public function handle(array $record): bool return parent::handle($record); } - protected function write(array $record): void + private function doWrite(array|LogRecord $record): void { $recordFormatted = $this->formatRecord($record); @@ -139,7 +151,7 @@ private function createSocket() return $socket; } - private function formatRecord(array $record): string + private function formatRecord(array|LogRecord $record): string { $recordFormatted = $record['formatted']; diff --git a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php index f98969700bcab..c455be29a33ec 100644 --- a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Processor; +use Monolog\LogRecord; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -19,9 +20,13 @@ * * @author Dany Maillard * @author Igor Timoshenko + * + * @internal since Symfony 6.1 */ abstract class AbstractTokenProcessor { + use CompatibilityProcessor; + /** * @var TokenStorageInterface */ @@ -36,7 +41,7 @@ abstract protected function getKey(): string; abstract protected function getToken(): ?TokenInterface; - public function __invoke(array $record): array + private function doInvoke(array|LogRecord $record): array|LogRecord { $record['extra'][$this->getKey()] = null; diff --git a/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php b/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php new file mode 100644 index 0000000000000..2f337b29febcf --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Processor/CompatibilityProcessor.php @@ -0,0 +1,51 @@ + + * + * 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 a1e1c144379ba..a5b26eacbae83 100644 --- a/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/ConsoleCommandProcessor.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Processor; +use Monolog\LogRecord; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -20,9 +21,13 @@ * Adds the current console command information to the log entry. * * @author Piotr Stankowski + * + * @final since Symfony 6.1 */ class ConsoleCommandProcessor implements EventSubscriberInterface, ResetInterface { + use CompatibilityProcessor; + private array $commandData; private bool $includeArguments; private bool $includeOptions; @@ -33,13 +38,13 @@ public function __construct(bool $includeArguments = true, bool $includeOptions $this->includeOptions = $includeOptions; } - public function __invoke(array $records) + private function doInvoke(array|LogRecord $record): array|LogRecord { - if (isset($this->commandData) && !isset($records['extra']['command'])) { - $records['extra']['command'] = $this->commandData; + if (isset($this->commandData) && !isset($record['extra']['command'])) { + $record['extra']['command'] = $this->commandData; } - return $records; + return $record; } public function reset() diff --git a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php index bca5b948c6b9b..a033d73c3b187 100644 --- a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Monolog\Processor; use Monolog\Logger; +use Monolog\LogRecord; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; @@ -19,6 +20,8 @@ class DebugProcessor implements DebugLoggerInterface, ResetInterface { + use CompatibilityProcessor; + private array $records = []; private array $errorCount = []; private ?RequestStack $requestStack; @@ -28,7 +31,7 @@ public function __construct(RequestStack $requestStack = null) $this->requestStack = $requestStack; } - public function __invoke(array $record) + private function doInvoke(array|LogRecord $record): array|LogRecord { $hash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : ''; diff --git a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php index 0bb738f378532..c9f28af084068 100644 --- a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Processor; +use Monolog\LogRecord; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -35,13 +36,13 @@ public function __construct(bool $includeParams = true) $this->reset(); } - public function __invoke(array $records): array + public function __invoke(array|LogRecord $record): array|LogRecord { - if ($this->routeData && !isset($records['extra']['requests'])) { - $records['extra']['requests'] = array_values($this->routeData); + if ($this->routeData && !isset($record['extra']['requests'])) { + $record['extra']['requests'] = array_values($this->routeData); } - return $records; + return $record; } public function reset() diff --git a/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php index 76aa7e479d0e5..bb3f6ff73d0cd 100644 --- a/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php @@ -18,6 +18,8 @@ * Adds the original security token to the log entry. * * @author Igor Timoshenko + * + * @final since Symfony 6.1 */ class SwitchUserTokenProcessor extends AbstractTokenProcessor { diff --git a/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php index 7ca212eb29770..c824ea1761efd 100644 --- a/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php @@ -18,6 +18,8 @@ * * @author Dany Maillard * @author Igor Timoshenko + * + * @final since Symfony 6.1 */ class TokenProcessor extends AbstractTokenProcessor { diff --git a/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php b/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php index 89d5bee454548..8e847c522642e 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Formatter/ConsoleFormatterTest.php @@ -12,15 +12,17 @@ namespace Symfony\Bridge\Monolog\Tests\Formatter; use Monolog\Logger; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; +use Symfony\Bridge\Monolog\Tests\RecordFactory; class ConsoleFormatterTest extends TestCase { /** * @dataProvider providerFormatTests */ - public function testFormat(array $record, $expectedMessage) + public function testFormat(array|LogRecord $record, $expectedMessage) { $formatter = new ConsoleFormatter(); self::assertSame($expectedMessage, $formatter->format($record)); @@ -28,25 +30,20 @@ public function testFormat(array $record, $expectedMessage) public function providerFormatTests(): array { - $currentDateTime = new \DateTime(); + $currentDateTime = new \DateTimeImmutable(); - return [ + $tests = [ 'record with DateTime object in datetime field' => [ - 'record' => [ - 'message' => 'test', - 'context' => [], - 'level' => Logger::WARNING, - 'level_name' => Logger::getLevelName(Logger::WARNING), - 'channel' => 'test', - 'datetime' => $currentDateTime, - 'extra' => [], - ], + 'record' => RecordFactory::create(datetime: $currentDateTime), 'expectedMessage' => sprintf( "%s WARNING [test] test\n", $currentDateTime->format(ConsoleFormatter::SIMPLE_DATE) ), ], - 'record with string in datetime field' => [ + ]; + + if (Logger::API < 3) { + $tests['record with string in datetime field'] = [ 'record' => [ 'message' => 'test', 'context' => [], @@ -57,7 +54,9 @@ public function providerFormatTests(): array 'extra' => [], ], 'expectedMessage' => "2019-01-01T00:42:00+00:00 WARNING [test] test\n", - ], - ]; + ]; + } + + return $tests; } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index d61692ed76466..f7f09c389f8a4 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; use Symfony\Bridge\Monolog\Handler\ConsoleHandler; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; @@ -41,7 +42,7 @@ public function testConstructor() public function testIsHandling() { $handler = new ConsoleHandler(); - $this->assertFalse($handler->isHandling([]), '->isHandling returns false when no output is set'); + $this->assertFalse($handler->isHandling(RecordFactory::create()), '->isHandling returns false when no output is set'); } /** @@ -56,7 +57,7 @@ public function testVerbosityMapping($verbosity, $level, $isHandling, array $map ->willReturn($verbosity) ; $handler = new ConsoleHandler($output, true, $map); - $this->assertSame($isHandling, $handler->isHandling(['level' => $level]), + $this->assertSame($isHandling, $handler->isHandling(RecordFactory::create($level)), '->isHandling returns correct value depending on console verbosity and log level' ); @@ -77,15 +78,7 @@ public function testVerbosityMapping($verbosity, $level, $isHandling, array $map ->with($log, false); $handler = new ConsoleHandler($realOutput, true, $map); - $infoRecord = [ - 'message' => 'My info message', - 'context' => [], - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'channel' => 'app', - 'datetime' => new \DateTime('2013-05-29 16:21:54'), - 'extra' => [], - ]; + $infoRecord = RecordFactory::create($level, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); $this->assertFalse($handler->handle($infoRecord), 'The handler finished handling the log.'); } @@ -123,10 +116,10 @@ public function testVerbosityChanged() ) ; $handler = new ConsoleHandler($output); - $this->assertFalse($handler->isHandling(['level' => Logger::NOTICE]), + $this->assertFalse($handler->isHandling(RecordFactory::create(Logger::NOTICE)), 'when verbosity is set to quiet, the handler does not handle the log' ); - $this->assertTrue($handler->isHandling(['level' => Logger::NOTICE]), + $this->assertTrue($handler->isHandling(RecordFactory::create(Logger::NOTICE)), 'since the verbosity of the output increased externally, the handler is now handling the log' ); } @@ -157,15 +150,7 @@ public function testWritingAndFormatting() $handler = new ConsoleHandler(null, false); $handler->setOutput($output); - $infoRecord = [ - 'message' => 'My info message', - 'context' => [], - 'level' => Logger::INFO, - 'level_name' => Logger::getLevelName(Logger::INFO), - 'channel' => 'app', - 'datetime' => new \DateTime('2013-05-29 16:21:54'), - 'extra' => [], - ]; + $infoRecord = RecordFactory::create(Logger::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 2940f0440ff8f..1074ca47d32ee 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php @@ -16,6 +16,7 @@ use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\ElasticsearchLogstashHandler; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; @@ -47,24 +48,17 @@ public function testHandle() return new MockResponse(); }; - $handler = new ElasticsearchLogstashHandlerWithHardCodedHostname('http://es:9200', 'log', new MockHttpClient($responseFactory)); + $handler = new ElasticsearchLogstashHandler('http://es:9200', 'log', new MockHttpClient($responseFactory)); + $handler->setFormatter($this->getDefaultFormatter()); - $record = [ - 'message' => 'My info message', - 'context' => [], - 'level' => Logger::INFO, - 'level_name' => Logger::getLevelName(Logger::INFO), - 'channel' => 'app', - 'datetime' => new \DateTime('2020-01-01T00:00:00+01:00'), - 'extra' => [], - ]; + $record = RecordFactory::create(Logger::INFO, 'My info message', 'app', datetime: new \DateTimeImmutable('2020-01-01T00:00:00+01:00')); $handler->handle($record); $this->assertSame(1, $callCount); } - public function testBandleBatch() + public function testHandleBatch() { $callCount = 0; $responseFactory = function ($method, $url, $options) use (&$callCount) { @@ -93,38 +87,20 @@ public function testBandleBatch() return new MockResponse(); }; - $handler = new ElasticsearchLogstashHandlerWithHardCodedHostname('http://es:9200', 'log', new MockHttpClient($responseFactory)); + $handler = new ElasticsearchLogstashHandler('http://es:9200', 'log', new MockHttpClient($responseFactory)); + $handler->setFormatter($this->getDefaultFormatter()); $records = [ - [ - 'message' => 'My info message', - 'context' => [], - 'level' => Logger::INFO, - 'level_name' => Logger::getLevelName(Logger::INFO), - 'channel' => 'app', - 'datetime' => new \DateTime('2020-01-01T00:00:00+01:00'), - 'extra' => [], - ], - [ - 'message' => 'My second message', - 'context' => [], - 'level' => Logger::WARNING, - 'level_name' => Logger::getLevelName(Logger::WARNING), - 'channel' => 'php', - 'datetime' => new \DateTime('2020-01-01T00:00:01+01:00'), - 'extra' => [], - ], + 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')), ]; $handler->handleBatch($records); $this->assertSame(1, $callCount); } -} -class ElasticsearchLogstashHandlerWithHardCodedHostname extends ElasticsearchLogstashHandler -{ - protected function getDefaultFormatter(): FormatterInterface + private function getDefaultFormatter(): FormatterInterface { // Monolog 1.X if (\defined(LogstashFormatter::class.'::V1')) { diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php index ea6931670d863..81613fe21e0e0 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php @@ -15,6 +15,7 @@ use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -58,16 +59,16 @@ public function testIsActivated($url, $record, $expected) public function isActivatedProvider(): array { return [ - ['/test', ['level' => Logger::ERROR], true], - ['/400', ['level' => Logger::ERROR, 'context' => $this->getContextException(400)], true], - ['/400/a', ['level' => Logger::ERROR, 'context' => $this->getContextException(400)], false], - ['/400/b', ['level' => Logger::ERROR, 'context' => $this->getContextException(400)], false], - ['/400/c', ['level' => Logger::ERROR, 'context' => $this->getContextException(400)], true], - ['/401', ['level' => Logger::ERROR, 'context' => $this->getContextException(401)], true], - ['/403', ['level' => Logger::ERROR, 'context' => $this->getContextException(403)], false], - ['/404', ['level' => Logger::ERROR, 'context' => $this->getContextException(404)], false], - ['/405', ['level' => Logger::ERROR, 'context' => $this->getContextException(405)], false], - ['/500', ['level' => Logger::ERROR, 'context' => $this->getContextException(500)], true], + ['/test', RecordFactory::create(Logger::ERROR), true], + ['/400', RecordFactory::create(Logger::ERROR, context: $this->getContextException(400)), true], + ['/400/a', RecordFactory::create(Logger::ERROR, context: $this->getContextException(400)), false], + ['/400/b', RecordFactory::create(Logger::ERROR, context: $this->getContextException(400)), false], + ['/400/c', RecordFactory::create(Logger::ERROR, context: $this->getContextException(400)), true], + ['/401', RecordFactory::create(Logger::ERROR, context: $this->getContextException(401)), true], + ['/403', RecordFactory::create(Logger::ERROR, context: $this->getContextException(403)), false], + ['/404', RecordFactory::create(Logger::ERROR, context: $this->getContextException(404)), false], + ['/405', RecordFactory::create(Logger::ERROR, context: $this->getContextException(405)), false], + ['/500', RecordFactory::create(Logger::ERROR, context: $this->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 95590186d55f3..f58e9afa7164e 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php @@ -13,8 +13,10 @@ use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Logger; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -24,7 +26,7 @@ class NotFoundActivationStrategyTest extends TestCase /** * @dataProvider isActivatedProvider */ - public function testIsActivated(string $url, array $record, bool $expected) + public function testIsActivated(string $url, array|LogRecord $record, bool $expected) { $requestStack = new RequestStack(); $requestStack->push(Request::create($url)); @@ -37,15 +39,15 @@ public function testIsActivated(string $url, array $record, bool $expected) public function isActivatedProvider(): array { return [ - ['/test', ['level' => Logger::DEBUG], false], - ['/foo', ['level' => Logger::DEBUG, 'context' => $this->getContextException(404)], false], - ['/baz/bar', ['level' => Logger::ERROR, 'context' => $this->getContextException(404)], false], - ['/foo', ['level' => Logger::ERROR, 'context' => $this->getContextException(404)], false], - ['/foo', ['level' => Logger::ERROR, 'context' => $this->getContextException(500)], true], - - ['/test', ['level' => Logger::ERROR], true], - ['/baz', ['level' => Logger::ERROR, 'context' => $this->getContextException(404)], true], - ['/baz', ['level' => Logger::ERROR, 'context' => $this->getContextException(500)], true], + ['/test', RecordFactory::create(Logger::DEBUG), false], + ['/foo', RecordFactory::create(Logger::DEBUG, context: $this->getContextException(404)), false], + ['/baz/bar', RecordFactory::create(Logger::ERROR, context: $this->getContextException(404)), false], + ['/foo', RecordFactory::create(Logger::ERROR, context: $this->getContextException(404)), false], + ['/foo', RecordFactory::create(Logger::ERROR, context: $this->getContextException(500)), true], + + ['/test', RecordFactory::create(Logger::ERROR), true], + ['/baz', RecordFactory::create(Logger::ERROR, context: $this->getContextException(404)), true], + ['/baz', RecordFactory::create(Logger::ERROR, context: $this->getContextException(500)), true], ]; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php index daec7676c9e99..43d5ef3cfab72 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php @@ -13,10 +13,12 @@ use Monolog\Formatter\HtmlFormatter; use Monolog\Formatter\LineFormatter; +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; @@ -91,17 +93,9 @@ public function testHtmlContent() $handler->handle($this->getRecord(Logger::WARNING, 'message')); } - protected function getRecord($level = Logger::WARNING, $message = 'test', $context = []): array + protected function getRecord($level = Logger::WARNING, $message = 'test', $context = []): array|LogRecord { - return [ - 'message' => $message, - 'context' => $context, - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'channel' => 'test', - 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))), - 'extra' => [], - ]; + return RecordFactory::create($level, $message, context: $context); } protected function getMultipleRecords(): array diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php index f5a4405f645f1..cade0b80ec9fd 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ServerLogHandlerTest.php @@ -17,6 +17,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter; use Symfony\Bridge\Monolog\Handler\ServerLogHandler; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\VarDumper\Cloner\Data; /** @@ -37,7 +38,7 @@ public function testFormatter() public function testIsHandling() { $handler = new ServerLogHandler('tcp://127.0.0.1:9999', Logger::INFO); - $this->assertFalse($handler->isHandling(['level' => Logger::DEBUG]), '->isHandling returns false when no output is set'); + $this->assertFalse($handler->isHandling(RecordFactory::create(Logger::DEBUG)), '->isHandling returns false when no output is set'); } public function testGetFormatter() @@ -54,15 +55,7 @@ public function testWritingAndFormatting() $handler = new ServerLogHandler($host, Logger::INFO, false); $handler->pushProcessor(new ProcessIdProcessor()); - $infoRecord = [ - 'message' => 'My info message', - 'context' => [], - 'level' => Logger::INFO, - 'level_name' => Logger::getLevelName(Logger::INFO), - 'channel' => 'app', - 'datetime' => new \DateTime('2013-05-29 16:21:54'), - 'extra' => [], - ]; + $infoRecord = RecordFactory::create(Logger::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/Processor/ConsoleCommandProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/ConsoleCommandProcessorTest.php index 424f9ce10d597..c824721217ca5 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/ConsoleCommandProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/ConsoleCommandProcessorTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\ConsoleCommandProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\Console\Input\InputInterface; @@ -29,7 +30,7 @@ public function testProcessor() $processor = new ConsoleCommandProcessor(); $processor->addCommandData($this->getConsoleEvent()); - $record = $processor(['extra' => []]); + $record = $processor(RecordFactory::create()); $this->assertArrayHasKey('command', $record['extra']); $this->assertEquals( @@ -43,7 +44,7 @@ public function testProcessorWithOptions() $processor = new ConsoleCommandProcessor(true, true); $processor->addCommandData($this->getConsoleEvent()); - $record = $processor(['extra' => []]); + $record = $processor(RecordFactory::create()); $this->assertArrayHasKey('command', $record['extra']); $this->assertEquals( @@ -56,8 +57,8 @@ public function testProcessorDoesNothingWhenNotInConsole() { $processor = new ConsoleCommandProcessor(true, true); - $record = $processor(['extra' => []]); - $this->assertEquals(['extra' => []], $record); + $record = $processor(RecordFactory::create()); + $this->assertEquals([], $record['extra']); } private function getConsoleEvent(): ConsoleEvent diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php index c576462d0abfe..8de9a956e7282 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php @@ -12,59 +12,35 @@ namespace Symfony\Bridge\Monolog\Tests\Processor; use Monolog\Logger; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\DebugProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; class DebugProcessorTest extends TestCase { - /** - * @dataProvider providerDatetimeFormatTests - */ - public function testDatetimeFormat(array $record, $expectedTimestamp) + public function testDatetimeFormat() { + $record = RecordFactory::create(datetime: new \DateTimeImmutable('2019-01-01T00:01:00+00:00')); $processor = new DebugProcessor(); $processor($record); $records = $processor->getLogs(); self::assertCount(1, $records); - self::assertSame($expectedTimestamp, $records[0]['timestamp']); + self::assertSame(1546300860, $records[0]['timestamp']); } - public function providerDatetimeFormatTests(): array - { - $record = $this->getRecord(); - - return [ - [array_merge($record, ['datetime' => new \DateTime('2019-01-01T00:01:00+00:00')]), 1546300860], - [array_merge($record, ['datetime' => '2019-01-01T00:01:00+00:00']), 1546300860], - [array_merge($record, ['datetime' => 'foo']), false], - ]; - } - - /** - * @dataProvider providerDatetimeRfc3339FormatTests - */ - public function testDatetimeRfc3339Format(array $record, $expectedTimestamp) + public function testDatetimeRfc3339Format() { + $record = RecordFactory::create(datetime: new \DateTimeImmutable('2019-01-01T00:01:00+00:00')); $processor = new DebugProcessor(); $processor($record); $records = $processor->getLogs(); self::assertCount(1, $records); - self::assertSame($expectedTimestamp, $records[0]['timestamp_rfc3339']); - } - - public function providerDatetimeRfc3339FormatTests(): array - { - $record = $this->getRecord(); - - return [ - [array_merge($record, ['datetime' => new \DateTime('2019-01-01T00:01:00+00:00')]), '2019-01-01T00:01:00.000+00:00'], - [array_merge($record, ['datetime' => '2019-01-01T00:01:00+00:00']), '2019-01-01T00:01:00.000+00:00'], - [array_merge($record, ['datetime' => 'foo']), false], - ]; + self::assertSame('2019-01-01T00:01:00.000+00:00', $records[0]['timestamp_rfc3339']); } public function testDebugProcessor() @@ -123,16 +99,8 @@ public function testInheritedClassCallCountErrorsWithoutArgument() $this->assertEquals(0, $debugProcessorChild->countErrors()); } - private function getRecord($level = Logger::WARNING, $message = 'test'): array + private function getRecord($level = Logger::WARNING, $message = 'test'): array|LogRecord { - return [ - 'message' => $message, - 'context' => [], - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'channel' => 'test', - 'datetime' => new \DateTime(), - 'extra' => [], - ]; + return RecordFactory::create($level, $message); } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php index 602e9db61a82d..03706d7680e11 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; @@ -33,7 +34,7 @@ public function testProcessor() $tokenStorage->method('getToken')->willReturn($switchUserToken); $processor = new SwitchUserTokenProcessor($tokenStorage); - $record = ['extra' => []]; + $record = RecordFactory::create(); $record = $processor($record); $expected = [ diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/TokenProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/TokenProcessorTest.php index 249757d562e01..603b6f2ce131e 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/TokenProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/TokenProcessorTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\TokenProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\User\InMemoryUser; @@ -31,7 +32,7 @@ public function testProcessor() $tokenStorage->method('getToken')->willReturn($token); $processor = new TokenProcessor($tokenStorage); - $record = ['extra' => []]; + $record = RecordFactory::create(); $record = $processor($record); $this->assertArrayHasKey('token', $record['extra']); diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php index 9b70b4bbfbc25..3ae74658097de 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php @@ -12,8 +12,10 @@ namespace Symfony\Bridge\Monolog\Tests\Processor; use Monolog\Logger; +use Monolog\LogRecord; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Processor\WebProcessor; +use Symfony\Bridge\Monolog\Tests\RecordFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -94,17 +96,9 @@ private function createRequestEvent(array $additionalServerParameters = []): arr return [$event, $server]; } - private function getRecord(int $level = Logger::WARNING, string $message = 'test'): array + private function getRecord(int $level = Logger::WARNING, string $message = 'test'): array|LogRecord { - return [ - 'message' => $message, - 'context' => [], - 'level' => $level, - 'level_name' => Logger::getLevelName($level), - 'channel' => 'test', - 'datetime' => new \DateTime(), - 'extra' => [], - ]; + return RecordFactory::create($level, $message); } private function isExtraFieldsSupported() diff --git a/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php b/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php new file mode 100644 index 0000000000000..8f7b5a1f78357 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Tests/RecordFactory.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Tests; + +use Monolog\Logger; +use Monolog\LogRecord; + +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 + { + $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, + ]; + } +} diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 040ec44353576..025d54a48398d 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=8.1", - "monolog/monolog": "^1.25.1|^2", + "monolog/monolog": "^1.25.1|^2|^3", "symfony/service-contracts": "^1.1|^2|^3", "symfony/http-kernel": "^5.4|^6.0" }, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy