1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-01-16 20:28:23 +01:00

Deprecate DateTimeImmutable (#1928)

Fixes #1926
This commit is contained in:
Ruud Kamphuis 2024-12-05 15:38:02 +01:00 committed by GitHub
parent e940004193
commit a258e4fe90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 83 additions and 49 deletions

View File

@ -1,3 +1,7 @@
### Unreleased
* Deprecated Monolog\DateTimeImmutable in favor of Monolog\JsonSerializableDateTimeImmutable
### 3.8.0 (2024-11-12)
* Added `$fileOpenMode` param to `StreamHandler` to define a custom fopen mode to open the log file (#1913)

View File

@ -1,3 +1,9 @@
### 4.0.0
Overall / notable changes:
- Monolog\DateTimeImmutable has been removed in favor of Monolog\JsonSerializableDateTimeImmutable.
### 3.0.0
Overall / notable changes:

View File

@ -11,7 +11,7 @@ message | string | The log message. When the `PsrLogMessag
level | Monolog\Level case | Severity of the log message. See log levels described in [01-usage.md](01-usage.md#log-levels).
context | array | Arbitrary data passed with the construction of the message. For example the username of the current user or their IP address.
channel | string | The channel this message was logged to. This is the name that was passed when the logger was created with `new Logger('channel')`.
datetime | Monolog\DateTimeImmutable | Date and time when the message was logged. Class extends `\DateTimeImmutable`.
datetime | Monolog\JsonSerializableDateTimeImmutable | Date and time when the message was logged. Class extends `\DateTimeImmutable`.
extra | array | A placeholder array where processors can put additional data. Always available, but empty if there are no processors registered.
At first glance `context` and `extra` look very similar, and they are in the sense that they both carry arbitrary data that is related to the log message somehow.

View File

@ -11,38 +11,13 @@
namespace Monolog;
use DateTimeZone;
class_alias(JsonSerializableDateTimeImmutable::class, 'Monolog\DateTimeImmutable');
if (false) {
/**
* Overrides default json encoding of date time objects
*
* @author Menno Holtkamp
* @author Jordi Boggiano <j.boggiano@seld.be>
* @deprecated Use \Monolog\JsonSerializableDateTimeImmutable instead.
*/
class DateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable
class DateTimeImmutable extends JsonSerializableDateTimeImmutable
{
private bool $useMicroseconds;
public function __construct(bool $useMicroseconds, ?DateTimeZone $timezone = null)
{
$this->useMicroseconds = $useMicroseconds;
// if you like to use a custom time to pass to Logger::addRecord directly,
// call modify() or setTimestamp() on this instance to change the date after creating it
parent::__construct('now', $timezone);
}
public function jsonSerialize(): string
{
if ($this->useMicroseconds) {
return $this->format('Y-m-d\TH:i:s.uP');
}
return $this->format('Y-m-d\TH:i:sP');
}
public function __toString(): string
{
return $this->jsonSerialize();
}
}

View File

@ -11,7 +11,7 @@
namespace Monolog\Formatter;
use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
use Monolog\Utils;
use Throwable;
use Monolog\LogRecord;
@ -322,9 +322,9 @@ class NormalizerFormatter implements FormatterInterface
protected function formatDate(\DateTimeInterface $date): string
{
// in case the date format isn't custom then we defer to the custom DateTimeImmutable
// in case the date format isn't custom then we defer to the custom JsonSerializableDateTimeImmutable
// formatting logic, which will pick the right format based on whether useMicroseconds is on
if ($this->dateFormat === self::SIMPLE_DATE && $date instanceof DateTimeImmutable) {
if ($this->dateFormat === self::SIMPLE_DATE && $date instanceof JsonSerializableDateTimeImmutable) {
return (string) $date;
}

View File

@ -16,7 +16,7 @@ use Monolog\Formatter\FormatterInterface;
use Monolog\Level;
use Monolog\Utils;
use Monolog\LogRecord;
use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
/**
* Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
@ -150,7 +150,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
message: 'Incomplete logs, chrome header size limit reached',
level: Level::Warning,
channel: 'monolog',
datetime: new DateTimeImmutable(true),
datetime: new JsonSerializableDateTimeImmutable(true),
);
self::$json['rows'][\count(self::$json['rows']) - 1] = $this->getFormatter()->format($record);
$json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true);

View File

@ -0,0 +1,48 @@
<?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;
use DateTimeZone;
/**
* Overrides default json encoding of date time objects
*
* @author Menno Holtkamp
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class JsonSerializableDateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable
{
private bool $useMicroseconds;
public function __construct(bool $useMicroseconds, ?DateTimeZone $timezone = null)
{
$this->useMicroseconds = $useMicroseconds;
// if you like to use a custom time to pass to Logger::addRecord directly,
// call modify() or setTimestamp() on this instance to change the date after creating it
parent::__construct('now', $timezone);
}
public function jsonSerialize(): string
{
if ($this->useMicroseconds) {
return $this->format('Y-m-d\TH:i:s.uP');
}
return $this->format('Y-m-d\TH:i:sP');
}
public function __toString(): string
{
return $this->jsonSerialize();
}
}

View File

@ -323,12 +323,13 @@ class Logger implements LoggerInterface, ResettableInterface
* @param int $level The logging level (a Monolog or RFC 5424 level)
* @param string $message The log message
* @param mixed[] $context The log context
* @param DateTimeImmutable|null $datetime Optional log date to log into the past or future
* @param JsonSerializableDateTimeImmutable|null $datetime Optional log date to log into the past or future
*
* @return bool Whether the record has been processed
*
* @phpstan-param value-of<Level::VALUES>|Level $level
*/
public function addRecord(int|Level $level, string $message, array $context = [], DateTimeImmutable|null $datetime = null): bool
public function addRecord(int|Level $level, string $message, array $context = [], JsonSerializableDateTimeImmutable|null $datetime = null): bool
{
if (\is_int($level) && isset(self::RFC_5424_LEVELS[$level])) {
$level = self::RFC_5424_LEVELS[$level];
@ -356,7 +357,7 @@ class Logger implements LoggerInterface, ResettableInterface
$recordInitialized = \count($this->processors) === 0;
$record = new LogRecord(
datetime: $datetime ?? new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
datetime: $datetime ?? new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone),
channel: $this->name,
level: self::toMonologLevel($level),
message: $message,
@ -518,7 +519,7 @@ class Logger implements LoggerInterface, ResettableInterface
public function isHandling(int|string|Level $level): bool
{
$record = new LogRecord(
datetime: new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
datetime: new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone),
channel: $this->name,
message: '',
level: self::toMonologLevel($level),

View File

@ -60,7 +60,7 @@ class PsrLogMessageProcessor implements ProcessorInterface
if (null === $val || \is_scalar($val) || (\is_object($val) && method_exists($val, "__toString"))) {
$replacements[$placeholder] = $val;
} elseif ($val instanceof \DateTimeInterface) {
if (null === $this->dateFormat && $val instanceof \Monolog\DateTimeImmutable) {
if (null === $this->dateFormat && $val instanceof \Monolog\JsonSerializableDateTimeImmutable) {
// handle monolog dates using __toString if no specific dateFormat was asked for
// so that it follows the useMicroseconds flag
$replacements[$placeholder] = (string) $val;

View File

@ -14,7 +14,7 @@ namespace Monolog\Test;
use Monolog\Level;
use Monolog\Logger;
use Monolog\LogRecord;
use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
use Monolog\Formatter\FormatterInterface;
use Psr\Log\LogLevel;
use ReflectionProperty;
@ -34,7 +34,7 @@ class TestCase extends \PHPUnit\Framework\TestCase
*
* @phpstan-param value-of<Level::VALUES>|value-of<Level::NAMES>|Level|LogLevel::* $level
*/
protected function getRecord(int|string|Level $level = Level::Warning, string|\Stringable $message = 'test', array $context = [], string $channel = 'test', \DateTimeImmutable $datetime = new DateTimeImmutable(true), array $extra = []): LogRecord
protected function getRecord(int|string|Level $level = Level::Warning, string|\Stringable $message = 'test', array $context = [], string $channel = 'test', \DateTimeImmutable $datetime = new JsonSerializableDateTimeImmutable(true), array $extra = []): LogRecord
{
return new LogRecord(
message: (string) $message,

View File

@ -11,7 +11,7 @@
namespace Monolog\Formatter;
use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
use Monolog\Test\TestCase;
class ScalarFormatterTest extends TestCase
@ -57,7 +57,7 @@ class ScalarFormatterTest extends TestCase
'baz' => false,
'bam' => [1, 2, 3],
'bat' => ['foo' => 'bar'],
'bap' => $dt = new DateTimeImmutable(true),
'bap' => $dt = new JsonSerializableDateTimeImmutable(true),
'ban' => $exception,
]));

View File

@ -556,7 +556,7 @@ class LoggerTest extends TestCase
/**
* @covers Logger::setTimezone
* @covers DateTimeImmutable::__construct
* @covers JsonSerializableDateTimeImmutable::__construct
*/
public function testTimezoneIsRespectedInUTC()
{
@ -578,7 +578,7 @@ class LoggerTest extends TestCase
/**
* @covers Logger::setTimezone
* @covers DateTimeImmutable::__construct
* @covers JsonSerializableDateTimeImmutable::__construct
*/
public function testTimezoneIsRespectedInOtherTimezone()
{
@ -807,7 +807,7 @@ class LoggerTest extends TestCase
$logger->pushHandler($loggingHandler);
$logger->pushHandler($testHandler);
$datetime = (new DateTimeImmutable($microseconds))->modify('2022-03-04 05:06:07');
$datetime = (new JsonSerializableDateTimeImmutable($microseconds))->modify('2022-03-04 05:06:07');
$logger->addRecord(Level::Debug, 'test', [], $datetime);
list($record) = $testHandler->getRecords();