Преглед на файлове

Add graylog2/gelf-php 2.x support, fixes #1747

Jordi Boggiano преди 3 години
родител
ревизия
5eccd17dc5

+ 1 - 1
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",

+ 3 - 0
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)\(#'

+ 30 - 15
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]);
+                }
             }
         }
 

+ 27 - 8
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');
+    }
 }

+ 23 - 3
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');
+    }
 }