diff --git a/src/Monolog/Logger.php b/src/Monolog/Logger.php index e545c4487..462cdf233 100644 --- a/src/Monolog/Logger.php +++ b/src/Monolog/Logger.php @@ -19,10 +19,12 @@ use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; use Psr\Log\LogLevel; +use Psr\Clock\ClockInterface; use Throwable; use Stringable; use WeakMap; + /** * Monolog log channel * @@ -164,21 +166,28 @@ class Logger implements LoggerInterface, ResettableInterface */ private bool $detectCycles = true; + /** + * @var ClockInterface|null + */ + private ?ClockInterface $clock; + /** * @param string $name The logging channel, a simple descriptive name that is attached to all log records * @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 service for fetching timestamps * * @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 $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 @@ -329,7 +338,7 @@ public function useLoggingLoopDetection(bool $detectCycles): self * * @phpstan-param value-of|Level $level */ - public function addRecord(int|Level $level, string $message, array $context = [], JsonSerializableDateTimeImmutable|null $datetime = null): bool + public function addRecord(int|Level $level, string $message, array $context = [], bool $useClock = false): bool { if (\is_int($level) && isset(self::RFC_5424_LEVELS[$level])) { $level = self::RFC_5424_LEVELS[$level]; @@ -356,8 +365,9 @@ public function addRecord(int|Level $level, string $message, array $context = [] try { $recordInitialized = \count($this->processors) === 0; + $datetime = $useClock ? $this->clock->now() : new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone); $record = new LogRecord( - datetime: $datetime ?? new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone), + datetime: $datetime, channel: $this->name, level: self::toMonologLevel($level), message: $message, @@ -732,6 +742,7 @@ public function __serialize(): array 'exceptionHandler' => $this->exceptionHandler, 'logDepth' => $this->logDepth, 'detectCycles' => $this->detectCycles, + 'clock' => $this->clock, ]; } @@ -740,7 +751,7 @@ public function __serialize(): array */ public function __unserialize(array $data): void { - foreach (['name', 'handlers', 'processors', 'microsecondTimestamps', 'timezone', 'exceptionHandler', 'logDepth', 'detectCycles'] as $property) { + foreach (['name', 'handlers', 'processors', 'microsecondTimestamps', 'timezone', 'exceptionHandler', 'logDepth', 'detectCycles', 'clock'] as $property) { if (isset($data[$property])) { $this->$property = $data[$property]; }