8000 Deprecate DateTimeImmutable by ruudk · Pull Request #1928 · Seldaek/monolog · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Deprecate DateTimeImmutable #1928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
6 changes: 6 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
2 changes: 1 addition & 1 deletion doc/message-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
37 changes: 6 additions & 31 deletions src/Monolog/DateTimeImmutable.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,13 @@

namespace Monolog;

use DateTimeZone;
class_alias(JsonSerializableDateTimeImmutable::class, 'Monolog\DateTimeImmutable');

/**
* Overrides default json encoding of date time objects
*
* @author Menno Holtkamp
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class DateTimeImmutable 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
if (false) {
/**
* @deprecated Use \Monolog\JsonSerializableDateTimeImmutable instead.
*/
class DateTimeImmutable extends JsonSerializableDateTimeImmutable
{
return $this->jsonSerialize();
}
}
6 changes: 3 additions & 3 deletions src/Monolog/Formatter/NormalizerFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Monolog\Formatter;

use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
use Monolog\Utils;
use Throwable;
use Monolog\LogRecord;
Expand Down Expand Up @@ -322,9 +322,9 @@ protected function toJson($data, bool $ignoreErrors = false): string

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

Expand Down
4 changes: 2 additions & 2 deletions src/Monolog/Handler/ChromePHPHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
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/)
Expand Down Expand Up @@ -150,7 +150,7 @@ protected function send(): void
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);
Expand Down
48 changes: 48 additions & 0 deletions src/Monolog/JsonSerializableDateTimeImmutable.php
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor
@glensc glensc Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't immutable mean that you can't modify the instance?

I tested locally, and setTimestamp does nothing, I was expecting it to throw.

$ php -r '$t = new \DateTimeImmutable(); $t->setTimestamp(123); echo PHP_VERSION, "\n", $t->getTimestamp(), "\n";'

8.4.2
1735898810

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class behaves the same as DateTime except new objects are returned when modification methods such as DateTime::modify() are called.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to use the instance returned by setTimestamp and pass that to Logger::addRecord as custom datetime instance.

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();
}
}
9 changes: 5 additions & 4 deletions src/Monolog/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,13 @@ public function useLoggingLoopDetection(bool $detectCycles): self
* @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];
Expand Down Expand Up @@ -356,7 +357,7 @@ public function addRecord(int|Level $level, string $message, array $context = []
$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,
Expand Down Expand Up @@ -518,7 +519,7 @@ public static function toMonologLevel(string|int|Level $level): Level
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),
Expand Down
2 changes: 1 addition & 1 deletion src/Monolog/Processor/PsrLogMessageProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function __invoke(LogRecord $record): LogRecord
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;
Expand Down
4 changes: 2 additions & 2 deletions src/Monolog/Test/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
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;
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions tests/Monolog/Formatter/ScalarFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Monolog\Formatter;

use Monolog\DateTimeImmutable;
use Monolog\JsonSerializableDateTimeImmutable;
use Monolog\Test\TestCase;

class ScalarFormatterTest extends TestCase
Expand Down Expand Up @@ -57,7 +57,7 @@ public function testFormat()
'baz' => false,
'bam' => [1, 2, 3],
'bat' => ['foo' => 'bar'],
'bap' => $dt = new DateTimeImmutable(true),
'bap' => $dt = new JsonSerializableDateTimeImmutable(true),
'ban' => $exception,
]));

Expand Down
6 changes: 3 additions & 3 deletions tests/Monolog/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ function ($tz) {

/**
* @covers Logger::setTimezone
* @covers DateTimeImmutable::__construct
* @covers JsonSerializableDateTimeImmutable::__construct
*/
public function testTimezoneIsRespectedInUTC()
{
Expand All @@ -578,7 +578,7 @@ public function testTimezoneIsRespectedInUTC()

/**
* @covers Logger::setTimezone
* @covers DateTimeImmutable::__construct
* @covers JsonSerializableDateTimeImmutable::__construct
*/
public function testTimezoneIsRespectedInOtherTimezone()
{
Expand Down Expand Up @@ -807,7 +807,7 @@ public function testLogWithDateTime()
$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();
Expand Down
0