Skip to content
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 2.0.1 under development

- no changes in this release.
- Bug #84: Change the type of the `$level` parameter in the `Message` constructor to `string` (dood-)

## 2.0.0 May 22, 2022

Expand Down
2 changes: 1 addition & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<psalm
errorLevel="2"
errorLevel="1"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
Expand Down
19 changes: 17 additions & 2 deletions src/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
*
* When the application ends or {@see Logger::$flushInterval} is reached, Logger will call {@see Logger::flush()}
* to send logged messages to different log targets, such as file or email according to the {@see Logger::$targets}.
*
* @psalm-import-type Backtrace from Message
* @psalm-import-type LogMessageContext from Message
*/
final class Logger implements LoggerInterface
{
Expand Down Expand Up @@ -143,6 +146,15 @@ public function getTargets(): array
return $this->targets;
}

/**
* @param string $level
* @param string|Stringable $message
* @param array $context
* @psalm-param LogMessageContext $context
* @psalm-suppress MoreSpecificImplementedParamType
*
* @return void
*/
public function log(mixed $level, string|Stringable $message, array $context = []): void
{
$context['time'] ??= microtime(true);
Expand Down Expand Up @@ -205,7 +217,7 @@ public function setTraceLevel(int $traceLevel): self
/**
* Sets an array of paths to exclude from tracing when tracing is enabled with {@see Logger::setTraceLevel()}.
*
* @param array $excludedTracePaths The paths to exclude from tracing.
* @param string[] $excludedTracePaths The paths to exclude from tracing.
*
* @throws InvalidArgumentException for non-string values.
*
Expand All @@ -216,6 +228,7 @@ public function setTraceLevel(int $traceLevel): self
public function setExcludedTracePaths(array $excludedTracePaths): self
{
foreach ($excludedTracePaths as $excludedTracePath) {
/** @psalm-suppress DocblockTypeContradiction */
if (!is_string($excludedTracePath)) {
throw new InvalidArgumentException(sprintf(
'The trace path must be a string, %s received.',
Expand All @@ -231,7 +244,7 @@ public function setExcludedTracePaths(array $excludedTracePaths): self
/**
* Sets a target to {@see Logger::$targets}.
*
* @param array $targets The log targets. Each array element represents a single {@see \Yiisoft\Log\Target}
* @param Target[] $targets The log targets. Each array element represents a single {@see \Yiisoft\Log\Target}
* instance or the configuration for creating the log target instance.
*
* @throws InvalidArgumentException for non-instance Target.
Expand Down Expand Up @@ -281,8 +294,10 @@ private function dispatch(array $messages, bool $final): void
* Collects a trace when tracing is enabled with {@see Logger::setTraceLevel()}.
*
* @param array $backtrace The list of call stack information.
* @psalm-param Backtrace|list<array{object?:object,args?:array}> $backtrace
*
* @return array Collected a list of call stack information.
* @psalm-return Backtrace
*/
private function collectTrace(array $backtrace): array
{
Expand Down
29 changes: 24 additions & 5 deletions src/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@

/**
* Message is a data object that stores log message data.
*
* @psalm-type Backtrace = list<array{
* file:string,
* line:int,
* function?:string,
* class?:string,
* type?:string,
* }>
* @psalm-type LogMessageContext = array{
* category?:string,
* memory?:int,
* time?:float,
* trace?:Backtrace,
* }&array
*/
final class Message
{
Expand All @@ -29,7 +43,8 @@ final class Message
private string $message;

/**
* @var array Log message context.
* @var array<string, mixed> Log message context.
* @psalm-var LogMessageContext
*
* Message context has a following keys:
*
Expand All @@ -41,16 +56,17 @@ final class Message
private array $context;

/**
* @param mixed $level Log message level.
* @param string $level Log message level.
* @param string|Stringable $message Log message.
* @param array $context Log message context.
* @param array<string, mixed> $context Log message context.
* @psalm-param LogMessageContext $context
*
* @throws InvalidArgumentException for invalid log message level.
*
* @see LoggerTrait::log()
* @see LogLevel
*/
public function __construct(mixed $level, string|Stringable $message, array $context = [])
public function __construct(string $level, string|Stringable $message, array $context = [])
Comment thread
vjik marked this conversation as resolved.
{
$this->level = Logger::validateLevel($level);
$this->message = $this->parse($message, $context);
Expand Down Expand Up @@ -86,6 +102,7 @@ public function message(): string
* @param mixed $default If the context parameter does not exist, the `$default` will be returned.
*
* @return mixed The context parameter value.
* @psalm-return LogMessageContext|mixed
*/
public function context(string $name = null, mixed $default = null): mixed
{
Expand All @@ -101,7 +118,8 @@ public function context(string $name = null, mixed $default = null): mixed
* where foo will be replaced by the context data in key "foo".
*
* @param string|Stringable $message Raw log message.
* @param array $context Message context.
* @param array<string, mixed> $context Message context.
* @psalm-param LogMessageContext $context
*
* @return string Parsed message.
*/
Expand All @@ -113,6 +131,7 @@ private function parse(string|Stringable $message, array $context): string
$placeholderName = $matches[1];

if (isset($context[$placeholderName])) {
/** @psalm-suppress PossiblyInvalidCast */
return (string) $context[$placeholderName];
}

Expand Down
17 changes: 15 additions & 2 deletions src/Message/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* Formatter formats log messages.
*
* @internal
*
* @psalm-import-type Backtrace from Message
*/
final class Formatter
{
Expand Down Expand Up @@ -125,6 +127,7 @@ private function defaultFormat(Message $message, array $commonContext): string
$time = $this->getTime($message);
$prefix = $this->getPrefix($message, $commonContext);
$context = $this->getContext($message, $commonContext);
/** @var string $category */
$category = $message->context('category', CategoryFilter::DEFAULT);

return "{$time} {$prefix}[{$message->level()}][{$category}] {$message->message()}{$context}";
Expand All @@ -139,6 +142,7 @@ private function defaultFormat(Message $message, array $commonContext): string
*/
private function getTime(Message $message): string
{
/** @psalm-suppress PossiblyInvalidCast */
$timestamp = (string) $message->context('time', microtime(true));

$format = match (true) {
Expand Down Expand Up @@ -199,12 +203,19 @@ private function getContext(Message $message, array $commonContext): string
$context[] = $trace;
}

/**
* @var array-key $name
* @var mixed $value
*/
foreach ($message->context() as $name => $value) {
if ($name !== 'trace') {
$context[] = "{$name}: " . $this->convertToString($value);
}
}

/**
* @var mixed $value
*/
foreach ($commonContext as $name => $value) {
$common[] = "{$name}: " . $this->convertToString($value);
}
Expand All @@ -222,14 +233,16 @@ private function getContext(Message $message, array $commonContext): string
*/
private function getTrace(Message $message): string
{
$traces = (array) $message->context('trace', []);
/** @psalm-var Backtrace $traces */
$traces = $message->context('trace', []);

foreach ($traces as $key => $trace) {
if (isset($trace['file'], $trace['line'])) {
$traces[$key] = "in {$trace['file']}:{$trace['line']}";
}
}

/** @var string[] $traces */
Comment thread
vjik marked this conversation as resolved.
return empty($traces) ? '' : "trace:\n " . implode("\n ", $traces);
}

Expand All @@ -243,7 +256,7 @@ private function getTrace(Message $message): string
private function convertToString(mixed $value): string
{
if (is_object($value) && method_exists($value, '__toString')) {
return $value->__toString();
return (string) $value;
}

return VarDumper::create($value)->asString();
Expand Down
4 changes: 3 additions & 1 deletion src/PsrTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public function getLogger(): LoggerInterface
protected function export(): void
{
foreach ($this->getMessages() as $message) {
$this->logger->log($message->level(), $message->message(), $message->context());
/** @var array $context */
$context = $message->context();
$this->logger->log($message->level(), $message->message(), $context);
}
}
}
11 changes: 7 additions & 4 deletions src/Target.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function collect(array $messages, bool $final): void
/**
* Sets a list of log message categories that this target is interested in.
*
* @param array $categories The list of log message categories.
* @param string[] $categories The list of log message categories.
*
* @throws InvalidArgumentException for invalid log message categories structure.
*
Expand All @@ -132,7 +132,7 @@ public function setCategories(array $categories): self
/**
* Sets a list of log message categories that this target is NOT interested in.
*
* @param array $except The list of log message categories.
* @param string[] $except The list of log message categories.
*
* @throws InvalidArgumentException for invalid log message categories structure.
*
Expand All @@ -149,7 +149,7 @@ public function setExcept(array $except): self
/**
* Sets a list of log message levels that current target is interested in.
*
* @param array $levels The list of log message levels.
* @param string[] $levels The list of log message levels.
*
* @throws InvalidArgumentException for invalid log message level.
*
Expand Down Expand Up @@ -383,7 +383,10 @@ private function filterMessages(array $messages): void
continue;
}

if ($this->categories->isExcluded($message->context('category', ''))) {
/** @var string $category */
$category = $message->context('category', '');

if ($this->categories->isExcluded($category)) {
unset($messages[$i]);
continue;
}
Expand Down