Skip to content
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.2.2 under development

- no changes in this release.
- Enh #146: Move `Target` configuration to constructor parameters and deprecate the corresponding setters (@WarLikeLaux)

## 2.2.1 March 22, 2026

Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,16 @@ $logger->setFlushInterval(100); // default is 1000

Each log target also collects and stores messages in memory.
Message exporting in a target follows the same principle as in the logger.
To change the number of stored messages, call the `\Yiisoft\Log\Target::setExportInterval()` method:
To change the number of stored messages, pass the `exportInterval` constructor parameter:

```php
$target->setExportInterval(100); // default is 1000
$target = new \Yiisoft\Log\StreamTarget(exportInterval: 100); // default is 1000
```

The `setExportInterval()` setter is deprecated; use the constructor parameter instead. The same
applies to `setCategories()`, `setExcept()`, `setLevels()`, `setFormat()`, `setPrefix()`, `setTimestampFormat()`
and `setEnabled()`.

> Note: All message flushing and exporting also occurs when the application ends.

### Logging targets
Expand Down
8 changes: 6 additions & 2 deletions docs/guide/ru/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,16 @@ $logger->setFlushInterval(100); // по умолчанию 1000
```

Каждый таргет тоже накапливает сообщения в памяти. Экспорт работает по тому же принципу.
Количество сообщений перед экспортом настраивается через `\Yiisoft\Log\Target::setExportInterval()`:
Количество сообщений перед экспортом задаётся параметром конструктора `exportInterval`:

```php
$target->setExportInterval(100); // по умолчанию 1000
$target = new \Yiisoft\Log\StreamTarget(exportInterval: 100); // по умолчанию 1000
```

Сеттер `setExportInterval()` объявлен устаревшим, используйте вместо него параметр конструктора.
То же касается `setCategories()`, `setExcept()`, `setLevels()`, `setFormat()`, `setPrefix()`,
`setTimestampFormat()` и `setEnabled()`.

> Примечание: сброс и экспорт всех сообщений также происходит при завершении приложения.

### Таргеты логирования
Expand Down
12 changes: 12 additions & 0 deletions src/Message/CategoryFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ final class CategoryFilter
*/
private array $exclude = [];

/**
* @param string[] $include The list of included log message categories.
* @param string[] $exclude The list of excluded log message categories.
*
* @throws InvalidArgumentException for invalid log message categories structure.
*/
public function __construct(array $include = [], array $exclude = [])
{
$this->include($include);
$this->exclude($exclude);
}

/**
* Sets the log message categories to be included.
*
Expand Down
35 changes: 14 additions & 21 deletions src/Message/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,22 @@
*/
final class Formatter
{
/**
* @var callable|null PHP callable that returns a string representation of the log message.
*
* If not set, {@see Formatter::defaultFormat()} will be used.
*
* The signature of the callable should be `function (Message $message, array $commonContext): string;`.
*/
private $format;

/**
* @var callable|null PHP callable that returns a string to be prefixed to every exported message.
*
* If not set, {@see Formatter::getPrefix()} will be used, which prefixes
* the message with context information such as user IP, user ID and session ID.
*
* The signature of the callable should be `function (Message $message, array $commonContext): string;`.
*/
private $prefix;
private const DEFAULT_TIMESTAMP_FORMAT = 'Y-m-d H:i:s.u';

/**
* @var string The date format for the log timestamp. Defaults to `Y-m-d H:i:s.u`.
* @param callable|null $format A PHP callable that returns a string representation of the log message.
* If not set, {@see Formatter::defaultFormat()} is used.
* Its signature should be `function (Message $message, array $commonContext): string;`.
* @param callable|null $prefix A PHP callable that returns a string to be prefixed to every exported message.
* If not set, {@see Formatter::getPrefix()} is used.
* Its signature should be `function (Message $message, array $commonContext): string;`.
* @param string|null $timestampFormat The date format for the log timestamp. Defaults to `Y-m-d H:i:s.u`.
*/
private string $timestampFormat = 'Y-m-d H:i:s.u';
public function __construct(
Comment thread
WarLikeLaux marked this conversation as resolved.
private $format = null,
private $prefix = null,
private ?string $timestampFormat = null,
) {}

/**
* Sets the format for the string representation of the log message.
Expand Down Expand Up @@ -120,7 +113,7 @@ public function format(Message $message, array $commonContext): string
*/
private function defaultFormat(Message $message, array $commonContext): string
{
$time = $message->time()->format($this->timestampFormat);
$time = $message->time()->format($this->timestampFormat ?? self::DEFAULT_TIMESTAMP_FORMAT);
$prefix = $this->getPrefix($message, $commonContext);
$context = $this->getContext($message, $commonContext);

Expand Down
22 changes: 19 additions & 3 deletions src/PsrTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,26 @@
*
* @param LoggerInterface $logger The logger instance to be used for messages processing.
* @param string[] $levels The {@see LogLevel log message levels} that this target is interested in.
* @param string[] $categories The log message categories that this target is interested in.
* @param string[] $exceptCategories The log message categories that this target is NOT interested in.
* @param callable|null $format A PHP callable that returns a string representation of the log message.
* @param callable|null $prefix A PHP callable that returns a string to be prefixed to every exported message.
* @param string|null $timestampFormat The date format for the log timestamp.
* @param int $exportInterval How many messages should be accumulated before they are exported.
* @param bool|callable $enabled Whether this target is enabled, or a PHP callable that returns a boolean.
*/
public function __construct(private LoggerInterface $logger, array $levels = [])
{
parent::__construct($levels);
public function __construct(
private LoggerInterface $logger,
array $levels = [],
array $categories = [],
array $exceptCategories = [],
?callable $format = null,
?callable $prefix = null,
?string $timestampFormat = null,
int $exportInterval = self::DEFAULT_EXPORT_INTERVAL,
bool|callable $enabled = true,

Check warning on line 37 in src/PsrTarget.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.4-ubuntu-latest

Escaped Mutant for Mutator "TrueValue": @@ @@ ?callable $prefix = null, ?string $timestampFormat = null, int $exportInterval = self::DEFAULT_EXPORT_INTERVAL, - bool|callable $enabled = true, + bool|callable $enabled = false, ) { parent::__construct($levels, $categories, $exceptCategories, $format, $prefix, $timestampFormat, $exportInterval, $enabled); }
) {
parent::__construct($levels, $categories, $exceptCategories, $format, $prefix, $timestampFormat, $exportInterval, $enabled);
}

/**
Expand Down
22 changes: 19 additions & 3 deletions src/StreamTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,35 @@
/**
* @param resource|string $stream A string stream identifier or a stream resource.
* @param string[] $levels The {@see LogLevel log message levels} that this target is interested in.
* @param string[] $categories The log message categories that this target is interested in.
* @param string[] $exceptCategories The log message categories that this target is NOT interested in.
* @param callable|null $format A PHP callable that returns a string representation of the log message.
* @param callable|null $prefix A PHP callable that returns a string to be prefixed to every exported message.
* @param string|null $timestampFormat The date format for the log timestamp.
* @param int $exportInterval How many messages should be accumulated before they are exported.
* @param bool|callable $enabled Whether this target is enabled, or a PHP callable that returns a boolean.
*/
public function __construct(private $stream = 'php://stdout', array $levels = [])
{
parent::__construct($levels);
public function __construct(
private $stream = 'php://stdout',
array $levels = [],
array $categories = [],
array $exceptCategories = [],
?callable $format = null,
?callable $prefix = null,
?string $timestampFormat = null,
int $exportInterval = self::DEFAULT_EXPORT_INTERVAL,
bool|callable $enabled = true,

Check warning on line 51 in src/StreamTarget.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.4-ubuntu-latest

Escaped Mutant for Mutator "TrueValue": @@ @@ ?callable $prefix = null, ?string $timestampFormat = null, int $exportInterval = self::DEFAULT_EXPORT_INTERVAL, - bool|callable $enabled = true, + bool|callable $enabled = false, ) { parent::__construct($levels, $categories, $exceptCategories, $format, $prefix, $timestampFormat, $exportInterval, $enabled); }
) {
parent::__construct($levels, $categories, $exceptCategories, $format, $prefix, $timestampFormat, $exportInterval, $enabled);
}

protected function export(): void
{
$stream = $this->createStream();
flock($stream, LOCK_EX);

Check warning on line 59 in src/StreamTarget.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.4-ubuntu-latest

Escaped Mutant for Mutator "FunctionCallRemoval": @@ @@ protected function export(): void { $stream = $this->createStream(); - flock($stream, LOCK_EX); + if (fwrite($stream, $this->formatMessages("\n")) === false) { flock($stream, LOCK_UN);

if (fwrite($stream, $this->formatMessages("\n")) === false) {
flock($stream, LOCK_UN);

Check warning on line 62 in src/StreamTarget.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.4-ubuntu-latest

Escaped Mutant for Mutator "FunctionCallRemoval": @@ @@ flock($stream, LOCK_EX); if (fwrite($stream, $this->formatMessages("\n")) === false) { - flock($stream, LOCK_UN); + fclose($stream); throw new RuntimeException(sprintf( 'Unable to export the log because of an error writing to the stream: %s',
fclose($stream);
throw new RuntimeException(sprintf(
'Unable to export the log because of an error writing to the stream: %s',
Expand Down
62 changes: 46 additions & 16 deletions src/Target.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Yiisoft\Log\ContextProvider\CommonContextProvider;
use Yiisoft\Log\Message\CategoryFilter;
use Yiisoft\Log\Message\Formatter;
use Psr\Log\LogLevel;

use function count;
use function in_array;
Expand All @@ -28,6 +29,11 @@
*/
abstract class Target
{
/**
* @psalm-suppress MissingClassConstType
*/
public const DEFAULT_EXPORT_INTERVAL = 1000;

private CategoryFilter $categories;
private Formatter $formatter;

Expand Down Expand Up @@ -60,14 +66,6 @@ abstract class Target
*/
private array $commonContext = [];

/**
* @var int How many log messages should be accumulated before they are exported.
*
* Defaults to 1000. Note that messages will always be exported when the application terminates.
* Set this property to be 0 if you don't want to export messages until the application terminates.
*/
private int $exportInterval = 1000;

/**
* @var bool|callable Enables or disables the current target to export.
*/
Expand All @@ -76,13 +74,30 @@ abstract class Target
/**
* 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.
* @param string[] $levels The {@see LogLevel log message levels} that this target is interested in.
* @param string[] $categories The log message categories that this target is interested in.
* @param string[] $exceptCategories The log message categories that this target is NOT interested in.
* @param callable|null $format A PHP callable that returns a string representation of the log message.
* @param callable|null $prefix A PHP callable that returns a string to be prefixed to every exported message.
* @param string|null $timestampFormat The date format for the log timestamp.
* @param int $exportInterval How many messages should be accumulated before they are exported.
* @param bool|callable $enabled Whether this target is enabled, or a PHP callable that returns a boolean.
*/
public function __construct(array $levels = [])
{
$this->categories = new CategoryFilter();
$this->formatter = new Formatter();
public function __construct(
Comment thread
WarLikeLaux marked this conversation as resolved.
array $levels = [],
array $categories = [],
array $exceptCategories = [],
?callable $format = null,
?callable $prefix = null,
?string $timestampFormat = null,
private int $exportInterval = self::DEFAULT_EXPORT_INTERVAL,
bool|callable $enabled = true,
) {
$this->categories = new CategoryFilter($categories, $exceptCategories);
$this->formatter = new Formatter($format, $prefix, $timestampFormat);
/** @psalm-suppress DeprecatedMethod */
$this->setLevels($levels);
$this->enabled = $enabled;
}

/**
Expand Down Expand Up @@ -119,6 +134,8 @@ public function collect(array $messages, bool $final): void
* @return self
*
* @see CategoryFilter::$include
*
* @deprecated To be removed in 3.0. Use the `$categories` constructor parameter instead.
*/
public function setCategories(array $categories): self
{
Expand All @@ -136,6 +153,8 @@ public function setCategories(array $categories): self
* @return self
*
* @see CategoryFilter::$exclude
*
* @deprecated To be removed in 3.0. Use the `$exceptCategories` constructor parameter instead.
*/
public function setExcept(array $except): self
{
Expand All @@ -144,7 +163,7 @@ public function setExcept(array $except): self
}

/**
* Sets a list of {@see \Psr\Log\LogLevel log message levels} that current target is interested in.
* Sets a list of {@see LogLevel log message levels} that current target is interested in.
*
* @param string[] $levels The list of log message levels.
*
Expand All @@ -153,12 +172,13 @@ public function setExcept(array $except): self
* @return self
*
* @see Target::$levels
*
* @deprecated To be removed in 3.0. Use the `$levels` constructor parameter instead.
*/
public function setLevels(array $levels): self
{
foreach ($levels as $key => $level) {
foreach ($levels as $level) {
Logger::assertLevelIsValid($level);
$levels[$key] = $level;
}

$this->levels = $levels;
Expand Down Expand Up @@ -190,6 +210,8 @@ public function setCommonContext(array $commonContext): self
* @return self
*
* @see Formatter::$format
*
* @deprecated To be removed in 3.0. Use the `$format` constructor parameter instead.
*/
public function setFormat(callable $format): self
{
Expand All @@ -205,6 +227,8 @@ public function setFormat(callable $format): self
* @return self
*
* @see Formatter::$prefix
*
* @deprecated To be removed in 3.0. Use the `$prefix` constructor parameter instead.
*/
public function setPrefix(callable $prefix): self
{
Expand All @@ -220,6 +244,8 @@ public function setPrefix(callable $prefix): self
* @return self
*
* @see Target::$exportInterval
*
* @deprecated To be removed in 3.0. Use the `$exportInterval` constructor parameter instead.
*/
public function setExportInterval(int $exportInterval): self
{
Expand All @@ -235,6 +261,8 @@ public function setExportInterval(int $exportInterval): self
* @return self
*
* @see Target::$timestampFormat
*
* @deprecated To be removed in 3.0. Use the `$timestampFormat` constructor parameter instead.
*/
public function setTimestampFormat(string $format): self
{
Expand All @@ -252,6 +280,8 @@ public function setTimestampFormat(string $format): self
* @return self
*
* @see Target::$enabled
*
* @deprecated To be removed in 3.0. Use the `$enabled` constructor parameter instead.
*/
public function setEnabled(callable $value): self
{
Expand Down
Loading
Loading