From cfbad7eec812e91e09b40ff85c8aa7f5c4fa2cd6 Mon Sep 17 00:00:00 2001 From: Joao Jacome Date: Tue, 21 Mar 2023 16:25:58 +0000 Subject: [PATCH 1/3] [Monolog Bridge] renamed LoggerTest to LegacyLoggerTest --- .../Monolog/Tests/{LoggerTest.php => LegacyLoggerTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Symfony/Bridge/Monolog/Tests/{LoggerTest.php => LegacyLoggerTest.php} (99%) diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php similarity index 99% rename from src/Symfony/Bridge/Monolog/Tests/LoggerTest.php rename to src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php index e862d780e7eb9..16205be6cefc7 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php @@ -18,7 +18,7 @@ use Symfony\Bridge\Monolog\Processor\DebugProcessor; use Symfony\Component\HttpFoundation\Request; -class LoggerTest extends TestCase +class LegacyLoggerTest extends TestCase { public function testGetLogsWithoutDebugProcessor() { From 8f782adfa69d43444bb80a1d69363d2f7eb26edd Mon Sep 17 00:00:00 2001 From: Joao Jacome Date: Tue, 21 Mar 2023 17:02:04 +0000 Subject: [PATCH 2/3] Updated MonologBridge\Logger so it doesn't extend Monolog\Logger This shouldn't break any BC. An adapter for the public Monolog\Logger methods has been created as a trait. The trait has been created as "deprecated", so it can be removed later. This change depends on a change in the upstream Monolog class. An MR has been opened for monolog to cover that --- src/Symfony/Bridge/Monolog/Logger.php | 134 +++++++- .../Bridge/Monolog/MonologApiTrait.php | 324 ++++++++++++++++++ .../Bridge/Monolog/Tests/LoggerTest.php | 156 +++++++++ src/Symfony/Bridge/Monolog/composer.json | 13 +- 4 files changed, 607 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Bridge/Monolog/MonologApiTrait.php create mode 100644 src/Symfony/Bridge/Monolog/Tests/LoggerTest.php diff --git a/src/Symfony/Bridge/Monolog/Logger.php b/src/Symfony/Bridge/Monolog/Logger.php index 367b3351ff102..a9509bcd0b8bb 100644 --- a/src/Symfony/Bridge/Monolog/Logger.php +++ b/src/Symfony/Bridge/Monolog/Logger.php @@ -11,8 +11,11 @@ namespace Symfony\Bridge\Monolog; +use Monolog\Handler\HandlerInterface; use Monolog\Logger as BaseLogger; +use Monolog\Processor\ProcessorInterface; use Monolog\ResettableInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Contracts\Service\ResetInterface; @@ -20,8 +23,71 @@ /** * @author Fabien Potencier */ -class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface +class Logger implements LoggerInterface, DebugLoggerInterface, ResetInterface { + use MonologApiTrait; + + /** + * @see BaseLogger::DEBUG + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const DEBUG = 100; + + /** + * @see BaseLogger::INFO + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const INFO = 200; + + /** + * @see BaseLogger::NOTICE + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually.. + */ + public const NOTICE = 250; + + /** + * @see BaseLogger::WARNING + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const WARNING = 300; + + /** + * @see BaseLogger::ERROR + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const ERROR = 400; + + /** + * @see BaseLogger::CRITICAL + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const CRITICAL = 500; + + /** + * @see BaseLogger::ALERT + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const ALERT = 550; + + /** + * @see BaseLogger::EMERGENCY + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const EMERGENCY = 600; + + /** + * @see BaseLogger::API + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public const API = 3; + + public function setLogger(BaseLogger $logger): self + { + $this->logger = $logger; + + return $this; + } + public function getLogs(Request $request = null): array { if ($logger = $this->getDebugLogger()) { @@ -54,9 +120,7 @@ public function reset(): void { $this->clear(); - if ($this instanceof ResettableInterface) { - parent::reset(); - } + $this->logger->reset(); } /** @@ -64,17 +128,8 @@ public function reset(): void */ public function removeDebugLogger() { - foreach ($this->processors as $k => $processor) { - if ($processor instanceof DebugLoggerInterface) { - unset($this->processors[$k]); - } - } - - foreach ($this->handlers as $k => $handler) { - if ($handler instanceof DebugLoggerInterface) { - unset($this->handlers[$k]); - } - } + $this->logger->removeProcessor(fn (int $key, ProcessorInterface $processor) => $processor instanceof DebugLoggerInterface); + $this->logger->removeHandler(fn (int $key, HandlerInterface $handler) => $handler instanceof DebugLoggerInterface); } /** @@ -82,13 +137,13 @@ public function removeDebugLogger() */ private function getDebugLogger(): ?DebugLoggerInterface { - foreach ($this->processors as $processor) { + foreach ($this->logger->getProcessors() as $processor) { if ($processor instanceof DebugLoggerInterface) { return $processor; } } - foreach ($this->handlers as $handler) { + foreach ($this->logger->getHandlers() as $handler) { if ($handler instanceof DebugLoggerInterface) { return $handler; } @@ -96,4 +151,49 @@ private function getDebugLogger(): ?DebugLoggerInterface return null; } + + public function emergency(\Stringable|string $message, array $context = []): void + { + $this->logger->emergency($message, $context); + } + + public function alert(\Stringable|string $message, array $context = []): void + { + $this->logger->alert($message, $context); + } + + public function critical(\Stringable|string $message, array $context = []): void + { + $this->logger->critical($message, $context); + } + + public function error(\Stringable|string $message, array $context = []): void + { + $this->logger->error($message, $context); + } + + public function warning(\Stringable|string $message, array $context = []): void + { + $this->logger->warning($message, $context); + } + + public function notice(\Stringable|string $message, array $context = []): void + { + $this->logger->notice($message, $context); + } + + public function info(\Stringable|string $message, array $context = []): void + { + $this->logger->info($message, $context); + } + + public function debug(\Stringable|string $message, array $context = []): void + { + $this->logger->debug($message, $context); + } + + public function log($level, \Stringable|string $message, array $context = []): void + { + $this->logger->log($level, $message, $context); + } } diff --git a/src/Symfony/Bridge/Monolog/MonologApiTrait.php b/src/Symfony/Bridge/Monolog/MonologApiTrait.php new file mode 100644 index 0000000000000..200792510c6da --- /dev/null +++ b/src/Symfony/Bridge/Monolog/MonologApiTrait.php @@ -0,0 +1,324 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog; + +use Monolog\Handler\HandlerInterface; +use Monolog\Level; +use Monolog\Logger as BaseLogger; +use Monolog\LogRecord; +use Monolog\Processor\ProcessorInterface; +use Closure; +use DateTimeImmutable; +use DateTimeZone; +use Throwable; + +/** + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ +trait MonologApiTrait +{ + protected BaseLogger $logger; + + /** + * @see BaseLogger::$name + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + protected string $name; + + /** + * @see BaseLogger::$handlers + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + * + * @var list + */ + protected array $handlers; + + /** + * @see BaseLogger::$processors + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + * + * @var array<(callable(LogRecord): LogRecord)|ProcessorInterface> + */ + protected array $processors; + + /** + * @see BaseLogger::$microsecondTimestamps + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + protected bool $microsecondTimestamps = true; + + /** + * @see BaseLogger::$timezone + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + protected DateTimeZone $timezone; + + /** + * @see BaseLogger::$exceptionHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + protected Closure|null $exceptionHandler = null; + + /** + * @see BaseLogger::__construct + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function __construct() // string $name, array $handlers = [], array $processors = [], DateTimeZone|null $timezone = null + { + $args = \func_get_args(); + if ([] !== $args) { + $this->logger = new BaseLogger(...$args); + } + } + + /** + * @see BaseLogger::getName + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function getName(): string + { + return $this->logger->name; + } + + /** + * @see BaseLogger::withName + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function withName(string $name): self + { + $new = clone $this; + $new->setLogger($this->logger->withName($name)); + + return $new; + } + + /** + * @see BaseLogger::pushHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function pushHandler(HandlerInterface $handler): self + { + $this->logger->pushHandler($handler); + + return $this; + } + + /** + * @see BaseLogger::popHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function popHandler(): HandlerInterface + { + return $this->logger->popHandler(); + } + + /** + * @see BaseLogger::removeHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function removeHandler(int $handlerIndex): void + { + $this->logger->removeHandler($handlerIndex); + } + + /** + * @see BaseLogger::setHandlers + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function setHandlers(array $handlers): self + { + $this->logger->setHandlers($handlers); + + return $this; + } + + /** + * @see BaseLogger::getHandlers + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function getHandlers(): array + { + return $this->logger->getHandlers(); + } + + /** + * @see BaseLogger::pushProcessor + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function pushProcessor(ProcessorInterface|callable $callback): self + { + $this->logger->pushProcessor($callback); + + return $this; + } + + /** + * @see BaseLogger::popProcessor + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function popProcessor(): callable + { + return $this->logger->popProcessor(); + } + + /** + * @see BaseLogger::removeProcessor + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function removeProcessor(int $processorIndex): void + { + $this->logger->removeProcessor($processorIndex); + } + + /** + * @see BaseLogger::getProcessors + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function getProcessors(): array + { + return $this->logger->getProcessors(); + } + + /** + * @see BaseLogger::useMicrosecondTimestamps + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function useMicrosecondTimestamps(bool $micro): self + { + $this->logger->useMicrosecondTimestamps($micro); + + return $this; + } + + /** + * @see BaseLogger::useLoggingLoopDetection + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function useLoggingLoopDetection(bool $detectCycles): self + { + $this->logger->useLoggingLoopDetection($detectCycles); + + return $this; + } + + /** + * @see BaseLogger::addRecord() + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function addRecord(int|Level $level, string $message, array $context = [], DateTimeImmutable $datetime = null): bool + { + return $this->logger->addRecord($level, $message, $context, $datetime); + } + + /** + * @see BaseLogger::close + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function close(): void + { + $this->logger->close(); + } + + /** + * @see BaseLogger::getLevelName + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public static function getLevelName(int|Level $level): string + { + return BaseLogger::getLevelName($level); + } + + /** + * @see BaseLogger::toMonologLevel + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public static function toMonologLevel(string|int|Level $level): Level + { + return BaseLogger::toMonologLevel($level); + } + + /** + * @see BaseLogger::isHandling + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function isHandling(int|string|Level $level): bool + { + return $this->logger->isHandling($level); + } + + /** + * @see BaseLogger::setExceptionHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function setExceptionHandler(Closure|null $callback): self + { + $this->logger->setExceptionHandler($callback); + + return $this; + } + + /** + * @see BaseLogger::getExceptionHandler + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function getExceptionHandler(): Closure|null + { + return $this->logger->getExceptionHandler(); + } + + /** + * @see BaseLogger::setTimezone + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function setTimezone(DateTimeZone $tz): self + { + $this->logger->setTimezone($tz); + + return $this; + } + + /** + * @see BaseLogger::getTimezone + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function getTimezone(): DateTimeZone + { + return $this->logger->getTimezone(); + } + + /** + * @see BaseLogger::handleException + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + protected function handleException(Throwable $e, LogRecord $record): void + { + $this->logger->handleException($e, $record); + } + + /** + * @see BaseLogger::__serialize + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function __serialize(): array + { + return $this->logger->__serialize(); + } + + /** + * @see BaseLogger::__unserialize + * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + */ + public function __unserialize(array $data): void + { + $this->logger->__unserialize($data); + } +} diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php new file mode 100644 index 0000000000000..a55e80157500e --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php @@ -0,0 +1,156 @@ + + * + * 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\Handler\TestHandler; +use Monolog\Logger as BaseLogger; +use Monolog\ResettableInterface; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Monolog\Logger; +use Symfony\Bridge\Monolog\Processor\DebugProcessor; +use Symfony\Component\HttpFoundation\Request; + +class LoggerTest extends TestCase +{ + public function testGetLogsWithoutDebugProcessor() + { + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger(__METHOD__, [$handler]); + $logger->setLogger($baseLogger); + + $logger->error('error message'); + $this->assertSame([], $logger->getLogs()); + } + + public function testCountErrorsWithoutDebugProcessor() + { + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger(__METHOD__, [$handler]); + $logger->setLogger($baseLogger); + + $logger->error('error message'); + $this->assertSame(0, $logger->countErrors()); + } + + public function testGetLogsWithDebugProcessor() + { + $handler = new TestHandler(); + $processor = new DebugProcessor(); + $logger = new Logger(); + $baseLogger = new BaseLogger(__METHOD__, [$handler], [$processor]); + $logger->setLogger($baseLogger); + + $logger->error('error message'); + $this->assertCount(1, $logger->getLogs()); + } + + public function testCountErrorsWithDebugProcessor() + { + $handler = new TestHandler(); + $processor = new DebugProcessor(); + $logger = new Logger(); + $baseLogger = new BaseLogger(__METHOD__, [$handler], [$processor]); + $logger->setLogger($baseLogger); + + $logger->debug('test message'); + $logger->info('test message'); + $logger->notice('test message'); + $logger->warning('test message'); + + $logger->error('test message'); + $logger->critical('test message'); + $logger->alert('test message'); + $logger->emergency('test message'); + + $this->assertSame(4, $logger->countErrors()); + } + + public function testGetLogsWithDebugProcessor2() + { + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger('test', [$handler]); + $logger->setLogger($baseLogger); + $logger->pushProcessor(new DebugProcessor()); + + $logger->info('test'); + $this->assertCount(1, $logger->getLogs()); + [$record] = $logger->getLogs(); + + $this->assertEquals('test', $record['message']); + $this->assertEquals(Logger::INFO, $record['priority']); + } + + public function testGetLogsWithDebugProcessor3() + { + $request = new Request(); + $processor = $this->createMock(DebugProcessor::class); + $processor->expects($this->once())->method('getLogs')->with($request); + $processor->expects($this->once())->method('countErrors')->with($request); + + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger('test', [$handler]); + $logger->setLogger($baseLogger); + $logger->pushProcessor($processor); + + $logger->getLogs($request); + $logger->countErrors($request); + } + + public function testClear() + { + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger('test', [$handler]); + $logger->setLogger($baseLogger); + $logger->pushProcessor(new DebugProcessor()); + + $logger->info('test'); + $logger->clear(); + + $this->assertEmpty($logger->getLogs()); + $this->assertSame(0, $logger->countErrors()); + } + + public function testReset() + { + $handler = new TestHandler(); + $logger = new Logger(); + $baseLogger = new BaseLogger('test', [$handler]); + $logger->setLogger($baseLogger); + $logger->pushProcessor(new DebugProcessor()); + + $logger->info('test'); + $logger->reset(); + + $this->assertEmpty($logger->getLogs()); + $this->assertSame(0, $logger->countErrors()); + if (class_exists(ResettableInterface::class)) { + $this->assertEmpty($handler->getRecords()); + } + } + + public function testInheritedClassCallGetLogsWithoutArgument() + { + $loggerChild = new ClassThatInheritLogger('test'); + $this->assertSame([], $loggerChild->getLogs()); + } + + public function testInheritedClassCallCountErrorsWithoutArgument() + { + $loggerChild = new ClassThatInheritLogger('test'); + $this->assertEquals(0, $loggerChild->countErrors()); + } +} diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 8fc06d8ece4e8..87a4c283f42a4 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -17,9 +17,10 @@ ], "require": { "php": ">=8.1", - "monolog/monolog": "^1.25.1|^2|^3", + "monolog/monolog": "dev-remove-handlers-processors", "symfony/service-contracts": "^2.5|^3", - "symfony/http-kernel": "^5.4|^6.0" + "symfony/http-kernel": "^5.4|^6.0", + "psr/log": "^2.0 || ^3.0" }, "require-dev": { "symfony/console": "^5.4|^6.0", @@ -46,5 +47,11 @@ "/Tests/" ] }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "repositories": [ + { + "type": "vcs", + "url": "git@github.com:joaojacome/monolog" + } + ] } From 9e46c79797eac9ca788bd0bc7d81264d4226701d Mon Sep 17 00:00:00 2001 From: Joao Jacome Date: Tue, 28 Mar 2023 10:30:21 +0100 Subject: [PATCH 3/3] Rolling back Symfony Logger extending Monolog\Logger; Added deprecation messages --- src/Symfony/Bridge/Monolog/Logger.php | 20 ++++++------ .../Bridge/Monolog/MonologApiTrait.php | 31 ++++++++++--------- .../Bridge/Monolog/Tests/LegacyLoggerTest.php | 12 +++++++ src/Symfony/Bridge/Monolog/composer.json | 3 +- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Logger.php b/src/Symfony/Bridge/Monolog/Logger.php index a9509bcd0b8bb..8826b7c8eae3c 100644 --- a/src/Symfony/Bridge/Monolog/Logger.php +++ b/src/Symfony/Bridge/Monolog/Logger.php @@ -23,7 +23,7 @@ /** * @author Fabien Potencier */ -class Logger implements LoggerInterface, DebugLoggerInterface, ResetInterface +class Logger extends BaseLogger implements LoggerInterface, DebugLoggerInterface, ResetInterface { use MonologApiTrait; @@ -152,47 +152,47 @@ private function getDebugLogger(): ?DebugLoggerInterface return null; } - public function emergency(\Stringable|string $message, array $context = []): void + public function emergency($message, array $context = []): void { $this->logger->emergency($message, $context); } - public function alert(\Stringable|string $message, array $context = []): void + public function alert($message, array $context = []): void { $this->logger->alert($message, $context); } - public function critical(\Stringable|string $message, array $context = []): void + public function critical($message, array $context = []): void { $this->logger->critical($message, $context); } - public function error(\Stringable|string $message, array $context = []): void + public function error($message, array $context = []): void { $this->logger->error($message, $context); } - public function warning(\Stringable|string $message, array $context = []): void + public function warning($message, array $context = []): void { $this->logger->warning($message, $context); } - public function notice(\Stringable|string $message, array $context = []): void + public function notice($message, array $context = []): void { $this->logger->notice($message, $context); } - public function info(\Stringable|string $message, array $context = []): void + public function info($message, array $context = []): void { $this->logger->info($message, $context); } - public function debug(\Stringable|string $message, array $context = []): void + public function debug($message, array $context = []): void { $this->logger->debug($message, $context); } - public function log($level, \Stringable|string $message, array $context = []): void + public function log($level, $message, array $context = []): void { $this->logger->log($level, $message, $context); } diff --git a/src/Symfony/Bridge/Monolog/MonologApiTrait.php b/src/Symfony/Bridge/Monolog/MonologApiTrait.php index 200792510c6da..9034d00d38a00 100644 --- a/src/Symfony/Bridge/Monolog/MonologApiTrait.php +++ b/src/Symfony/Bridge/Monolog/MonologApiTrait.php @@ -32,7 +32,7 @@ trait MonologApiTrait * @see BaseLogger::$name * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - protected string $name; + protected $name; /** * @see BaseLogger::$handlers @@ -40,7 +40,7 @@ trait MonologApiTrait * * @var list */ - protected array $handlers; + protected $handlers; /** * @see BaseLogger::$processors @@ -48,34 +48,35 @@ trait MonologApiTrait * * @var array<(callable(LogRecord): LogRecord)|ProcessorInterface> */ - protected array $processors; + protected $processors; /** * @see BaseLogger::$microsecondTimestamps * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - protected bool $microsecondTimestamps = true; + protected $microsecondTimestamps = true; /** * @see BaseLogger::$timezone * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - protected DateTimeZone $timezone; + protected $timezone; /** * @see BaseLogger::$exceptionHandler * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - protected Closure|null $exceptionHandler = null; + protected $exceptionHandler = null; /** * @see BaseLogger::__construct - * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. + * @deprecated Creating an instance of Monolog\Logger through this method is deprecated. Please use ::setLogger */ public function __construct() // string $name, array $handlers = [], array $processors = [], DateTimeZone|null $timezone = null { $args = \func_get_args(); if ([] !== $args) { + trigger_deprecation('symfony/monolog-bridge', '6.3', 'The "%s" class extending "%s" is deprecated. In the future, this class will stop extending it.', self::class, BaseLogger::class); $this->logger = new BaseLogger(...$args); } } @@ -125,9 +126,9 @@ public function popHandler(): HandlerInterface * @see BaseLogger::removeHandler * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - public function removeHandler(int $handlerIndex): void + public function removeHandler(callable $callback): void { - $this->logger->removeHandler($handlerIndex); + $this->logger->removeHandler($callback); } /** @@ -174,9 +175,9 @@ public function popProcessor(): callable * @see BaseLogger::removeProcessor * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - public function removeProcessor(int $processorIndex): void + public function removeProcessor(callable $callback): void { - $this->logger->removeProcessor($processorIndex); + $this->logger->removeProcessor($callback); } /** @@ -241,7 +242,7 @@ public static function getLevelName(int|Level $level): string * @see BaseLogger::toMonologLevel * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - public static function toMonologLevel(string|int|Level $level): Level + public static function toMonologLevel($level): int { return BaseLogger::toMonologLevel($level); } @@ -259,7 +260,7 @@ public function isHandling(int|string|Level $level): bool * @see BaseLogger::setExceptionHandler * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - public function setExceptionHandler(Closure|null $callback): self + public function setExceptionHandler(?callable $callback): self { $this->logger->setExceptionHandler($callback); @@ -270,7 +271,7 @@ public function setExceptionHandler(Closure|null $callback): self * @see BaseLogger::getExceptionHandler * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - public function getExceptionHandler(): Closure|null + public function getExceptionHandler(): ?callable { return $this->logger->getExceptionHandler(); } @@ -299,7 +300,7 @@ public function getTimezone(): DateTimeZone * @see BaseLogger::handleException * @deprecated This has been copied over from \Monolog\Logger for compatibility reasons, and might be removed eventually. */ - protected function handleException(Throwable $e, LogRecord $record): void + protected function handleException(Throwable $e, array $record): void { $this->logger->handleException($e, $record); } diff --git a/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php index 16205be6cefc7..70204e5243184 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LegacyLoggerTest.php @@ -16,10 +16,22 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Logger; use Symfony\Bridge\Monolog\Processor\DebugProcessor; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\HttpFoundation\Request; +/** + * @group legacy + */ class LegacyLoggerTest extends TestCase { + use ExpectDeprecationTrait; + + public function testConstructWillTriggerDeprecation() + { + $this->expectDeprecation('Since symfony/monolog-bridge 6.3: The "Symfony\Bridge\Monolog\Logger" class extending "Monolog\Logger" is deprecated. In the future, this class will stop extending it.'); + new Logger(__METHOD__); + } + public function testGetLogsWithoutDebugProcessor() { $handler = new TestHandler(); diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 87a4c283f42a4..44c0d32f2ece0 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -20,7 +20,8 @@ "monolog/monolog": "dev-remove-handlers-processors", "symfony/service-contracts": "^2.5|^3", "symfony/http-kernel": "^5.4|^6.0", - "psr/log": "^2.0 || ^3.0" + "psr/log": "^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { "symfony/console": "^5.4|^6.0",