Переглянути джерело

Merge pull request #1290 from versh23/fix-gelp-formtatter

use mb_ functions everywhere if possible
Jordi Boggiano 6 роки тому
батько
коміт
9b5deda678

+ 2 - 1
composer.json

@@ -42,7 +42,8 @@
         "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
         "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
         "rollbar/rollbar": "Allow sending log messages to Rollbar",
-        "php-console/php-console": "Allow sending log messages to Google Chrome"
+        "php-console/php-console": "Allow sending log messages to Google Chrome",
+        "ext-mbstring": "Allow to work properly with unicode symbols"
     },
     "autoload": {
         "psr-4": {"Monolog\\": "src/Monolog"}

+ 6 - 3
src/Monolog/Formatter/GelfMessageFormatter.php

@@ -13,6 +13,7 @@ namespace Monolog\Formatter;
 
 use Monolog\Logger;
 use Gelf\Message;
+use Monolog\Utils;
 
 /**
  * Serializes a log message to GELF
@@ -96,7 +97,7 @@ class GelfMessageFormatter extends NormalizerFormatter
         $len = 200 + strlen((string) $record['message']) + strlen($this->systemName);
 
         if ($len > $this->maxLength) {
-            $message->setShortMessage(substr($record['message'], 0, $this->maxLength));
+            $message->setShortMessage(Utils::substr($record['message'], 0, $this->maxLength));
         }
 
         if (isset($record['channel'])) {
@@ -115,7 +116,8 @@ class GelfMessageFormatter extends NormalizerFormatter
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
             $len = strlen($this->extraPrefix . $key . $val);
             if ($len > $this->maxLength) {
-                $message->setAdditional($this->extraPrefix . $key, substr($val, 0, $this->maxLength));
+                $message->setAdditional($this->extraPrefix . $key, Utils::substr($val, 0, $this->maxLength));
+
                 continue;
             }
             $message->setAdditional($this->extraPrefix . $key, $val);
@@ -125,7 +127,8 @@ class GelfMessageFormatter extends NormalizerFormatter
             $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
             $len = strlen($this->contextPrefix . $key . $val);
             if ($len > $this->maxLength) {
-                $message->setAdditional($this->contextPrefix . $key, substr($val, 0, $this->maxLength));
+                $message->setAdditional($this->contextPrefix . $key, Utils::substr($val, 0, $this->maxLength));
+
                 continue;
             }
             $message->setAdditional($this->contextPrefix . $key, $val);

+ 2 - 1
src/Monolog/Handler/BrowserConsoleHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
+use Monolog\Utils;
 
 /**
  * Handler sending logs to browser's javascript console with no browser extension required
@@ -175,7 +176,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
             $args[] = '"font-weight: normal"';
 
             $pos = $match[0][1];
-            $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
+            $format = Utils::substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . Utils::substr($format, $pos + strlen($match[0][0]));
         }
 
         array_unshift($args, static::quote($format));

+ 4 - 4
src/Monolog/Handler/Curl/Util.php

@@ -31,9 +31,9 @@ final class Util
     /**
      * Executes a CURL request with optional retries and exception on failure
      *
-     * @param resource $ch curl handler
-     * @param int $retries
-     * @param bool $closeAfterDone
+     * @param  resource    $ch             curl handler
+     * @param  int         $retries
+     * @param  bool        $closeAfterDone
      * @return bool|string @see curl_exec
      */
     public static function execute($ch, int $retries = 5, bool $closeAfterDone = true)
@@ -65,4 +65,4 @@ final class Util
 
         return false;
     }
-}
+}

+ 5 - 5
src/Monolog/Handler/OverflowHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Monolog\Logger;
 
-
 /**
  * Handler to only pass log messages when a certain threshold of number of messages is reached.
  *
@@ -60,9 +59,9 @@ class OverflowHandler extends AbstractHandler
 
     /**
      * @param HandlerInterface $handler
-     * @param int[] $thresholdMap Dictionary of logger level => threshold
-     * @param int $level
-     * @param bool $bubble
+     * @param int[]            $thresholdMap Dictionary of logger level => threshold
+     * @param int              $level
+     * @param bool             $bubble
      */
     public function __construct(
         HandlerInterface $handler,
@@ -87,7 +86,7 @@ class OverflowHandler extends AbstractHandler
      * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
      * calling further handlers in the stack with a given log record.
      *
-     * @param  array $record The record to handle
+     * @param array $record The record to handle
      *
      * @return Boolean true means that this handler handled the record, and that bubbling is not permitted.
      *                 false means the record was either not processed or that this handler allows bubbling.
@@ -108,6 +107,7 @@ class OverflowHandler extends AbstractHandler
             // The overflow threshold is not yet reached, so we're buffering the record and lowering the threshold by 1
             $this->thresholdMap[$level]--;
             $this->buffer[$level][] = $record;
+
             return false === $this->bubble;
         }
 

