1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-07-31 10:20:14 +02:00

mb_* functions with BC

This commit is contained in:
vershinin_so
2019-07-08 11:05:19 +03:00
parent ada57dd4a1
commit c79d81ec28
27 changed files with 120 additions and 64 deletions

View File

@@ -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"}

View File

@@ -11,6 +11,8 @@
namespace Monolog\Formatter;
use Monolog\Utils;
/**
* formats the record to be used in the FlowdockHandler
*
@@ -84,22 +86,10 @@ class FlowdockFormatter implements FormatterInterface
public function getShortMessage(string $message): string
{
static $hasMbString;
if (null === $hasMbString) {
$hasMbString = function_exists('mb_strlen');
}
$maxLength = 45;
if ($hasMbString) {
if (mb_strlen($message, 'UTF-8') > $maxLength) {
$message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...';
}
} else {
if (strlen($message) > $maxLength) {
$message = substr($message, 0, $maxLength - 4) . ' ...';
}
if (Utils::strlen($message) > $maxLength) {
$message = Utils::substr($message, 0, $maxLength - 4) . ' ...';
}
return $message;

View File

@@ -13,6 +13,7 @@ namespace Monolog\Formatter;
use Monolog\Logger;
use Gelf\Message;
use Monolog\Utils;
/**
* Serializes a log message to GELF
@@ -93,10 +94,10 @@ class GelfMessageFormatter extends NormalizerFormatter
->setLevel($this->logLevels[$record['level']]);
// message length + system name length + 200 for padding / metadata
$len = 200 + mb_strlen((string) $record['message']) + mb_strlen($this->systemName);
$len = 200 + Utils::strlen((string) $record['message']) + Utils::strlen($this->systemName);
if ($len > $this->maxLength) {
$message->setShortMessage(mb_substr($record['message'], 0, $this->maxLength));
$message->setShortMessage(Utils::substr($record['message'], 0, $this->maxLength));
}
if (isset($record['channel'])) {
@@ -113,9 +114,10 @@ class GelfMessageFormatter extends NormalizerFormatter
foreach ($record['extra'] as $key => $val) {
$val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
$len = mb_strlen($this->extraPrefix . $key . $val);
$len = Utils::strlen($this->extraPrefix . $key . $val);
if ($len > $this->maxLength) {
$message->setAdditional($this->extraPrefix . $key, mb_substr($val, 0, $this->maxLength));
$message->setAdditional($this->extraPrefix . $key, Utils::substr($val, 0, $this->maxLength));
continue;
}
$message->setAdditional($this->extraPrefix . $key, $val);
@@ -123,9 +125,10 @@ class GelfMessageFormatter extends NormalizerFormatter
foreach ($record['context'] as $key => $val) {
$val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
$len = mb_strlen($this->contextPrefix . $key . $val);
$len = Utils::strlen($this->contextPrefix . $key . $val);
if ($len > $this->maxLength) {
$message->setAdditional($this->contextPrefix . $key, mb_substr($val, 0, $this->maxLength));
$message->setAdditional($this->contextPrefix . $key, Utils::substr($val, 0, $this->maxLength));
continue;
}
$message->setAdditional($this->contextPrefix . $key, $val);

View File

@@ -379,12 +379,12 @@ class NormalizerFormatter implements FormatterInterface
return $date->format($this->dateFormat);
}
protected function addJsonEncodeOption($option)
{
$this->jsonEncodeOptions |= $option;
}
protected function removeJsonEncodeOption($option)
{
$this->jsonEncodeOptions ^= $option;

View File

@@ -12,6 +12,7 @@
namespace Monolog\Formatter;
use Monolog\Logger;
use Monolog\Utils;
/**
* Serializes a log message according to Wildfire's header requirements
@@ -90,7 +91,7 @@ class WildfireFormatter extends NormalizerFormatter
// The message itself is a serialization of the above JSON object + it's length
return sprintf(
'%d|%s|',
strlen($json),
Utils::strlen($json),
$json
);
}

View File

@@ -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 + Utils::strlen($match[0][0]));
}
array_unshift($args, static::quote($format));

View File

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
use Monolog\Formatter\ChromePHPFormatter;
use Monolog\Formatter\FormatterInterface;
use Monolog\Logger;
use Monolog\Utils;
/**
* Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
@@ -146,7 +147,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
$json = @json_encode(self::$json);
$data = base64_encode(utf8_encode($json));
if (strlen($data) > 240 * 1024) {
if (Utils::strlen($data) > 240 * 1024) {
self::$overflowed = true;
$record = [

View File

@@ -12,6 +12,7 @@
namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Utils;
/**
* Logs to Cube.
@@ -134,7 +135,7 @@ class CubeHandler extends AbstractProcessingHandler
$this->connectUdp();
}
socket_send($this->udpConnection, $data, strlen($data), 0);
socket_send($this->udpConnection, $data, Utils::strlen($data), 0);
}
private function writeHttp(string $data): void
@@ -146,7 +147,7 @@ class CubeHandler extends AbstractProcessingHandler
curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen('['.$data.']'),
'Content-Length: ' . Utils::strlen('['.$data.']'),
]);
Curl\Util::execute($this->httpConnection, 5, false);

View File

@@ -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;
}
}
}

View File

@@ -12,6 +12,7 @@
namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Utils;
/**
* Simple handler wrapper that deduplicates log records across multiple requests
@@ -66,7 +67,7 @@ class DeduplicationHandler extends BufferHandler
{
parent::__construct($handler, 0, Logger::DEBUG, $bubble, false);
$this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
$this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . Utils::substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
$this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel);
$this->time = $time;
}
@@ -149,7 +150,7 @@ class DeduplicationHandler extends BufferHandler
while (!feof($handle)) {
$log = fgets($handle);
if ($log && substr($log, 0, 10) >= $timestampValidity) {
if ($log && Utils::substr($log, 0, 10) >= $timestampValidity) {
$validLogs[] = $log;
}
}

View File

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
use Monolog\Formatter\FormatterInterface;
use Monolog\Formatter\LineFormatter;
use Monolog\Logger;
use Monolog\Utils;
/**
* Sends logs to Fleep.io using Webhook integrations
@@ -96,7 +97,7 @@ class FleepHookHandler extends SocketHandler
$header = "POST " . static::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n";
$header .= "Host: " . static::FLEEP_HOST . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($content) . "\r\n";
$header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
$header .= "\r\n";
return $header;

View File

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Formatter\FlowdockFormatter;
use Monolog\Formatter\FormatterInterface;
use Monolog\Utils;
/**
* Sends notifications through the Flowdock push API
@@ -107,7 +108,7 @@ class FlowdockHandler extends SocketHandler
$header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
$header .= "Host: api.flowdock.com\r\n";
$header .= "Content-Type: application/json\r\n";
$header .= "Content-Length: " . strlen($content) . "\r\n";
$header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
$header .= "\r\n";
return $header;

View File

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
use Monolog\Formatter\FormatterInterface;
use Monolog\Formatter\HtmlFormatter;
use Monolog\Utils;
/**
* Base class for all mail handlers
@@ -70,7 +71,7 @@ abstract class MailHandler extends AbstractProcessingHandler
protected function isHtmlBody(string $body): bool
{
return substr($body, 0, 1) === '<';
return Utils::substr($body, 0, 1) === '<';
}
/**

View File

@@ -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;
}

View File

@@ -12,6 +12,7 @@
namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Utils;
/**
* Sends notifications through the pushover api to mobile phones
@@ -115,10 +116,10 @@ class PushoverHandler extends SocketHandler
private function buildContent(array $record): string
{
// Pushover has a limit of 512 characters on title and message combined.
$maxMessageLength = 512 - strlen($this->title);
$maxMessageLength = 512 - Utils::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();
@@ -158,7 +159,7 @@ class PushoverHandler extends SocketHandler
$header = "POST /1/messages.json HTTP/1.1\r\n";
$header .= "Host: api.pushover.net\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($content) . "\r\n";
$header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
$header .= "\r\n";
return $header;

View File

@@ -14,6 +14,7 @@ namespace Monolog\Handler\Slack;
use Monolog\Logger;
use Monolog\Formatter\NormalizerFormatter;
use Monolog\Formatter\FormatterInterface;
use Monolog\Utils;
/**
* Slack record utility helping to log to Slack webhooks or API.
@@ -307,7 +308,7 @@ class SlackRecord
private function generateAttachmentField(string $title, $value): array
{
$value = is_array($value)
? sprintf('```%s```', substr($this->stringify($value), 0, 1990))
? sprintf('```%s```', Utils::substr($this->stringify($value), 0, 1990))
: $value;
return array(

View File

@@ -14,6 +14,7 @@ namespace Monolog\Handler;
use Monolog\Formatter\FormatterInterface;
use Monolog\Logger;
use Monolog\Handler\Slack\SlackRecord;
use Monolog\Utils;
/**
* Sends notifications through Slack API
@@ -129,7 +130,7 @@ class SlackHandler extends SocketHandler
$header = "POST /api/chat.postMessage HTTP/1.1\r\n";
$header .= "Host: slack.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($content) . "\r\n";
$header .= "Content-Length: " . Utils::strlen($content) . "\r\n";
$header .= "\r\n";
return $header;

View File

@@ -12,6 +12,7 @@
namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Utils;
/**
* Stores to any socket - uses fsockopen() or pfsockopen().
@@ -325,7 +326,7 @@ class SocketHandler extends AbstractProcessingHandler
private function writeToSocket(string $data): void
{
$length = strlen($data);
$length = Utils::strlen($data);
$sent = 0;
$this->lastSentBytes = $sent;
while ($this->isConnected() && $sent < $length) {

View File

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

View File

@@ -12,6 +12,7 @@
namespace Monolog\Handler;
use Monolog\Logger;
use Monolog\Utils;
/**
* Stores to any stream resource
@@ -146,8 +147,8 @@ class StreamHandler extends AbstractProcessingHandler
return dirname($stream);
}
if ('file://' === substr($stream, 0, 7)) {
return dirname(substr($stream, 7));
if ('file://' === Utils::substr($stream, 0, 7)) {
return dirname(Utils::substr($stream, 7));
}
return null;

View File

@@ -11,6 +11,8 @@
namespace Monolog\Handler\SyslogUdp;
use Monolog\Utils;
class UdpSocket
{
protected const DATAGRAM_MAX_LENGTH = 65023;
@@ -47,13 +49,13 @@ class UdpSocket
if (!is_resource($this->socket)) {
throw new \RuntimeException('The UdpSocket to '.$this->ip.':'.$this->port.' has been closed and can not be written to anymore');
}
socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
socket_sendto($this->socket, $chunk, Utils::strlen($chunk), $flags = 0, $this->ip, $this->port);
}
protected function assembleMessage(string $line, string $header): string
{
$chunkSize = static::DATAGRAM_MAX_LENGTH - strlen($header);
$chunkSize = static::DATAGRAM_MAX_LENGTH - Utils::strlen($header);
return $header . substr($line, 0, $chunkSize);
return $header . Utils::substr($line, 0, $chunkSize);
}
}

View File

@@ -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']);
}
}
}
}

View File

@@ -12,6 +12,7 @@
namespace Monolog\Processor;
use Monolog\ResettableInterface;
use Monolog\Utils;
/**
* Adds a unique identifier into records
@@ -45,11 +46,11 @@ class UidProcessor implements ProcessorInterface, ResettableInterface
public function reset()
{
$this->uid = $this->generateUid(strlen($this->uid));
$this->uid = $this->generateUid(Utils::strlen($this->uid));
}
private function generateUid(int $length): string
{
return substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length);
return Utils::substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length);
}
}

View File

@@ -22,4 +22,33 @@ final class Utils
return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
}
private static function hasMbString(): bool
{
static $hasMbString;
if (null === $hasMbString) {
$hasMbString = extension_loaded('mbstring');
}
return $hasMbString;
}
public static function strlen(string $string, ?string $encoding = null): int
{
if (self::hasMbString()) {
return mb_strlen($string, $encoding);
}
return strlen($string);
}
public static function substr(string $string, int $start, ?int $length = null)
{
if (self::hasMbString()) {
return mb_substr($string, $start, $length);
}
return substr($string, $start, $length);
}
}

View File

@@ -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

View File

@@ -75,7 +75,6 @@ class SyslogUdpHandlerTest extends TestCase
$handler->handle($this->getRecordWithMessage(null));
}
public function testRfc()
{
$time = 'Mar 22 21:16:47';

View File

@@ -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;
@@ -39,4 +48,4 @@ class TelegramBotHandlerTest extends TestCase
->method('send')
->willReturn(null);
}
}
}