diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index 56e70976008ff..b90238c397d43 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -20,6 +20,7 @@ use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -52,6 +53,8 @@ final class ConsoleHandler extends AbstractProcessingHandler implements EventSub OutputInterface::VERBOSITY_DEBUG => Level::Debug, ]; + private ?InputInterface $input = null; + /** * @param OutputInterface|null $output The console output to use (the handler remains disabled when passing null * until the output is set, e.g. by using console events) @@ -64,6 +67,7 @@ public function __construct( bool $bubble = true, array $verbosityLevelMap = [], private array $consoleFormatterOptions = [], + private bool $interactiveOnly = false, ) { parent::__construct(Level::Debug, $bubble); @@ -74,7 +78,16 @@ public function __construct( public function isHandling(LogRecord $record): bool { - return $this->updateLevel() && parent::isHandling($record); + return $this->isInteractiveOnlyEnabled() || ($this->updateLevel() && parent::isHandling($record)); + } + + public function getBubble(): bool + { + if ($this->isInteractiveOnlyEnabled()) { + return false; + } + + return parent::getBubble(); } public function handle(LogRecord $record): bool @@ -84,6 +97,11 @@ public function handle(LogRecord $record): bool return $this->updateLevel() && parent::handle($record); } + public function setInput(InputInterface $input): void + { + $this->input = $input; + } + /** * Sets the console output to use for printing logs. */ @@ -108,6 +126,9 @@ public function close(): void */ public function onCommand(ConsoleCommandEvent $event): void { + $input = $event->getInput(); + $this->setInput($input); + $output = $event->getOutput(); if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); @@ -173,4 +194,9 @@ private function updateLevel(): bool return true; } + + private function isInteractiveOnlyEnabled(): bool + { + return $this->interactiveOnly && $this->input && $this->input->isInteractive(); + } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 626c94ce0ccf8..450d0b6f90689 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -186,4 +186,26 @@ public function testLogsFromListeners() $this->assertStringContainsString('Before terminate message.', $out = $output->fetch()); $this->assertStringContainsString('After terminate message.', $out); } + + public function testInteractiveOnly() + { + $message = RecordFactory::create(Level::Info, 'My info message'); + $interactiveInput = $this->createMock(InputInterface::class); + $interactiveInput + ->method('isInteractive') + ->willReturn(true); + $handler = new ConsoleHandler(interactiveOnly: true); + $handler->setInput($interactiveInput); + self::assertTrue($handler->isHandling($message)); + self::assertFalse($handler->getBubble()); + + $nonInteractiveInput = $this->createMock(InputInterface::class); + $nonInteractiveInput + ->method('isInteractive') + ->willReturn(false); + $handler = new ConsoleHandler(interactiveOnly: true); + $handler->setInput($nonInteractiveInput); + self::assertFalse($handler->isHandling($message)); + self::assertTrue($handler->getBubble()); + } }