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

## 2.1.2 under development

- New #125: Add optional `$levels` parameter to `Target` constructor allowing log level filtering at instantiation (@samdark)
- Chg #126: Add `ext-psr` to `conflict` section in `composer.json` (@samdark)

## 2.1.1 June 03, 2025
Expand All @@ -13,7 +14,7 @@

- New #104: Add new static methods `Logger::assertLevelIsValid()`, `Logger::assertLevelIsString()` and
`Logger::assertLevelIsSupported()` (@vjik)
- New #108: Support of nested values in message templates' variables, e. g. `{foo.bar}` (@vjik)
- New #108: Support of nested values in message templates' variables, e.g. `{foo.bar}` (@vjik)
- New #109, #113, #116: Add context providers (@vjik)
- New #111: Add `DateTime` and `DateTimeImmutable` support as time in log context (@vjik)
- New #112: Add `Message::category()` method and `Message::DEFAULT_CATEGORY` constant, deprecate
Expand Down
5 changes: 3 additions & 2 deletions src/PsrTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ final class PsrTarget extends Target
* Sets the PSR-3 logger used to save messages of this target.
*
* @param LoggerInterface $logger The logger instance to be used for messages processing.
* @param string[] $levels The {@see \Psr\Log\LogLevel log message levels} that this target is interested in.
*/
public function __construct(private LoggerInterface $logger)
public function __construct(private LoggerInterface $logger, array $levels = [])
{
parent::__construct();
parent::__construct($levels);
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/StreamTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ final class StreamTarget extends Target
{
/**
* @param resource|string $stream A string stream identifier or a stream resource.
* @param string[] $levels The {@see \Psr\Log\LogLevel log message levels} that this target is interested in.
*/
public function __construct(private $stream = 'php://stdout')
public function __construct(private $stream = 'php://stdout', array $levels = [])
{
parent::__construct();
parent::__construct($levels);
}

protected function export(): void
Expand Down
7 changes: 5 additions & 2 deletions src/Target.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,14 @@ abstract protected function export(): void;

/**
* When defining a constructor in child classes, you must call `parent::__construct()`.
*
* @param string[] $levels The {@see \Psr\Log\LogLevel log message levels} that this target is interested in.
*/
public function __construct()
public function __construct(array $levels = [])
{
$this->categories = new CategoryFilter();
$this->formatter = new Formatter();
$this->setLevels($levels);
}

/**
Expand Down Expand Up @@ -147,7 +150,7 @@ public function setExcept(array $except): self
}

/**
* Sets a list of log message levels that current target is interested in.
* Sets a list of {@see \Psr\Log\LogLevel log message levels} that current target is interested in.
*
* @param string[] $levels The list of log message levels.
*
Expand Down
26 changes: 26 additions & 0 deletions tests/PsrTargetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,30 @@ public function testPsrLogInterfaceMethods(string $level, string $message, array
$this->target->collect([new Message($level, $message, $context)], true);
$this->expectOutputString("{$level}: {$message}: " . json_encode($context, JSON_THROW_ON_ERROR));
}

public function testSetLevelsViaConstructor(): void
{
$target = new PsrTarget(
new class () implements LoggerInterface {
use LoggerTrait;

public function log($level, $message, array $context = []): void
{
echo "$level: $message";
}
},
[LogLevel::ERROR, LogLevel::INFO]
);

$target->collect(
[
new Message(LogLevel::INFO, 'message-1', ['foo' => 'bar']),
new Message(LogLevel::DEBUG, 'message-2', ['foo' => true]),
new Message(LogLevel::ERROR, 'message-3', ['foo' => 1]),
],
true
);

$this->expectOutputString('info: message-1error: message-3');
}
}
17 changes: 17 additions & 0 deletions tests/StreamTargetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,21 @@ private function exportStreamTarget(StreamTarget $target): void
true
);
}

public function testSetLevelsViaConstructor(): void
{
$target = new StreamTarget('php://output', [LogLevel::ERROR, LogLevel::INFO]);
$target->setFormat(static fn (Message $message) => "[{$message->level()}] {$message->message()}");

$target->collect(
[
new Message(LogLevel::INFO, 'message-1', ['foo' => 'bar']),
new Message(LogLevel::DEBUG, 'message-2', ['foo' => true]),
new Message(LogLevel::ERROR, 'message-3', ['foo' => 1]),
],
true
);

$this->expectOutputString("[info] message-1\n[error] message-3\n");
}
}
31 changes: 31 additions & 0 deletions tests/TargetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,37 @@ public function testFormatMessageThrowExceptionForPrefixCallableReturnNotBoolean
$this->target->formatMessages();
}

public function testSetLevelsViaConstructor(): void
{
$target = new DummyTarget([LogLevel::ERROR, LogLevel::WARNING]);
$logger = new Logger([$target]);

$logger->setFlushInterval(1);
$logger->log(LogLevel::INFO, 'testInfo');
$logger->log(LogLevel::ERROR, 'testError');
$logger->log(LogLevel::WARNING, 'testWarning');
$logger->log(LogLevel::DEBUG, 'testDebug');

$messages = $target->getMessages();
$this->assertCount(2, $messages);
$this->assertSame('testError', $messages[0]->message());
$this->assertSame('testWarning', $messages[1]->message());
}

public function testSetLevelsViaConstructorWithEmptyArray(): void
{
$target = new DummyTarget([]);
$logger = new Logger([$target]);

$logger->setFlushInterval(1);
$logger->log(LogLevel::INFO, 'testInfo');
$logger->log(LogLevel::ERROR, 'testError');
$logger->log(LogLevel::DEBUG, 'testDebug');

$messages = $target->getMessages();
$this->assertCount(3, $messages);
}

private function collectOneAndExport(string $level, string $message, array $context = []): void
{
$this->target->collect([new Message($level, $message, $context)], true);
Expand Down
4 changes: 2 additions & 2 deletions tests/TestAsset/DummyTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ final class DummyTarget extends Target
private array $exportMessages = [];
private Formatter $exportFormatter;

public function __construct()
public function __construct(array $levels = [])
{
parent::__construct();
parent::__construct($levels);
$this->exportFormatter = new Formatter();
}

Expand Down
Loading