+ 2 - 1
src/Monolog/Handler/PushoverHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Sends notifications through the pushover api to mobile phones
@@ -118,7 +119,7 @@ class PushoverHandler extends SocketHandler
         $maxMessageLength = 512 - strlen($this->title);
 
         $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message'];
-        $message = substr($message, 0, $maxMessageLength);
+        $message = Utils::substr($message, 0, $maxMessageLength);
 
         $timestamp = $record['datetime']->getTimestamp();
 

+ 2 - 1
src/Monolog/Handler/SqsHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Aws\Sqs\SqsClient;
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Writes to any sqs queue.
@@ -52,7 +53,7 @@ class SqsHandler extends AbstractProcessingHandler
 
         $messageBody = $record['formatted'];
         if (strlen($messageBody) >= static::MAX_MESSAGE_SIZE) {
-            $messageBody = substr($messageBody, 0, static::HEAD_MESSAGE_SIZE);
+            $messageBody = Utils::substr($messageBody, 0, static::HEAD_MESSAGE_SIZE);
         }
 
         $this->client->sendMessage([

+ 3 - 1
src/Monolog/Handler/SyslogUdp/UdpSocket.php

@@ -11,6 +11,8 @@
 
 namespace Monolog\Handler\SyslogUdp;
 
+use Monolog\Utils;
+
 class UdpSocket
 {
     protected const DATAGRAM_MAX_LENGTH = 65023;
@@ -54,6 +56,6 @@ class UdpSocket
     {
         $chunkSize = static::DATAGRAM_MAX_LENGTH - strlen($header);
 
-        return $header . substr($line, 0, $chunkSize);
+        return $header . Utils::substr($line, 0, $chunkSize);
     }
 }

+ 12 - 3
src/Monolog/Handler/TelegramBotHandler.php

@@ -1,4 +1,13 @@
-<?php
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
 
 namespace Monolog\Handler;
 
@@ -38,7 +47,7 @@ class TelegramBotHandler extends AbstractProcessingHandler
     private $channel;
 
     /**
-     * @param string $apiKey Telegram bot access token provided by BotFather
+     * @param string $apiKey  Telegram bot access token provided by BotFather
      * @param string $channel Telegram channel name
      * @inheritDoc
      */
@@ -87,4 +96,4 @@ class TelegramBotHandler extends AbstractProcessingHandler
             throw new RuntimeException('Telegram API error. Description: ' . $result['description']);
         }
     }
-}
+}

+ 9 - 0
src/Monolog/Utils.php

@@ -22,4 +22,13 @@ final class Utils
 
         return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
     }
+
+    public static function substr(string $string, int $start, ?int $length = null)
+    {
+        if (extension_loaded('mbstring')) {
+            return mb_strcut($string, $start, $length);
+        }
+
+        return substr($string, $start, $length);
+    }
 }

+ 20 - 0
tests/Monolog/Formatter/GelfMessageFormatterTest.php

@@ -253,6 +253,26 @@ class GelfMessageFormatterTest extends TestCase
         $this->assertGreaterThanOrEqual(131289, $length, 'The message should not be truncated');
     }
 
+    public function testFormatWithLargeCyrillicData()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = [
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => ['exception' => str_repeat('а', 32767)],
+            'datetime' => new \DateTimeImmutable("@0"),
+            'extra' => ['key' => str_repeat('б', 32767)],
+            'message' => str_repeat('в', 32767),
+        ];
+        $message = $formatter->format($record);
+        $messageArray = $message->toArray();
+
+        $messageString = json_encode($messageArray);
+
+        $this->assertIsString($messageString);
+    }
+
     private function isLegacy()
     {
         return interface_exists('\Gelf\IMessagePublisher');

+ 0 - 1
tests/Monolog/Handler/AmqpHandlerTest.php

@@ -14,7 +14,6 @@ namespace Monolog\Handler;
 use Monolog\Test\TestCase;
 use Monolog\Logger;
 use PhpAmqpLib\Message\AMQPMessage;
-use PhpAmqpLib\Connection\AMQPConnection;
 
 /**
  * @covers Monolog\Handler\RotatingFileHandler

+ 0 - 1
tests/Monolog/Handler/SyslogUdpHandlerTest.php

@@ -67,7 +67,6 @@ class SyslogUdpHandlerTest extends TestCase
         $handler->handle($this->getRecordWithMessage(null));
     }
 
-
     public function testRfc()
     {
         $time = 'Jan 07 12:34:56';

+ 10 - 1
tests/Monolog/Handler/TelegramBotHandlerTest.php

@@ -1,4 +1,13 @@
-<?php
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
 
 namespace Monolog\Handler;