vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php line 165
<?php/** This file is part of the Symfony package.** (c) Fabien Potencier <fabien@symfony.com>** 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\Formatter\FormatterInterface;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;use Symfony\Component\Console\Event\ConsoleTerminateEvent;use Symfony\Component\Console\Output\ConsoleOutputInterface;use Symfony\Component\Console\Output\OutputInterface;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 <j.boggiano@seld.be>** @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 <j.boggiano@seld.be>** @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.** It is disabled by default and gets activated as soon as a command is executed.* Instead of listening to the console events, the output can also be set manually.** The minimum logging level at which this handler will be triggered depends on the* verbosity setting of the console output. The default mapping is:* - OutputInterface::VERBOSITY_NORMAL will show all WARNING and higher logs* - OutputInterface::VERBOSITY_VERBOSE (-v) will show all NOTICE and higher logs* - OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) will show all INFO and higher logs* - OutputInterface::VERBOSITY_DEBUG (-vvv) will show all DEBUG and higher logs, i.e. all logs** This mapping can be customized with the $verbosityLevelMap constructor parameter.** @author Tobias Schultze <http://tobion.de>** @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,OutputInterface::VERBOSITY_NORMAL => Logger::WARNING,OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE,OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO,OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG,];private array $consoleFormatterOptions;/*** @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)* @param bool $bubble Whether the messages that are handled can bubble up the stack* @param array $verbosityLevelMap Array that maps the OutputInterface verbosity to a minimum logging* level (leave empty to use the default mapping)*/public function __construct(OutputInterface $output = null, bool $bubble = true, array $verbosityLevelMap = [], array $consoleFormatterOptions = []){parent::__construct(Logger::DEBUG, $bubble);$this->output = $output;if ($verbosityLevelMap) {$this->verbosityLevelMap = $verbosityLevelMap;}$this->consoleFormatterOptions = $consoleFormatterOptions;}private function doIsHandling(array|LogRecord $record): bool{return $this->updateLevel() && parent::isHandling($record);}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)return $this->updateLevel() && parent::handle($record);}/*** Sets the console output to use for printing logs.*/public function setOutput(OutputInterface $output){$this->output = $output;}/*** Disables the output.*/public function close(): void{$this->output = null;parent::close();}/*** Before a command is executed, the handler gets activated and the console output* is set in order to know where to write the logs.*/public function onCommand(ConsoleCommandEvent $event){$output = $event->getOutput();if ($output instanceof ConsoleOutputInterface) {$output = $output->getErrorOutput();}$this->setOutput($output);}/*** After a command has been executed, it disables the output.*/public function onTerminate(ConsoleTerminateEvent $event){$this->close();}public static function getSubscribedEvents(): array{return [ConsoleEvents::COMMAND => ['onCommand', 255],ConsoleEvents::TERMINATE => ['onTerminate', -255],];}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());}protected function getDefaultFormatter(): FormatterInterface{if (!class_exists(CliDumper::class)) {return new LineFormatter();}if (!$this->output) {return new ConsoleFormatter($this->consoleFormatterOptions);}return new ConsoleFormatter(array_replace(['colors' => $this->output->isDecorated(),'multiline' => OutputInterface::VERBOSITY_DEBUG <= $this->output->getVerbosity(),], $this->consoleFormatterOptions));}/*** Updates the logging level based on the verbosity setting of the console output.** @return bool Whether the handler is enabled and verbosity is not set to quiet*/private function updateLevel(): bool{if (null === $this->output) {return false;}$verbosity = $this->output->getVerbosity();if (isset($this->verbosityLevelMap[$verbosity])) {$this->setLevel($this->verbosityLevelMap[$verbosity]);} else {$this->setLevel(Logger::DEBUG);}return true;}}