Jordi Boggiano 8 лет назад
Родитель
Сommit
2551b8e3eb

+ 7 - 3
.travis.yml

@@ -1,6 +1,13 @@
 language: php
 
 sudo: false
+dist: trusty
+
+php:
+  - 7.0
+  - 7.1
+  - hhvm
+  - nightly
 
 cache:
   directories:
@@ -10,9 +17,6 @@ matrix:
     include:
         - php: 7.0
           env: deps=low
-        - php: 7.0
-        - php: 7.1
-        - php: nightly
     fast_finish: true
     allow_failures:
         - php: nightly

+ 17 - 16
src/Monolog/Formatter/GelfMessageFormatter.php

@@ -22,7 +22,7 @@ use Gelf\Message;
  */
 class GelfMessageFormatter extends NormalizerFormatter
 {
-    const MAX_LENGTH = 32766;
+    const DEFAULT_MAX_LENGTH = 32766;
 
     /**
      * @var string the name of the system for the Gelf log message
@@ -39,6 +39,11 @@ class GelfMessageFormatter extends NormalizerFormatter
      */
     protected $contextPrefix;
 
+    /**
+     * @var int max length per field
+     */
+    protected $maxLength;
+
     /**
      * Translates Monolog log levels to Graylog2 log priorities.
      */
@@ -53,7 +58,7 @@ class GelfMessageFormatter extends NormalizerFormatter
         Logger::EMERGENCY => 0,
     ];
 
-    public function __construct(string $systemName = null, string $extraPrefix = null, string $contextPrefix = 'ctxt_')
+    public function __construct(string $systemName = null, string $extraPrefix = null, string $contextPrefix = 'ctxt_', int $maxLength = null)
     {
         parent::__construct('U.u');
 
@@ -61,6 +66,7 @@ class GelfMessageFormatter extends NormalizerFormatter
 
         $this->extraPrefix = $extraPrefix;
         $this->contextPrefix = $contextPrefix;
+        $this->maxLength = is_null($maxLength) ? self::DEFAULT_MAX_LENGTH : $maxLength;
     }
 
     /**
@@ -86,35 +92,30 @@ class GelfMessageFormatter extends NormalizerFormatter
             ->setHost($this->systemName)
             ->setLevel($this->logLevels[$record['level']]);
 
-        // start count with message length + system name length + 200 for padding / metadata
+        // message length + system name length + 200 for padding / metadata
         $len = 200 + strlen((string) $record['message']) + strlen($this->systemName);
 
-        if ($len > self::MAX_LENGTH) {
-            $message->setShortMessage(substr($record['message'], 0, self::MAX_LENGTH - 200));
-
-            return $message;
+        if ($len > $this->maxLength) {
+            $message->setShortMessage(substr($record['message'], 0, $this->maxLength));
         }
 
         if (isset($record['channel'])) {
             $message->setFacility($record['channel']);
-            $len += strlen($record['channel']);
         }
         if (isset($record['extra']['line'])) {
             $message->setLine($record['extra']['line']);
-            $len += 10;
             unset($record['extra']['line']);
         }
         if (isset($record['extra']['file'])) {
             $message->setFile($record['extra']['file']);
-            $len += strlen($record['extra']['file']);
             unset($record['extra']['file']);
         }
 
         foreach ($record['extra'] as $key => $val) {
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
-            $len += strlen($this->extraPrefix . $key . $val);
-            if ($len > self::MAX_LENGTH) {
-                $message->setAdditional($this->extraPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len));
+            $len = strlen($this->extraPrefix . $key . $val);
+            if ($len > $this->maxLength) {
+                $message->setAdditional($this->extraPrefix . $key, substr($val, 0, $this->maxLength));
                 break;
             }
             $message->setAdditional($this->extraPrefix . $key, $val);
@@ -122,9 +123,9 @@ class GelfMessageFormatter extends NormalizerFormatter
 
         foreach ($record['context'] as $key => $val) {
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
-            $len += strlen($this->contextPrefix . $key . $val);
-            if ($len > self::MAX_LENGTH) {
-                $message->setAdditional($this->contextPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len));
+            $len = strlen($this->contextPrefix . $key . $val);
+            if ($len > $this->maxLength) {
+                $message->setAdditional($this->contextPrefix . $key, substr($val, 0, $this->maxLength));
                 break;
             }
             $message->setAdditional($this->contextPrefix . $key, $val);

+ 1 - 3
src/Monolog/Formatter/JsonFormatter.php

@@ -27,6 +27,7 @@ class JsonFormatter extends NormalizerFormatter
 
     protected $batchMode;
     protected $appendNewline;
+
     /**
      * @var bool
      */
@@ -81,9 +82,6 @@ class JsonFormatter extends NormalizerFormatter
         }
     }
 
-    /**
-     * @param bool $include
-     */
     public function includeStacktraces(bool $include = true)
     {
         $this->includeStacktraces = $include;

+ 28 - 4
tests/Monolog/Formatter/GelfMessageFormatterTest.php

@@ -221,10 +221,34 @@ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase
             }
         }
 
-        // in graylog2/gelf-php before 1.4.1 empty strings are filtered and won't be included in the message
-        // though it should be sufficient to ensure that the entire message length does not exceed the maximum
-        // length being allowed
-        $this->assertLessThanOrEqual(32766, $length, 'The message length is no longer than the maximum allowed length');
+        $this->assertLessThanOrEqual(65792, $length, 'The message length is no longer than the maximum allowed length');
+    }
+
+    public function testFormatWithUnlimitedLength()
+    {
+        $formatter = new GelfMessageFormatter(null, null, 'ctxt_', PHP_INT_MAX);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('exception' => str_repeat(' ', 32767 * 2)),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => str_repeat(' ', 32767 * 2)),
+            'message' => 'log'
+        );
+        $message = $formatter->format($record);
+        $messageArray = $message->toArray();
+
+        // 200 for padding + metadata
+        $length = 200;
+
+        foreach ($messageArray as $key => $value) {
+            if (!in_array($key, array('level', 'timestamp'))) {
+                $length += strlen($value);
+            }
+        }
+
+        $this->assertGreaterThanOrEqual(131289, $length, 'The message should not be truncated');
     }
 
     private function isLegacy()