From e294b27a6df1cb6feb97411cf283e44c2ec40072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ch=C3=A1bek?= Date: Fri, 18 Aug 2017 14:14:44 +0200 Subject: [PATCH 1/4] [MonologBridge] remove redundant method call --- src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php index 9b372d6e22749..f44d3dfc58431 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -114,8 +114,6 @@ public function formatBatch(array $records) */ public function format(array $record) { - $record = $this->replacePlaceHolder($record); - $levelColor = self::$levelColorMap[$record['level']]; if ($this->options['multiline']) { From cbcabcd694a982634b67221ae6d470eee99865a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ch=C3=A1bek?= Date: Fri, 18 Aug 2017 14:50:06 +0200 Subject: [PATCH 2/4] [MonologBridge] allow passing options to default formatter --- src/Symfony/Bridge/Monolog/CHANGELOG.md | 5 +++++ .../Bridge/Monolog/Handler/ConsoleHandler.php | 20 ++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index f91d4c5d9a224..2ad1787fae0b5 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +3.4.0 +----- + + * the `ConsoleHandler` class now accepts options for default formatter (`ConsoleFormatter`) + 3.3.0 ----- diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index 01f055f20a1aa..ccc7497b51ddf 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -56,6 +56,9 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG, ); + /** @var array */ + private $formatterOptions; + /** * Constructor. * @@ -64,15 +67,22 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe * @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) + * @param array $formatterOptions Array of options for default formatter (ConsoleFormatter) */ - public function __construct(OutputInterface $output = null, $bubble = true, array $verbosityLevelMap = array()) - { + public function __construct( + OutputInterface $output = null, + $bubble = true, + array $verbosityLevelMap = array(), + array $formatterOptions = array() + ) { parent::__construct(Logger::DEBUG, $bubble); $this->output = $output; if ($verbosityLevelMap) { $this->verbosityLevelMap = $verbosityLevelMap; } + + $this->formatterOptions = $formatterOptions; } /** @@ -165,13 +175,13 @@ protected function write(array $record) protected function getDefaultFormatter() { if (!$this->output) { - return new ConsoleFormatter(); + return new ConsoleFormatter($this->formatterOptions); } - return new ConsoleFormatter(array( + return new ConsoleFormatter(array_replace(array( 'colors' => $this->output->isDecorated(), 'multiline' => OutputInterface::VERBOSITY_DEBUG <= $this->output->getVerbosity(), - )); + ), $this->formatterOptions)); } /** From af8a369359eda4fef8d0e4bd3865de4e73564dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ch=C3=A1bek?= Date: Fri, 18 Aug 2017 14:51:09 +0200 Subject: [PATCH 3/4] [MonologBridge] add ConsoleFormatter option to ignore empty context/extra --- src/Symfony/Bridge/Monolog/CHANGELOG.md | 1 + .../Monolog/Formatter/ConsoleFormatter.php | 16 ++++++---- .../Tests/Handler/ConsoleHandlerTest.php | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index 2ad1787fae0b5..9e02df75370f0 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * the `ConsoleHandler` class now accepts options for default formatter (`ConsoleFormatter`) + * added option `ignore_empty_context_and_extra` to `ConsoleFormatter` 3.3.0 ----- diff --git a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php index f44d3dfc58431..854a434d8542b 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -78,6 +78,7 @@ public function __construct($options = array()) 'date_format' => self::SIMPLE_DATE, 'colors' => true, 'multiline' => false, + 'ignore_empty_context_and_extra' => false, ), $options); if (class_exists(VarCloner::class)) { @@ -116,13 +117,16 @@ public function format(array $record) { $levelColor = self::$levelColorMap[$record['level']]; - if ($this->options['multiline']) { - $context = $extra = "\n"; - } else { - $context = $extra = ' '; + $context = $extra = ''; + if (!empty($record['context']) || !$this->options['ignore_empty_context_and_extra']) { + $context = $this->options['multiline'] ? "\n" : ' '; + $context .= $this->dumpData($record['context']); + } + + if (!empty($record['extra']) || !$this->options['ignore_empty_context_and_extra']) { + $extra = $this->options['multiline'] ? "\n" : ' '; + $extra .= $this->dumpData($record['extra']); } - $context .= $this->dumpData($record['context']); - $extra .= $this->dumpData($record['extra']); $formatted = strtr($this->options['format'], array( '%datetime%' => $record['datetime']->format($this->options['date_format']), diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 63b5a8f07b6d7..4c3b31c599178 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -168,6 +168,36 @@ public function testWritingAndFormatting() $this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.'); } + public function testWritingAndFormattingWithCustomFormattingOptions() + { + $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface')->getMock(); + $output + ->expects($this->any()) + ->method('getVerbosity') + ->will($this->returnValue(OutputInterface::VERBOSITY_DEBUG)) + ; + $output + ->expects($this->once()) + ->method('write') + ->with("16:21:54 INFO [app] My info message\n") + ; + + $handler = new ConsoleHandler(null, false, array(), array('ignore_empty_context_and_extra' => true)); + $handler->setOutput($output); + + $infoRecord = array( + 'message' => 'My info message', + 'context' => array(), + 'level' => Logger::INFO, + 'level_name' => Logger::getLevelName(Logger::INFO), + 'channel' => 'app', + 'datetime' => new \DateTime('2013-05-29 16:21:54'), + 'extra' => array(), + ); + + $this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.'); + } + public function testLogsFromListeners() { $output = new BufferedOutput(); From df8982c9eab58be55ae4fd6a12a8bfda46ee0ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ch=C3=A1bek?= Date: Sun, 20 Aug 2017 14:28:13 +0200 Subject: [PATCH 4/4] [MonologBridge] add ConsoleFormatter option to remove used context fields --- src/Symfony/Bridge/Monolog/CHANGELOG.md | 1 + .../Monolog/Formatter/ConsoleFormatter.php | 17 +++++++++++-- .../Tests/Handler/ConsoleHandlerTest.php | 24 ++++++++++++------- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index 9e02df75370f0..9857d382b9574 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * the `ConsoleHandler` class now accepts options for default formatter (`ConsoleFormatter`) * added option `ignore_empty_context_and_extra` to `ConsoleFormatter` + * added option `remove_used_context_fields` to `ConsoleFormatter` 3.3.0 ----- diff --git a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php index 854a434d8542b..230d5439297d0 100644 --- a/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php +++ b/src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php @@ -79,6 +79,7 @@ public function __construct($options = array()) 'colors' => true, 'multiline' => false, 'ignore_empty_context_and_extra' => false, + 'remove_used_context_fields' => false, ), $options); if (class_exists(VarCloner::class)) { @@ -117,6 +118,8 @@ public function format(array $record) { $levelColor = self::$levelColorMap[$record['level']]; + $record = $this->replacePlaceHolder($record); + $context = $extra = ''; if (!empty($record['context']) || !$this->options['ignore_empty_context_and_extra']) { $context = $this->options['multiline'] ? "\n" : ' '; @@ -134,7 +137,7 @@ public function format(array $record) '%level_name%' => sprintf('%-9s', $record['level_name']), '%end_tag%' => '', '%channel%' => $record['channel'], - '%message%' => $this->replacePlaceHolder($record)['message'], + '%message%' => $record['message'], '%context%' => $context, '%extra%' => $extra, )); @@ -181,13 +184,23 @@ private function replacePlaceHolder(array $record) $replacements = array(); foreach ($context as $k => $v) { + $placeholder = '{'.$k.'}'; + if (strpos($message, $placeholder) === false) { + continue; + } + // Remove quotes added by the dumper around string. $v = trim($this->dumpData($v, false), '"'); $v = OutputFormatter::escape($v); - $replacements['{'.$k.'}'] = sprintf('%s', $v); + $replacements[$placeholder] = sprintf('%s', $v); + + if ($this->options['remove_used_context_fields']) { + unset($context[$k]); + } } $record['message'] = strtr($message, $replacements); + $record['context'] = $context; return $record; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 4c3b31c599178..7b95f46440ae9 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -146,18 +146,25 @@ public function testWritingAndFormatting() ->method('getVerbosity') ->will($this->returnValue(OutputInterface::VERBOSITY_DEBUG)) ; + $message = <<<'EOL' +16:21:54 INFO [app] My info message bar +[ + "foo" => "bar" +] +[] + +EOL; $output ->expects($this->once()) ->method('write') - ->with("16:21:54 INFO [app] My info message\n[]\n[]\n") - ; + ->with($message); $handler = new ConsoleHandler(null, false); $handler->setOutput($output); $infoRecord = array( - 'message' => 'My info message', - 'context' => array(), + 'message' => 'My info message {foo}', + 'context' => array('foo' => 'bar'), 'level' => Logger::INFO, 'level_name' => Logger::getLevelName(Logger::INFO), 'channel' => 'app', @@ -179,15 +186,16 @@ public function testWritingAndFormattingWithCustomFormattingOptions() $output ->expects($this->once()) ->method('write') - ->with("16:21:54 INFO [app] My info message\n") + ->with("16:21:54 INFO [app] My info message bar\n") ; - $handler = new ConsoleHandler(null, false, array(), array('ignore_empty_context_and_extra' => true)); + $formatterOptions = array('ignore_empty_context_and_extra' => true, 'remove_used_context_fields' => true); + $handler = new ConsoleHandler(null, false, array(), $formatterOptions); $handler->setOutput($output); $infoRecord = array( - 'message' => 'My info message', - 'context' => array(), + 'message' => 'My info message {foo}', + 'context' => array('foo' => 'bar'), 'level' => Logger::INFO, 'level_name' => Logger::getLevelName(Logger::INFO), 'channel' => 'app',