From c7b12a7497413e04e5216cd9e21558eda66e2fbf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 9 Jun 2018 17:02:23 +0200 Subject: [PATCH] Json formatter should always format context/extra as an object, fixes #1028 --- src/Monolog/Formatter/JsonFormatter.php | 10 +++++++++- tests/Monolog/Formatter/JsonFormatterTest.php | 6 ++++-- tests/Monolog/Handler/LogmaticHandlerTest.php | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index 28086e10..e0d5449e 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -64,7 +64,15 @@ class JsonFormatter extends NormalizerFormatter */ public function format(array $record): string { - return $this->toJson($this->normalize($record), true) . ($this->appendNewline ? "\n" : ''); + $normalized = $this->normalize($record); + if (isset($normalized['context']) && $normalized['context'] === []) { + $normalized['context'] = new \stdClass; + } + if (isset($normalized['extra']) && $normalized['extra'] === []) { + $normalized['extra'] = new \stdClass; + } + + return $this->toJson($normalized, true) . ($this->appendNewline ? "\n" : ''); } /** diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index eeb6b5bb..7ccf5bc8 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -38,11 +38,12 @@ class JsonFormatterTest extends TestCase { $formatter = new JsonFormatter(); $record = $this->getRecord(); + $record['context'] = $record['extra'] = new \stdClass; $this->assertEquals(json_encode($record)."\n", $formatter->format($record)); $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); $record = $this->getRecord(); - $this->assertEquals('{"message":"test","context":[],"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":[]}', $formatter->format($record)); + $this->assertEquals('{"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"'.$record['datetime']->format('Y-m-d\TH:i:s.uP').'","extra":{}}', $formatter->format($record)); } /** @@ -71,6 +72,7 @@ class JsonFormatterTest extends TestCase $this->getRecord(Logger::DEBUG), ]; array_walk($expected, function (&$value, $key) { + $value['context'] = $value['extra'] = new \stdClass; $value = json_encode($value); }); $this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records)); @@ -160,7 +162,7 @@ class JsonFormatterTest extends TestCase private function assertContextContainsFormattedException($expected, $actual) { $this->assertEquals( - '{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":[],"message":"foobar"}'."\n", + '{"level_name":"CRITICAL","channel":"core","context":{"exception":'.$expected.'},"datetime":null,"extra":{},"message":"foobar"}'."\n", $actual ); } diff --git a/tests/Monolog/Handler/LogmaticHandlerTest.php b/tests/Monolog/Handler/LogmaticHandlerTest.php index bab74ac9..de33c6bb 100644 --- a/tests/Monolog/Handler/LogmaticHandlerTest.php +++ b/tests/Monolog/Handler/LogmaticHandlerTest.php @@ -37,7 +37,7 @@ class LogmaticHandlerTest extends TestCase fseek($this->res, 0); $content = fread($this->res, 1024); - $this->assertRegexp('/testToken {"message":"Critical write test","context":\[\],"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); + $this->assertRegexp('/testToken {"message":"Critical write test","context":{},"level":500,"level_name":"CRITICAL","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); } public function testWriteBatchContent() @@ -53,7 +53,7 @@ class LogmaticHandlerTest extends TestCase fseek($this->res, 0); $content = fread($this->res, 1024); - $this->assertRegexp('/testToken {"message":"test","context":\[\],"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":\[\],"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); + $this->assertRegexp('/testToken {"message":"test","context":{},"level":300,"level_name":"WARNING","channel":"test","datetime":"(.*)","extra":{},"hostname":"testHostname","appname":"testAppname","@marker":\["sourcecode","php"\]}/', $content); } private function createHandler()