From 0951cb6dfe5c17de295bb5fd98be2052edf8176e Mon Sep 17 00:00:00 2001 From: omerimzali Date: Tue, 4 Feb 2025 00:11:36 +0300 Subject: [PATCH 1/5] Add PSR-20 ClockInterface support for customizable timestamps --- src/Monolog/Logger.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index e545c4487..5ffe2bb6a 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -19,9 +19,11 @@ use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; use Psr\Log\LogLevel; +use Psr\Clock\ClockInterface; use Throwable; use Stringable; use WeakMap; +use Monolog\LoggerClock; /** * Monolog log channel @@ -148,6 +150,8 @@ class Logger implements LoggerInterface, ResettableInterface protected Closure|null $exceptionHandler = null; + protected ClockInterface|null $clock = null; + /** * Keeps track of depth to prevent infinite logging loops */ @@ -169,16 +173,17 @@ class Logger implements LoggerInterface, ResettableInterface * @param list $handlers Optional stack of handlers, the first one in the array is called first, etc. * @param callable[] $processors Optional array of processors * @param DateTimeZone|null $timezone Optional timezone, if not provided date_default_timezone_get() will be used - * + * @param ClockInterface|null $clock Optional clock for timestamp generation * @phpstan-param array<(callable(LogRecord): LogRecord)|ProcessorInterface> $processors */ - public function __construct(string $name, array $handlers = [], array $processors = [], DateTimeZone|null $timezone = null) + public function __construct(string $name, array $handlers = [], array $processors = [], DateTimeZone|null $timezone = null, ClockInterface|null $clock = null) { $this->name = $name; $this->setHandlers($handlers); $this->processors = $processors; $this->timezone = $timezone ?? new DateTimeZone(date_default_timezone_get()); $this->fiberLogDepth = new \WeakMap(); + $this->clock = $clock; } public function getName(): string @@ -357,7 +362,7 @@ public function addRecord(int|Level $level, string $message, array $context = [] $recordInitialized = \count($this->processors) === 0; $record = new LogRecord( - datetime: $datetime ?? new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone), + datetime: $datetime ?? ($this->clock ? $this->clock->now() : new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone)), channel: $this->name, level: self::toMonologLevel($level), message: $message, From 570eabaa2c969a758449e05977801f19d1dddf3e Mon Sep 17 00:00:00 2001 From: omerimzali Date: Tue, 4 Feb 2025 00:12:17 +0300 Subject: [PATCH 2/5] Add LoggerClock implementation for PSR-20 Clock interface --- src/Monolog/LoggerClock.php | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/Monolog/LoggerClock.php diff --git a/src/Monolog/LoggerClock.php b/src/Monolog/LoggerClock.php new file mode 100644 index 000000000..4acacf925 --- /dev/null +++ b/src/Monolog/LoggerClock.php @@ -0,0 +1,39 @@ +useMicroseconds = $useMicroseconds; + $this->timezone = $timezone; + } + + public function now(): JsonSerializableDateTimeImmutable + { + return $this->fixedTime ?? new JsonSerializableDateTimeImmutable($this->useMicroseconds, $this->timezone); + } + + public function setUseMicroseconds(bool $useMicroseconds): void + { + $this->useMicroseconds = $useMicroseconds; + } + + public function setTimezone(?\DateTimeZone $timezone): void + { + $this->timezone = $timezone; + } + + public function setFixedTime(JsonSerializableDateTimeImmutable $fixedTime): void + { + $this->fixedTime = $fixedTime; + } +} From 8301707e3f668db8e8801e8b62a17a69e4e15a2c Mon Sep 17 00:00:00 2001 From: omerimzali Date: Tue, 4 Feb 2025 00:14:32 +0300 Subject: [PATCH 3/5] Add PSR-20 ClockInterface support for customizable timestamps --- src/Monolog/Logger.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index 5ffe2bb6a..ba0dbec59 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -23,7 +23,6 @@ use Throwable; use Stringable; use WeakMap; -use Monolog\LoggerClock; /** * Monolog log channel @@ -151,7 +150,7 @@ class Logger implements LoggerInterface, ResettableInterface protected Closure|null $exceptionHandler = null; protected ClockInterface|null $clock = null; - + /** * Keeps track of depth to prevent infinite logging loops */ From bb636ff7a850f1b92d64d770feca74b0da929f29 Mon Sep 17 00:00:00 2001 From: omerimzali Date: Tue, 4 Feb 2025 00:18:10 +0300 Subject: [PATCH 4/5] Add psr/clock to composer.json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 9574a1b0d..693df0a2a 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ ], "require": { "php": ">=8.1", + "psr/clock": "^1.0", "psr/log": "^2.0 || ^3.0" }, "require-dev": { From fc49f1b422f66d1d88a9d61d9742d9f46b0a3eb6 Mon Sep 17 00:00:00 2001 From: omerimzali Date: Tue, 4 Feb 2025 00:23:07 +0300 Subject: [PATCH 5/5] Use instanceof check for ClockInterface in Logger --- src/Monolog/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index ba0dbec59..7ac72b93a 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -361,7 +361,7 @@ public function addRecord(int|Level $level, string $message, array $context = [] $recordInitialized = \count($this->processors) === 0; $record = new LogRecord( - datetime: $datetime ?? ($this->clock ? $this->clock->now() : new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone)), + datetime: $datetime ?? ($this->clock instanceof ClockInterface ? $this->clock->now() : new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone)), channel: $this->name, level: self::toMonologLevel($level), message: $message,