diff --git a/composer.json b/composer.json index ab775ad6..b9437d6d 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", - "graylog2/gelf-php": "^1.4.2", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d368b288..eb126d4a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -41,3 +41,6 @@ parameters: # legacy elasticsearch namespace failures - '# Elastic\\Elasticsearch\\#' + + # legacy GelfPHP 1.x failures + - '# Gelf\\Message::set(Facility|Line|File)\(#' diff --git a/src/Monolog/Formatter/GelfMessageFormatter.php b/src/Monolog/Formatter/GelfMessageFormatter.php index a1a79372..f5b60d04 100644 --- a/src/Monolog/Formatter/GelfMessageFormatter.php +++ b/src/Monolog/Formatter/GelfMessageFormatter.php @@ -47,6 +47,11 @@ class GelfMessageFormatter extends NormalizerFormatter */ protected $maxLength; + /** + * @var int + */ + private $gelfVersion = 2; + /** * Translates Monolog log levels to Graylog2 log priorities. * @@ -78,6 +83,10 @@ class GelfMessageFormatter extends NormalizerFormatter $this->extraPrefix = is_null($extraPrefix) ? '' : $extraPrefix; $this->contextPrefix = $contextPrefix; $this->maxLength = is_null($maxLength) ? self::DEFAULT_MAX_LENGTH : $maxLength; + + if (method_exists(Message::class, 'setFacility')) { + $this->gelfVersion = 1; + } } /** @@ -113,16 +122,20 @@ class GelfMessageFormatter extends NormalizerFormatter $message->setShortMessage(Utils::substr($record['message'], 0, $this->maxLength)); } - if (isset($record['channel'])) { - $message->setFacility($record['channel']); - } - if (isset($extra['line'])) { - $message->setLine($extra['line']); - unset($extra['line']); - } - if (isset($extra['file'])) { - $message->setFile($extra['file']); - unset($extra['file']); + if ($this->gelfVersion === 1) { + if (isset($record['channel'])) { + $message->setFacility($record['channel']); + } + if (isset($extra['line'])) { + $message->setLine($extra['line']); + unset($extra['line']); + } + if (isset($extra['file'])) { + $message->setFile($extra['file']); + unset($extra['file']); + } + } else { + $message->setAdditional('channel', $record['channel']); } foreach ($extra as $key => $val) { @@ -147,11 +160,13 @@ class GelfMessageFormatter extends NormalizerFormatter $message->setAdditional($this->contextPrefix . $key, $val); } - /** @phpstan-ignore-next-line */ - if (null === $message->getFile() && isset($context['exception']['file'])) { - if (preg_match("/^(.+):([0-9]+)$/", $context['exception']['file'], $matches)) { - $message->setFile($matches[1]); - $message->setLine($matches[2]); + if ($this->gelfVersion === 1) { + /** @phpstan-ignore-next-line */ + if (null === $message->getFile() && isset($context['exception']['file'])) { + if (preg_match("/^(.+):([0-9]+)$/", $context['exception']['file'], $matches)) { + $message->setFile($matches[1]); + $message->setLine($matches[2]); + } } } diff --git a/tests/Monolog/Formatter/GelfMessageFormatterTest.php b/tests/Monolog/Formatter/GelfMessageFormatterTest.php index 88eb9a4a..d5619e4f 100644 --- a/tests/Monolog/Formatter/GelfMessageFormatterTest.php +++ b/tests/Monolog/Formatter/GelfMessageFormatterTest.php @@ -11,6 +11,7 @@ namespace Monolog\Formatter; +use Gelf\Message; use Monolog\Logger; use PHPUnit\Framework\TestCase; @@ -44,9 +45,13 @@ class GelfMessageFormatterTest extends TestCase $this->assertInstanceOf('Gelf\Message', $message); $this->assertEquals(0, $message->getTimestamp()); $this->assertEquals('log', $message->getShortMessage()); - $this->assertEquals('meh', $message->getFacility()); - $this->assertEquals(null, $message->getLine()); - $this->assertEquals(null, $message->getFile()); + if (self::isGelfVersion1()) { + $this->assertEquals('meh', $message->getFacility()); + $this->assertEquals(null, $message->getLine()); + $this->assertEquals(null, $message->getFile()); + } else { + $this->assertEquals('meh', $message->getAdditional('channel')); + } $this->assertEquals($this->isLegacy() ? 3 : 'error', $message->getLevel()); $this->assertNotEmpty($message->getHost()); @@ -77,8 +82,13 @@ class GelfMessageFormatterTest extends TestCase $message = $formatter->format($record); $this->assertInstanceOf('Gelf\Message', $message); - $this->assertEquals('test', $message->getFile()); - $this->assertEquals(14, $message->getLine()); + if (self::isGelfVersion1()) { + $this->assertEquals('test', $message->getFile()); + $this->assertEquals(14, $message->getLine()); + } else { + $this->assertEquals('test', $message->getAdditional('file')); + $this->assertEquals(14, $message->getAdditional('line')); + } } /** @@ -144,7 +154,7 @@ class GelfMessageFormatterTest extends TestCase 'level' => Logger::ERROR, 'level_name' => 'ERROR', 'channel' => 'meh', - 'context' => ['from' => 'logger', 'exception' => [ + 'context' => ['exception' => [ 'class' => '\Exception', 'file' => '/some/file/in/dir.php:56', 'trace' => ['/some/file/1.php:23', '/some/file/2.php:3'], @@ -158,8 +168,12 @@ class GelfMessageFormatterTest extends TestCase $this->assertInstanceOf('Gelf\Message', $message); - $this->assertEquals("/some/file/in/dir.php", $message->getFile()); - $this->assertEquals("56", $message->getLine()); + if (self::isGelfVersion1()) { + $this->assertEquals("/some/file/in/dir.php", $message->getFile()); + $this->assertEquals("56", $message->getLine()); + } else { + $this->assertEquals(['channel' => 'meh', 'ctxt_exception' => '{"class":"\\\\Exception","file":"/some/file/in/dir.php:56","trace":["/some/file/1.php:23","/some/file/2.php:3"]}'], $message->getAllAdditionals()); + } } /** @@ -277,4 +291,9 @@ class GelfMessageFormatterTest extends TestCase { return interface_exists('\Gelf\IMessagePublisher'); } + + private static function isGelfVersion1() + { + return method_exists(Message::class, 'setFacility'); + } } diff --git a/tests/Monolog/Handler/GelfHandlerTest.php b/tests/Monolog/Handler/GelfHandlerTest.php index 6a23423d..7e0cd953 100644 --- a/tests/Monolog/Handler/GelfHandlerTest.php +++ b/tests/Monolog/Handler/GelfHandlerTest.php @@ -55,11 +55,16 @@ class GelfHandlerTest extends TestCase $expectedMessage = new Message(); $expectedMessage ->setLevel(7) - ->setFacility("test") ->setShortMessage($record['message']) ->setTimestamp($record['datetime']) ; + if (self::isGelfVersion1()) { + $expectedMessage->setFacility("test"); + } else { + $expectedMessage->setAdditional('channel', "test"); + } + $messagePublisher = $this->getMessagePublisher(); $messagePublisher->expects($this->once()) ->method('publish') @@ -76,11 +81,16 @@ class GelfHandlerTest extends TestCase $expectedMessage = new Message(); $expectedMessage ->setLevel(4) - ->setFacility("test") ->setShortMessage($record['message']) ->setTimestamp($record['datetime']) ; + if (self::isGelfVersion1()) { + $expectedMessage->setFacility("test"); + } else { + $expectedMessage->setAdditional('channel', "test"); + } + $messagePublisher = $this->getMessagePublisher(); $messagePublisher->expects($this->once()) ->method('publish') @@ -100,7 +110,6 @@ class GelfHandlerTest extends TestCase $expectedMessage = new Message(); $expectedMessage ->setLevel(4) - ->setFacility("test") ->setHost("mysystem") ->setShortMessage($record['message']) ->setTimestamp($record['datetime']) @@ -108,6 +117,12 @@ class GelfHandlerTest extends TestCase ->setAdditional("CTXfrom", 'logger') ; + if (self::isGelfVersion1()) { + $expectedMessage->setFacility("test"); + } else { + $expectedMessage->setAdditional('channel', "test"); + } + $messagePublisher = $this->getMessagePublisher(); $messagePublisher->expects($this->once()) ->method('publish') @@ -117,4 +132,9 @@ class GelfHandlerTest extends TestCase $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX')); $handler->handle($record); } + + private static function isGelfVersion1() + { + return method_exists(Message::class, 'setFacility'); + } }