From bdf31a88c74bea0a912c1646125fa5e77b149593 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Thu, 6 Feb 2025 10:34:01 +0200 Subject: [PATCH 1/5] implemented PSR3 Signed-off-by: Jurj-Bogdan --- README.md | 40 ++--- composer.json | 8 +- docs/book/v4/overview.md | 2 - docs/book/v4/usage.md | 2 +- docs/book/v5/adding-config-provider.md | 11 ++ docs/book/v5/configuring-writer.md | 43 +++++ docs/book/v5/example-with-formatter.md | 41 +++++ docs/book/v5/filtering-log-messages.md | 95 ++++++++++ docs/book/v5/formatting-messages.md | 19 ++ docs/book/v5/grouping-log-files-by-date.md | 12 ++ docs/book/v5/overview.md | 3 + docs/book/v5/usage.md | 26 +++ log.global.php.dist | 4 +- mkdocs.yml | 12 +- src/Filter/Level.php | 54 ++++++ src/Filter/Priority.php | 54 ------ src/Formatter/Simple.php | 2 +- src/Logger.php | 162 ++++++------------ src/LoggerInterface.php | 24 --- src/Manager/FilterPluginManager.php | 6 +- src/Processor/Backtrace.php | 8 +- src/Processor/PsrPlaceholder.php | 2 +- src/Processor/ReferenceId.php | 8 +- src/Processor/RequestId.php | 8 +- src/Writer/AbstractWriter.php | 4 +- .../{PriorityTest.php => LevelTest.php} | 24 +-- test/Formatter/SimpleTest.php | 2 +- test/LoggerServiceFactoryTest.php | 8 +- test/LoggerTest.php | 59 ++++--- test/Manager/FilterPluginManagerTest.php | 4 +- test/Manager/FormatterPluginManagerTest.php | 6 +- test/Processor/BackTraceTest.php | 2 +- test/Processor/PsrPlaceholderTest.php | 2 +- test/Processor/ReferenceIdTest.php | 4 +- test/Processor/RequestIdTest.php | 4 +- test/Writer/StreamTest.php | 4 +- 36 files changed, 478 insertions(+), 291 deletions(-) create mode 100644 docs/book/v5/adding-config-provider.md create mode 100644 docs/book/v5/configuring-writer.md create mode 100644 docs/book/v5/example-with-formatter.md create mode 100644 docs/book/v5/filtering-log-messages.md create mode 100644 docs/book/v5/formatting-messages.md create mode 100644 docs/book/v5/grouping-log-files-by-date.md create mode 100644 docs/book/v5/overview.md create mode 100644 docs/book/v5/usage.md create mode 100644 src/Filter/Level.php delete mode 100644 src/Filter/Priority.php delete mode 100644 src/LoggerInterface.php rename test/Filter/{PriorityTest.php => LevelTest.php} (60%) diff --git a/README.md b/README.md index 6fe050d..2ee8fdf 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 + 'level' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', ], @@ -58,9 +58,9 @@ return [ * The `FileWriter` key is optional, otherwise the writers array would be enumerative instead of associative. * The writer name key is a developer-provided name for that writer, the writer name key is **mandatory**. -The writer priority key is not affecting the errors that are written, it is a way to organize writers. +The writer level key is not affecting the errors that are written, it is a way to organize writers. -The writer priority key is optional. +The writer level key is optional. To write into a file the key stream must be present in the writer options array. This is required only if writing into streams/files. @@ -79,7 +79,7 @@ The full list of format specifiers is available [here](https://www.php.net/manua As per PSR-3 document. -The log levels are: emergency (0), alert (1), critical (2), error (3), warn (4), notice (5), info (6), debug (7) (in order of priority/importance) +The log levels are: emergency (0), alert (1), critical (2), error (3), warn (4), notice (5), info (6), debug (7) (in order of level/importance) Although the plain Logger in Dot Log is not fully compatible with PSR-3, it provides a way to log all of these message types. @@ -98,16 +98,16 @@ return [ 'my_logger' => [ 'writers' => [ 'FileWriter' => [ - 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'name' => 'FileWriter', + 'level' => \Dot\Log\Manager\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', 'filters' => [ 'allMessages' => [ - 'name' => 'priority', + 'name' => 'level', 'options' => [ 'operator' => '>=', - 'priority' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Manager\Logger::EMERG, ] ], ], @@ -115,16 +115,16 @@ return [ ], // Only warnings 'OnlyWarningsWriter' => [ - 'name' => 'stream', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'name' => 'stream', + 'level' => \Dot\Log\Manager\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/warnings_only.log', 'filters' => [ 'warningOnly' => [ - 'name' => 'priority', + 'name' => 'level', 'options' => [ 'operator' => '==', - 'priority' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Manager\Logger::WARN, ], ], ], @@ -133,17 +133,17 @@ return [ // Warnings and more important messages 'WarningOrHigherWriter' => [ 'name' => 'stream', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Manager\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/important_messages.log', 'filters' => [ 'importantMessages' => [ - 'name' => 'priority', + 'name' => 'level', 'options' => [ - // note, the smaller the priority, the more important is the message + // note, the smaller the level, the more important is the message // 0 - emergency, 1 - alert, 2- error, 3 - warn. .etc 'operator' => '<=', - 'priority' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Manager\Logger::WARN, ], ], ], @@ -203,17 +203,17 @@ return [ 'my_logger' => [ 'writers' => [ 'FileWriter' => [ - 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'name' => 'FileWriter', + 'level' => \Dot\Log\Manager\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', // explicitly log all messages 'filters' => [ 'allMessages' => [ - 'name' => 'priority', + 'name' => 'level', 'options' => [ 'operator' => '>=', - 'priority' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Manager\Logger::EMERG, ], ], ], diff --git a/composer.json b/composer.json index c205fe4..a5f4b36 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "dotkernel/dot-log", "type": "library", - "description": "Dotkernel log component extending and customizing laminas-log", + "description": "Dotkernel log component implementing PSR-3", "license": "MIT", "homepage": "https://github.com/dotkernel/dot-log", "keywords": [ @@ -9,8 +9,7 @@ "logging", "services", "mezzio", - "laminas", - "laminas-log" + "laminas" ], "authors": [ { @@ -21,7 +20,8 @@ "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "laminas/laminas-servicemanager": "^4.0", - "laminas/laminas-validator": "^3.0" + "laminas/laminas-validator": "^3.0", + "psr/log": "^3.0.2" }, "require-dev": { "laminas/laminas-coding-standard": "^3.0", diff --git a/docs/book/v4/overview.md b/docs/book/v4/overview.md index 615aaf0..89f6888 100644 --- a/docs/book/v4/overview.md +++ b/docs/book/v4/overview.md @@ -1,5 +1,3 @@ # Overview Robust, composite logger with filtering, formatting, and PSR-3 support. - -> dot-log is a wrapper on top of [laminas-log](https://github.com/laminas/laminas-log) diff --git a/docs/book/v4/usage.md b/docs/book/v4/usage.md index e479b9c..74778b9 100644 --- a/docs/book/v4/usage.md +++ b/docs/book/v4/usage.md @@ -5,7 +5,7 @@ Basic usage of the logger is illustrated below. The messages are written to see which logs are written and which are not written. ```php -use Dot\Log\Manager\Logger; +use Dot\Log\Logger; ``` ... diff --git a/docs/book/v5/adding-config-provider.md b/docs/book/v5/adding-config-provider.md new file mode 100644 index 0000000..98abb06 --- /dev/null +++ b/docs/book/v5/adding-config-provider.md @@ -0,0 +1,11 @@ +# Adding The Config Provider + +* In `config/config.php` add an entry for the config provider `\Dot\Log\ConfigProvider::class` + * Make sure it is added before with the Application-Specific components, eg.: + * `\Frontend\App\ConfigProvider.php` + * `\Admin\App\ConfigProvider::class` + * `\MyProject\ConfigProvider::class` etc. +* Add the logger configuration in an autoload config file, e.g. you can create `config/autoload/logger.global.php`. Follow the `Configuring the writer(s)` chapter for a simple working example. + +> `Dot\Log\ConfigProvider` has an abstract factory `LoggerAbstractServiceFactory::class` which corresponds to the alias, not the class name. +> Instead of requesting `Dot\Log\Logger::class` from the container, use `dot-log.my_logger`. diff --git a/docs/book/v5/configuring-writer.md b/docs/book/v5/configuring-writer.md new file mode 100644 index 0000000..c9dd904 --- /dev/null +++ b/docs/book/v5/configuring-writer.md @@ -0,0 +1,43 @@ +# Configuring the writer(s) + +Loggers must have at least one writer. + +A writer is an object that inherits from `Dot\Log\Writer\AbstractWriter`. +A writer's responsibility is to record log data to a storage backend. + +## Writing to a file (stream) + +You can separate logs into multiple files using writers and filters. +For example *warnings.log*, *errors.log*, *all_messages.log*. + +The following is the simplest example to write all log messages to `/log/dk.log`: + +```php +return [ + 'dot_log' => [ + 'loggers' => [ + 'my_logger' => [ + 'writers' => [ + 'FileWriter' => [ + 'name' => 'FileWriter', + 'level' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 + 'options' => [ + 'stream' => __DIR__ . '/../../log/dk.log', + ], + ], + ], + ] + ], + ], +]; +``` + +* The `FileWriter` key is optional, otherwise the writers array would be enumerative instead of associative. +* The `name` key is a developer-provided name for that writer, the writer name key is **mandatory**. + +The `level` key does not affect the errors that are written. +It is a way to organize writers. + +The `level` key is optional. + +The key `stream` is required only if writing into streams/files. diff --git a/docs/book/v5/example-with-formatter.md b/docs/book/v5/example-with-formatter.md new file mode 100644 index 0000000..8febee3 --- /dev/null +++ b/docs/book/v5/example-with-formatter.md @@ -0,0 +1,41 @@ +# Example with formatter + +* The log is used through `dot-log` +* The logger name is `my_logger` +* It writes to file: `log/dk.log` +* It is configured to explicitly write all messages +* The messages are formatted as JSON + +```php + [ + 'loggers' => [ + 'my_logger' => [ + 'writers' => [ + 'FileWriter' => [ + 'name' => 'FileWriter', + 'level' => \Dot\Log\Manager\Logger::ALERT, + 'options' => [ + 'stream' => __DIR__ . '/../../log/dk.log', + // explicitly log all messages + 'filters' => [ + 'allMessages' => [ + 'name' => 'level', + 'options' => [ + 'operator' => '>=', + 'level' => \Dot\Log\Manager\Logger::EMERG, + ], + ], + ], + 'formatter' => [ + 'name' => \Dot\Log\Manager\Formatter\Json::class, + ], + ], + ], + ], + ], + ], + ], +]; +``` diff --git a/docs/book/v5/filtering-log-messages.md b/docs/book/v5/filtering-log-messages.md new file mode 100644 index 0000000..e4a2d7f --- /dev/null +++ b/docs/book/v5/filtering-log-messages.md @@ -0,0 +1,95 @@ +# Filtering log messages + +The following conforms to the `PSR-3: Logger Interface` document. + +The log levels are in order of level/importance: + +* emergency (0) +* alert (1) +* critical (2) +* error (3) +* warning (4) +* notice (5) +* info (6) +* debug (7) + +Although the plain Logger in `dot-log` is not fully compatible with PSR-3, it provides a way to log all of these message types. + +The following example has three file writers using filters: + +* First Example: `FileWriter` - All messages are logged in `/log/dk.log` +* Second Example: `OnlyWarningsWriter` - Only warnings are logged in `/log/warnings.log` +* Third Example: `WarningOrHigherWriter` - All important messages (`warnings` or critical) are logged in `/log/important_messages.log` + +```php + [ + 'loggers' => [ + 'my_logger' => [ + 'writers' => [ + 'FileWriter' => [ + 'name' => 'FileWriter', + 'level' => \Dot\Log\Manager\Logger::ALERT, + 'options' => [ + 'stream' => __DIR__ . '/../../log/dk.log', + 'filters' => [ + 'allMessages' => [ + 'name' => 'level', + 'options' => [ + 'operator' => '>=', + 'level' => \Dot\Log\Manager\Logger::EMERG, + ] + ], + ], + ], + ], + // Only warnings + 'OnlyWarningsWriter' => [ + 'name' => 'stream', + 'level' => \Dot\Log\Manager\Logger::ALERT, + 'options' => [ + 'stream' => __DIR__ . '/../../log/warnings_only.log', + 'filters' => [ + 'warningOnly' => [ + 'name' => 'level', + 'options' => [ + 'operator' => '==', + 'level' => \Dot\Log\Manager\Logger::WARN, + ], + ], + ], + ], + ], + // Warnings and more important messages + 'WarningOrHigherWriter' => [ + 'name' => 'stream', + 'level' => \Dot\Log\Manager\Logger::ALERT, + 'options' => [ + 'stream' => __DIR__ . '/../../log/important_messages.log', + 'filters' => [ + 'importantMessages' => [ + 'name' => 'level', + 'options' => [ + // note, the smaller the level, the more important is the message + // 0 - emergency, 1 - alert, 2- error, 3 - warn etc. + 'operator' => '<=', + 'level' => \Dot\Log\Manager\Logger::WARN, + ], + ], + ], + ], + ], + ], + ], + ], + ], +]; +``` + +As in the writer configuration, the developer can optionally use keys for associating the filters with a name. + +> The operator for more important messages is `<=`, this is because the number representation is smaller for a more important message type. + +The filter added on the first writer is equivalent to not setting a filter, but it was added to illustrate the usage of the operator to explicitly allow all messages. diff --git a/docs/book/v5/formatting-messages.md b/docs/book/v5/formatting-messages.md new file mode 100644 index 0000000..4b2771c --- /dev/null +++ b/docs/book/v5/formatting-messages.md @@ -0,0 +1,19 @@ +# Formatting Messages + +When using `dot-log`, the logged value is not limited to a string. +Arrays can be logged as well. +For better readability, these arrays can be serialized. +DotLog provides String and JSON formatting. + +The formatter accepts following parameters: + +* name - the formatter class (it must implement `Dot\Log\Formatter\FormatterInterface`) +* options - passed to the formatter constructor if required + +The following snippet formats the message as JSON data: + +```php +'formatter' => [ + 'name' => \Dot\Log\Formatter\Json::class, +], +``` diff --git a/docs/book/v5/grouping-log-files-by-date.md b/docs/book/v5/grouping-log-files-by-date.md new file mode 100644 index 0000000..71c072a --- /dev/null +++ b/docs/book/v5/grouping-log-files-by-date.md @@ -0,0 +1,12 @@ +# Grouping log files by date + +By default, logs will be written to the same file: `log/dk.log`. + +Optionally, you can use date format specifiers wrapped between curly braces in your FileWriter's `stream` option to automatically group your logs by day, week, month, year etc. + +Examples: + +* `log/dk-{Y}-{m}-{d}.log` will create a new log file each day (eg: log/dk-2021-01-01.log) +* `log/dk-{Y}-{W}.log` will create a new log file each week (eg: log/dk-2021-10.log) + +The full list of format specifiers is available in the [PHP docs for datetime formatting](https://www.php.net/manual/en/datetime.format.php). diff --git a/docs/book/v5/overview.md b/docs/book/v5/overview.md new file mode 100644 index 0000000..89f6888 --- /dev/null +++ b/docs/book/v5/overview.md @@ -0,0 +1,3 @@ +# Overview + +Robust, composite logger with filtering, formatting, and PSR-3 support. diff --git a/docs/book/v5/usage.md b/docs/book/v5/usage.md new file mode 100644 index 0000000..08e692e --- /dev/null +++ b/docs/book/v5/usage.md @@ -0,0 +1,26 @@ +# Usage + +Basic usage of the logger is illustrated below. + +The messages are written to see which logs are written and which are not written. + +```php +use Dot\Log\Logger; +``` + +... + +```php +$logger = $container->get('dot-log.my_logger'); + +/** @var Logger $logger */ +$logger->emergency('0 EMERG'); +$logger->alert('1 ALERT'); +$logger->critical('2 CRITICAL'); +$logger->error('3 ERR'); +$logger->warning('4 WARN'); +$logger->notice('5 NOTICE'); +$logger->info('6 INF'); +$logger->debug('7 debug'); +$logger->log(Logger::NOTICE, 'NOTICE from log()'); +``` diff --git a/log.global.php.dist b/log.global.php.dist index 809e236..ddc18b7 100644 --- a/log.global.php.dist +++ b/log.global.php.dist @@ -6,8 +6,8 @@ return [ //define log services here 'stream_logger' => [ 'writers' => [ - 'name' => 'stream', - 'priority' => \Dot\Log\Logger::DEBUG, + 'name' => 'stream', + 'level' => \Dot\Log\Logger::DEBUG, 'options' => [ 'stream' => 'php://output', 'formatter' => [ diff --git a/mkdocs.yml b/mkdocs.yml index 5638928..cfefe4a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,12 +2,22 @@ docs_dir: docs/book site_dir: docs/html extra: project: Packages - current_version: v4 + current_version: v5 versions: - v4 - v3 + - v5 nav: - Home: index.md + - v5: + - "Overview": v5/overview.md + - "Adding The Config Provider": v5/adding-config-provider.md + - "Configuring the writer(s)": v5/configuring-writer.md + - "Grouping log files by date": v5/grouping-log-files-by-date.md + - "Filtering log messages": v5/filtering-log-messages.md + - "Formatting Messages": v5/formatting-messages.md + - "Example with formatter": v5/example-with-formatter.md + - "Usage": v5/usage.md - v4: - "Overview": v4/overview.md - "Adding The Config Provider": v4/adding-config-provider.md diff --git a/src/Filter/Level.php b/src/Filter/Level.php new file mode 100644 index 0000000..c5ae852 --- /dev/null +++ b/src/Filter/Level.php @@ -0,0 +1,54 @@ +level = $level; + $this->operator = $operator ?? '<='; + } + + /** + * Returns TRUE to accept the message, FALSE to block it. + */ + public function filter(array $event): bool|int|null + { + return version_compare((string) $event['level'], (string) $this->level, $this->operator); + } +} diff --git a/src/Filter/Priority.php b/src/Filter/Priority.php deleted file mode 100644 index 0b05cb3..0000000 --- a/src/Filter/Priority.php +++ /dev/null @@ -1,54 +0,0 @@ -priority = $priority; - $this->operator = $operator ?? '<='; - } - - /** - * Returns TRUE to accept the message, FALSE to block it. - */ - public function filter(array $event): bool|int|null - { - return version_compare((string) $event['priority'], (string) $this->priority, $this->operator); - } -} diff --git a/src/Formatter/Simple.php b/src/Formatter/Simple.php index b026de7..3c8771c 100644 --- a/src/Formatter/Simple.php +++ b/src/Formatter/Simple.php @@ -18,7 +18,7 @@ class Simple extends Base { - public const DEFAULT_FORMAT = '%timestamp% %priorityName% (%priority%): %message% %extra%'; + public const DEFAULT_FORMAT = '%timestamp% %levelName% (%level%): %message% %extra%'; /** * Format specifier for log messages diff --git a/src/Logger.php b/src/Logger.php index 2a92990..a84d0db 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -18,6 +18,9 @@ use Laminas\Stdlib\ArrayUtils; use Laminas\Stdlib\SplPriorityQueue; use Psr\Container\ContainerExceptionInterface; +use Psr\Log\AbstractLogger; +use Psr\Log\LogLevel; +use Stringable; use Traversable; use function array_reverse; @@ -26,9 +29,7 @@ use function error_reporting; use function in_array; use function is_array; -use function is_object; use function is_string; -use function method_exists; use function register_shutdown_function; use function restore_error_handler; use function restore_exception_handler; @@ -52,7 +53,7 @@ use const E_USER_WARNING; use const E_WARNING; -class Logger implements LoggerInterface +class Logger extends AbstractLogger { /** * @link http://tools.ietf.org/html/rfc3164 @@ -69,9 +70,9 @@ class Logger implements LoggerInterface public const DEBUG = 7; /** - * Map native PHP errors to priority + * Map native PHP errors to level */ - public static array $errorPriorityMap = [ + public static array $errorLevelMap = [ E_NOTICE => self::NOTICE, E_USER_NOTICE => self::NOTICE, E_WARNING => self::WARN, @@ -104,17 +105,17 @@ class Logger implements LoggerInterface protected static bool $registeredExceptionHandler = false; /** - * List of priority code => priority (short) name + * List of level code => level (short) name */ - protected array $priorities = [ - self::EMERG => 'EMERG', - self::ALERT => 'ALERT', - self::CRIT => 'CRIT', - self::ERR => 'ERR', - self::WARN => 'WARN', - self::NOTICE => 'NOTICE', - self::INFO => 'INFO', - self::DEBUG => 'DEBUG', + protected array $levels = [ + self::EMERG => LogLevel::EMERGENCY, + self::ALERT => LogLevel::ALERT, + self::CRIT => LogLevel::CRITICAL, + self::ERR => LogLevel::ERROR, + self::WARN => LogLevel::WARNING, + self::NOTICE => LogLevel::NOTICE, + self::INFO => LogLevel::INFO, + self::DEBUG => LogLevel::DEBUG, ]; protected SplPriorityQueue $writers; @@ -170,10 +171,10 @@ public function __construct(?iterable $options = null) throw new InvalidArgumentException('Options must contain a name for the writer'); } - $priority = $writer['priority'] ?? null; + $level = $writer['level'] ?? null; $writerOptions = $writer['options'] ?? null; - $this->addWriter($writer['name'], $priority, $writerOptions); + $this->addWriter($writer['name'], $level, $writerOptions); } } @@ -183,10 +184,10 @@ public function __construct(?iterable $options = null) throw new InvalidArgumentException('Options must contain a name for the processor'); } - $priority = $processor['priority'] ?? null; + $level = $processor['level'] ?? null; $processorOptions = $processor['options'] ?? null; - $this->addProcessor($processor['name'], $priority, $processorOptions); + $this->addProcessor($processor['name'], $level, $processorOptions); } } @@ -245,7 +246,7 @@ public function writerPlugin(string $name, ?array $options = null): ?WriterInter * * @throws ContainerExceptionInterface */ - public function addWriter(WriterInterface|string $writer, int $priority = 1, ?array $options = null): static + public function addWriter(WriterInterface|string $writer, int $level = 1, ?array $options = null): static { if (is_string($writer)) { $writer = $this->writerPlugin($writer, $options); @@ -256,7 +257,7 @@ public function addWriter(WriterInterface|string $writer, int $priority = 1, ?ar $writer::class )); } - $this->writers->insert($writer, $priority); + $this->writers->insert($writer, $level); return $this; } @@ -320,7 +321,7 @@ public function processorPlugin(string $name, ?array $options = null): ?Processo */ public function addProcessor( ProcessorInterface|string $processor, - int $priority = 1, + int $level = 1, ?array $options = null ): static { if (is_string($processor)) { @@ -331,7 +332,7 @@ public function addProcessor( $processor::class )); } - $this->processors->insert($processor, $priority); + $this->processors->insert($processor, $level); return $this; } @@ -341,27 +342,18 @@ public function getProcessors(): SplPriorityQueue return $this->processors; } - public function log(int $priority, mixed $message, iterable $extra = []): static + public function log(mixed $level, string|Stringable $message, iterable $context = []): void { - if (($priority < 0) || ($priority >= count($this->priorities))) { + if (($level < 0) || ($level >= count($this->levels))) { throw new InvalidArgumentException(sprintf( - '$priority must be an integer >= 0 and < %d; received %s', - count($this->priorities), - var_export($priority, true) + '$level must be an integer >= 0 and < %d; received %s', + count($this->levels), + var_export($level, true) )); } - if (is_object($message) && ! method_exists($message, '__toString')) { - throw new InvalidArgumentException( - '$message must implement magic __toString() method' - ); - } - if (! is_array($extra) && ! $extra instanceof Traversable) { - throw new InvalidArgumentException( - '$extra must be an array or implement Traversable' - ); - } elseif ($extra instanceof Traversable) { - $extra = ArrayUtils::iteratorToArray($extra); + if ($context instanceof Traversable) { + $context = ArrayUtils::iteratorToArray($context); } if ($this->writers->count() === 0) { @@ -370,16 +362,12 @@ public function log(int $priority, mixed $message, iterable $extra = []): static $timestamp = new DateTime(); - if (is_array($message)) { - $message = var_export($message, true); - } - $event = [ - 'timestamp' => $timestamp, - 'priority' => $priority, - 'priorityName' => $this->priorities[$priority], - 'message' => (string) $message, - 'extra' => $extra, + 'timestamp' => $timestamp, + 'level' => $level, + 'levelName' => $this->levels[$level], + 'message' => (string) $message, + 'context' => $context, ]; /** @var ProcessorInterface $processor */ @@ -391,48 +379,6 @@ public function log(int $priority, mixed $message, iterable $extra = []): static foreach ($this->writers->toArray() as $writer) { $writer->write($event); } - - return $this; - } - - public function emerg(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::EMERG, $message, $extra); - } - - public function alert(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::ALERT, $message, $extra); - } - - public function crit(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::CRIT, $message, $extra); - } - - public function err(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::ERR, $message, $extra); - } - - public function warn(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::WARN, $message, $extra); - } - - public function notice(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::NOTICE, $message, $extra); - } - - public function info(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::INFO, $message, $extra); - } - - public function debug(string $message, iterable $extra = []): LoggerInterface - { - return $this->log(self::DEBUG, $message, $extra); } /** @@ -447,19 +393,19 @@ public static function registerErrorHandler(Logger $logger, bool $continueNative return false; } - $errorPriorityMap = static::$errorPriorityMap; + $errorLevelMap = static::$errorLevelMap; $previous = set_error_handler( - function ($level, $message, $file, $line) use ($logger, $errorPriorityMap, $continueNativeHandler) { + function ($level, $message, $file, $line) use ($logger, $errorLevelMap, $continueNativeHandler) { $iniLevel = error_reporting(); if ($iniLevel & $level) { - if (isset($errorPriorityMap[$level])) { - $priority = $errorPriorityMap[$level]; + if (isset($errorLevelMap[$level])) { + $level = $errorLevelMap[$level]; } else { - $priority = Logger::INFO; + $level = Logger::INFO; } - $logger->log($priority, $message, [ + $logger->log($level, $message, [ 'errno' => $level, 'file' => $file, 'line' => $line, @@ -492,9 +438,9 @@ public static function registerFatalErrorShutdownFunction(Logger $logger): bool return false; } - $errorPriorityMap = static::$errorPriorityMap; + $errorLevelMap = static::$errorLevelMap; - register_shutdown_function(function () use ($logger, $errorPriorityMap) { + register_shutdown_function(function () use ($logger, $errorLevelMap) { $error = error_get_last(); if ( @@ -516,7 +462,7 @@ public static function registerFatalErrorShutdownFunction(Logger $logger): bool } $logger->log( - $errorPriorityMap[$error['type']], + $errorLevelMap[$error['type']], $error['message'], [ 'file' => $error['file'], @@ -542,15 +488,15 @@ public static function registerExceptionHandler(Logger $logger): bool return false; } - $errorPriorityMap = static::$errorPriorityMap; + $errorLevelMap = static::$errorLevelMap; - set_exception_handler(function ($exception) use ($logger, $errorPriorityMap) { + set_exception_handler(function ($exception) use ($logger, $errorLevelMap) { $logMessages = []; do { - $priority = Logger::ERR; - if ($exception instanceof ErrorException && isset($errorPriorityMap[$exception->getSeverity()])) { - $priority = $errorPriorityMap[$exception->getSeverity()]; + $level = Logger::ERR; + if ($exception instanceof ErrorException && isset($errorLevelMap[$exception->getSeverity()])) { + $level = $errorLevelMap[$exception->getSeverity()]; } $extra = [ @@ -560,15 +506,15 @@ public static function registerExceptionHandler(Logger $logger): bool ]; $logMessages[] = [ - 'priority' => $priority, - 'message' => $exception->getMessage(), - 'extra' => $extra, + 'level' => $level, + 'message' => $exception->getMessage(), + 'extra' => $extra, ]; $exception = $exception->getPrevious(); } while ($exception); foreach (array_reverse($logMessages) as $logMessage) { - $logger->log($logMessage['priority'], $logMessage['message'], $logMessage['extra']); + $logger->log($logMessage['level'], $logMessage['message'], $logMessage['extra']); } }); diff --git a/src/LoggerInterface.php b/src/LoggerInterface.php deleted file mode 100644 index 125bce6..0000000 --- a/src/LoggerInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - Priority::class, + 'level' => Level::class, 'regex' => Regex::class, 'suppress' => SuppressFilter::class, 'suppressfilter' => SuppressFilter::class, @@ -34,7 +34,7 @@ class FilterPluginManager extends AbstractPluginManager /** @var string[]|callable[] */ protected array $factories = [ - Priority::class => InvokableFactory::class, + Level::class => InvokableFactory::class, Regex::class => InvokableFactory::class, SuppressFilter::class => InvokableFactory::class, Validator::class => InvokableFactory::class, diff --git a/src/Processor/Backtrace.php b/src/Processor/Backtrace.php index ee5c2ca..b484284 100644 --- a/src/Processor/Backtrace.php +++ b/src/Processor/Backtrace.php @@ -59,11 +59,11 @@ public function process(array $event): array 'function' => $trace[$i]['function'] ?? null, ]; - $extra = $origin; - if (isset($event['extra'])) { - $extra = array_merge($origin, $event['extra']); + $context = $origin; + if (isset($event['context'])) { + $context = array_merge($origin, $event['context']); } - $event['extra'] = $extra; + $event['context'] = $context; return $event; } diff --git a/src/Processor/PsrPlaceholder.php b/src/Processor/PsrPlaceholder.php index 709a481..3a93c68 100644 --- a/src/Processor/PsrPlaceholder.php +++ b/src/Processor/PsrPlaceholder.php @@ -20,7 +20,7 @@ public function process(array $event): array } $replacements = []; - foreach ($event['extra'] as $key => $val) { + foreach ($event['context'] as $key => $val) { if ( $val === null || is_scalar($val) diff --git a/src/Processor/ReferenceId.php b/src/Processor/ReferenceId.php index b008d2a..ccdbb07 100644 --- a/src/Processor/ReferenceId.php +++ b/src/Processor/ReferenceId.php @@ -13,15 +13,15 @@ class ReferenceId extends RequestId implements ProcessorInterface */ public function process(array $event): array { - if (isset($event['extra']['referenceId'])) { + if (isset($event['context']['referenceId'])) { return $event; } - if (! isset($event['extra'])) { - $event['extra'] = []; + if (! isset($event['context'])) { + $event['context'] = []; } - $event['extra']['referenceId'] = $this->getIdentifier(); + $event['context']['referenceId'] = $this->getIdentifier(); return $event; } diff --git a/src/Processor/RequestId.php b/src/Processor/RequestId.php index e603397..dc2fcc7 100644 --- a/src/Processor/RequestId.php +++ b/src/Processor/RequestId.php @@ -17,15 +17,15 @@ class RequestId implements ProcessorInterface */ public function process(array $event): array { - if (isset($event['extra']['requestId'])) { + if (isset($event['context']['requestId'])) { return $event; } - if (! isset($event['extra'])) { - $event['extra'] = []; + if (! isset($event['context'])) { + $event['context'] = []; } - $event['extra']['requestId'] = $this->getIdentifier(); + $event['context']['requestId'] = $this->getIdentifier(); return $event; } diff --git a/src/Writer/AbstractWriter.php b/src/Writer/AbstractWriter.php index 18cfbb1..d9ff319 100644 --- a/src/Writer/AbstractWriter.php +++ b/src/Writer/AbstractWriter.php @@ -7,7 +7,7 @@ use Dot\Log\Exception\InvalidArgumentException; use Dot\Log\Exception\RuntimeException; use Dot\Log\Filter\FilterInterface; -use Dot\Log\Filter\Priority; +use Dot\Log\Filter\Level; use Dot\Log\Formatter\FormatterInterface; use Dot\Log\Manager\FilterPluginManager; use Dot\Log\Manager\FormatterPluginManager; @@ -123,7 +123,7 @@ public function __construct(?iterable $options = null) public function addFilter(int|string|FilterInterface $filter, ?array $options = null): WriterInterface { if (is_int($filter)) { - $filter = new Priority($filter); + $filter = new Level($filter); } if (is_string($filter)) { diff --git a/test/Filter/PriorityTest.php b/test/Filter/LevelTest.php similarity index 60% rename from test/Filter/PriorityTest.php rename to test/Filter/LevelTest.php index c80417d..262dea2 100644 --- a/test/Filter/PriorityTest.php +++ b/test/Filter/LevelTest.php @@ -5,44 +5,44 @@ namespace DotTest\Log\Filter; use Dot\Log\Exception\InvalidArgumentException; -use Dot\Log\Filter\Priority; +use Dot\Log\Filter\Level; use PHPUnit\Framework\TestCase; -class PriorityTest extends TestCase +class LevelTest extends TestCase { - private Priority $subject; + private Level $subject; public function setUp(): void { - $this->subject = new Priority(47); + $this->subject = new Level(47); } public function testWillInstantiateWithInt(): void { - $this->assertInstanceOf(Priority::class, $this->subject); + $this->assertInstanceOf(Level::class, $this->subject); } public function testWillInstantiateWithArray(): void { - $input = ['priority' => 47]; + $input = ['level' => 47]; - $result = new Priority($input); + $result = new Level($input); - $this->assertInstanceOf(Priority::class, $result); + $this->assertInstanceOf(Level::class, $result); } public function testWillNotInstantiateWithEmptyArray(): void { $input = []; - $this->expectExceptionMessage('Priority must be a number, received "NULL"'); + $this->expectExceptionMessage('Level must be a number, received "NULL"'); $this->expectException(InvalidArgumentException::class); - new Priority($input); + new Level($input); } public function testFilterWillAcceptMessage(): void { - $input = ['priority' => 47]; + $input = ['level' => 47]; $result = $this->subject->filter($input); @@ -51,7 +51,7 @@ public function testFilterWillAcceptMessage(): void public function testFilterWillNotAcceptMessage(): void { - $input = ['priority' => 244]; + $input = ['level' => 244]; $result = $this->subject->filter($input); diff --git a/test/Formatter/SimpleTest.php b/test/Formatter/SimpleTest.php index 7cee499..5b29257 100644 --- a/test/Formatter/SimpleTest.php +++ b/test/Formatter/SimpleTest.php @@ -32,7 +32,7 @@ public function testWillNotInstantiate(): void public function testFormat(): void { - $input = ['message' => 'Test Message', 'priorityName' => 'Critical']; + $input = ['message' => 'Test Message', 'levelName' => 'Critical']; $result = $this->subject->format($input); $this->assertIsString($result); } diff --git a/test/LoggerServiceFactoryTest.php b/test/LoggerServiceFactoryTest.php index fc7986c..b9a055b 100644 --- a/test/LoggerServiceFactoryTest.php +++ b/test/LoggerServiceFactoryTest.php @@ -101,7 +101,7 @@ public function testWillInjectWriterPluginManagerIfAvailable(): void 'LogWriterManager' => $writers, 'config' => [ 'log' => [ - 'writers' => [['name' => 'noop', 'priority' => 1]], + 'writers' => [['name' => 'noop', 'level' => 1]], ], ], ], @@ -129,8 +129,8 @@ public function testWillInjectProcessorPluginManagerIfAvailable(): void 'LogProcessorManager' => $processors, 'config' => [ 'log' => [ - 'writers' => [['name' => Noop::class, 'priority' => 1]], - 'processors' => [['name' => 'psrplaceholder', 'priority' => 1]], + 'writers' => [['name' => Noop::class, 'level' => 1]], + 'processors' => [['name' => 'psrplaceholder', 'level' => 1]], ], ], ], @@ -174,7 +174,7 @@ public static function dataWritersValues(): array 'number' => [1e3, 0], 'object' => [new stdClass(), 0], 'empty iterable' => [new ArrayObject(), 0], - 'iterable' => [new ArrayObject([['name' => Noop::class, 'priority' => 1]]), 1], + 'iterable' => [new ArrayObject([['name' => Noop::class, 'level' => 1]]), 1], ]; } diff --git a/test/LoggerTest.php b/test/LoggerTest.php index b77337f..1a2548c 100644 --- a/test/LoggerTest.php +++ b/test/LoggerTest.php @@ -77,7 +77,7 @@ public function testSetWriters(): void /** * @throws ContainerExceptionInterface */ - public function testAddWriterWithPriority(): void + public function testAddWriterWithLevel(): void { $writer = $this->subject->writerPlugin('null'); $this->subject->addWriter($writer, 3); @@ -91,7 +91,7 @@ public function testAddWriterWithPriority(): void /** * @throws ContainerExceptionInterface */ - public function testAddWithSamePriority(): void + public function testAddWithSameLevel(): void { $writer1 = $this->subject->writerPlugin('null'); $this->subject->addWriter($writer1, 1); @@ -122,11 +122,18 @@ public function testLogging(): void /** * @throws ContainerExceptionInterface */ - public function testLoggingArray(): void + public function testLoggingStringable(): void { + $test = new class { + public function __toString(): string + { + return 'test'; + } + }; + $writer = new Mock(); $this->subject->addWriter($writer); - $this->subject->log(Logger::INFO, ['test']); + $this->subject->log(Logger::INFO, $test); $this->assertEquals(1, count($writer->events)); $this->assertStringContainsString('test', $writer->events[0]['message']); @@ -141,7 +148,7 @@ public function testAddFilter(): void $filter = new MockFilter(); $writer->addFilter($filter); $this->subject->addWriter($writer); - $this->subject->log(Logger::INFO, ['test']); + $this->subject->log(Logger::INFO, 'test'); $this->assertEquals(1, count($filter->events)); $this->assertStringContainsString('test', $filter->events[0]['message']); @@ -150,7 +157,7 @@ public function testAddFilter(): void public static function provideTestFilters(): array { return [ - ['priority', ['priority' => Logger::INFO]], + ['level', ['level' => Logger::INFO]], ['regex', ['regex' => '/[0-9]+/']], ]; } @@ -183,15 +190,15 @@ public static function provideAttributes(): array * @dataProvider provideAttributes * @throws ContainerExceptionInterface */ - public function testLoggingCustomAttributesForUserContext(array|ArrayObject $extra): void + public function testLoggingCustomAttributesForUserContext(array|ArrayObject $context): void { $writer = new Mock(); $this->subject->addWriter($writer); - $this->subject->log(Logger::ERR, 'tottakai', $extra); + $this->subject->log(Logger::ERR, 'tottakai', $context); $this->assertEquals(1, count($writer->events)); - $this->assertIsArray($writer->events[0]['extra']); - $this->assertEquals(count($writer->events[0]['extra']), count($extra)); + $this->assertIsArray($writer->events[0]['context']); + $this->assertEquals(count($writer->events[0]['context']), count($context)); } /** @@ -225,8 +232,8 @@ public function testOptionsWithMock(): void $options = [ 'writers' => [ 'first_writer' => [ - 'name' => 'null', - 'priority' => 1, + 'name' => 'null', + 'level' => 1, ], ], ]; @@ -245,12 +252,12 @@ public function testOptionsWithWriterOptions(): void $options = [ 'writers' => [ [ - 'name' => 'stream', - 'options' => [ + 'name' => 'stream', + 'options' => [ 'stream' => 'php://output', 'log_separator' => 'foo', ], - 'priority' => 1, + 'level' => 1, ], ], ]; @@ -270,14 +277,14 @@ public function testOptionsWithMockAndProcessor(): void $options = [ 'writers' => [ 'first_writer' => [ - 'name' => 'null', - 'priority' => 1, + 'name' => 'null', + 'level' => 1, ], ], 'processors' => [ 'first_processor' => [ - 'name' => 'requestid', - 'priority' => 1, + 'name' => 'requestid', + 'level' => 1, ], ], ]; @@ -341,17 +348,17 @@ public function testExceptionHandler(): void // check logged messages $expectedEvents = [ - ['priority' => Logger::ERR, 'message' => 'previos', 'file' => __FILE__], - ['priority' => Logger::ERR, 'message' => 'error', 'file' => __FILE__], - ['priority' => Logger::NOTICE, 'message' => 'user notice', 'file' => __FILE__], + ['level' => Logger::ERR, 'message' => 'previos', 'file' => __FILE__], + ['level' => Logger::ERR, 'message' => 'error', 'file' => __FILE__], + ['level' => Logger::NOTICE, 'message' => 'user notice', 'file' => __FILE__], ]; for ($i = 0; $i < count($expectedEvents); $i++) { $expectedEvent = $expectedEvents[$i]; $event = $writer->events[$i]; - $this->assertEquals($expectedEvent['priority'], $event['priority'], 'Unexpected priority'); + $this->assertEquals($expectedEvent['level'], $event['level'], 'Unexpected level'); $this->assertEquals($expectedEvent['message'], $event['message'], 'Unexpected message'); - $this->assertEquals($expectedEvent['file'], $event['extra']['file'], 'Unexpected file'); + $this->assertEquals($expectedEvent['file'], $event['context']['file'], 'Unexpected file'); } } @@ -359,10 +366,10 @@ public function testExceptionHandler(): void * @group Laminas-7238 * @throws ContainerExceptionInterface */ - public function testCatchExceptionNotValidPriority(): void + public function testCatchExceptionNotValidLevel(): void { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('$priority must be an integer >= 0 and < 8; received -1'); + $this->expectExceptionMessage('$level must be an integer >= 0 and < 8; received -1'); $writer = new Mock(); $this->subject->addWriter($writer); $this->subject->log(-1, 'Foo'); diff --git a/test/Manager/FilterPluginManagerTest.php b/test/Manager/FilterPluginManagerTest.php index ffd09f5..e2c43a0 100644 --- a/test/Manager/FilterPluginManagerTest.php +++ b/test/Manager/FilterPluginManagerTest.php @@ -4,7 +4,7 @@ namespace DotTest\Log\Manager; -use Dot\Log\Filter\Priority; +use Dot\Log\Filter\Level; use Dot\Log\Formatter\Json; use Dot\Log\Manager\FilterPluginManager; use Laminas\ServiceManager\Exception\InvalidServiceException; @@ -27,7 +27,7 @@ protected function setUp(): void public function testValidate(): void { - $this->assertNull($this->subject->validate(new Priority(47))); + $this->assertNull($this->subject->validate(new Level(47))); } public function testWillNotValidate(): void diff --git a/test/Manager/FormatterPluginManagerTest.php b/test/Manager/FormatterPluginManagerTest.php index 376219e..2e400e5 100644 --- a/test/Manager/FormatterPluginManagerTest.php +++ b/test/Manager/FormatterPluginManagerTest.php @@ -4,7 +4,7 @@ namespace DotTest\Log\Manager; -use Dot\Log\Filter\Priority; +use Dot\Log\Filter\Level; use Dot\Log\Formatter\Json; use Dot\Log\Manager\FormatterPluginManager; use Laminas\ServiceManager\Exception\InvalidServiceException; @@ -34,9 +34,9 @@ public function testWillNotValidate(): void { $this->expectExceptionMessage( 'Dot\Log\Manager\FormatterPluginManager can only create instances of' - . ' Dot\Log\Formatter\FormatterInterface; Dot\Log\Filter\Priority is invalid' + . ' Dot\Log\Formatter\FormatterInterface; Dot\Log\Filter\Level is invalid' ); $this->expectException(InvalidServiceException::class); - $this->subject->validate(new Priority(47)); + $this->subject->validate(new Level(47)); } } diff --git a/test/Processor/BackTraceTest.php b/test/Processor/BackTraceTest.php index 49dcfca..9816a41 100644 --- a/test/Processor/BackTraceTest.php +++ b/test/Processor/BackTraceTest.php @@ -24,7 +24,7 @@ public function testWillInstantiate(): void public function testProcess(): void { $result = $this->subject->process([]); - $this->assertArrayHasKey('extra', $result); + $this->assertArrayHasKey('context', $result); } public function testGetIgnoredNamespaces(): void diff --git a/test/Processor/PsrPlaceholderTest.php b/test/Processor/PsrPlaceholderTest.php index e0b569e..4a1dbab 100644 --- a/test/Processor/PsrPlaceholderTest.php +++ b/test/Processor/PsrPlaceholderTest.php @@ -28,7 +28,7 @@ public function testProcess(): void { $input = [ "message" => '{nullvalue} of {objectvalue} is in fact a {stringvalue}', - "extra" => [ + "context" => [ "nullvalue" => null, "objectvalue" => $this->subject, "stringvalue" => "this is a message", diff --git a/test/Processor/ReferenceIdTest.php b/test/Processor/ReferenceIdTest.php index ee93150..f3d4d82 100644 --- a/test/Processor/ReferenceIdTest.php +++ b/test/Processor/ReferenceIdTest.php @@ -19,7 +19,7 @@ protected function setUp(): void public function testProcessWithReferenceId(): void { $input = [ - "extra" => [ + "context" => [ "referenceId" => "something", ], ]; @@ -33,7 +33,7 @@ public function testProcess(): void $input = []; $result = $this->subject->process($input); - $this->assertArrayHasKey("extra", $result); + $this->assertArrayHasKey("context", $result); } public function testGetReferenceId(): void diff --git a/test/Processor/RequestIdTest.php b/test/Processor/RequestIdTest.php index e0b911a..4f80447 100644 --- a/test/Processor/RequestIdTest.php +++ b/test/Processor/RequestIdTest.php @@ -19,7 +19,7 @@ protected function setUp(): void public function testProcessWithRequestId(): void { $input = [ - "extra" => [ + "context" => [ "requestId" => "something", ], ]; @@ -33,6 +33,6 @@ public function testProcess(): void $input = []; $result = $this->subject->process($input); - $this->assertArrayHasKey("extra", $result); + $this->assertArrayHasKey("context", $result); } } diff --git a/test/Writer/StreamTest.php b/test/Writer/StreamTest.php index b503458..cbb43aa 100644 --- a/test/Writer/StreamTest.php +++ b/test/Writer/StreamTest.php @@ -22,10 +22,10 @@ class StreamTest extends TestCase 'stream' => __DIR__ . '/../../log/error-log-{Y}-{m}-{d}.log', 'filters' => [ 'allMessages' => [ - 'name' => 'priority', + 'name' => 'level', 'options' => [ 'operator' => '>=', - 'priority' => Logger::EMERG, + 'level' => Logger::EMERG, ], ], ], From fab5331094cf5cc2d1bee7e4fad0214cb01333a2 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Mon, 10 Feb 2025 11:34:56 +0200 Subject: [PATCH 2/5] requested changes & bugfix Signed-off-by: Jurj-Bogdan --- README.md | 48 +++++++++++++++----------- composer.json | 3 +- docs/book/v4/configuring-writer.md | 2 +- docs/book/v4/example-with-formatter.md | 6 ++-- docs/book/v4/filtering-log-messages.md | 12 +++---- docs/book/v5/configuring-writer.md | 2 +- docs/book/v5/example-with-formatter.md | 6 ++-- docs/book/v5/filtering-log-messages.md | 14 ++++---- docs/book/v5/overview.md | 2 +- mkdocs.yml | 2 +- src/Logger.php | 26 +++++++++----- test/LoggerTest.php | 8 +++-- 12 files changed, 74 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2ee8fdf..3ec9420 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,22 @@ # dot-log +Robust, composite PSR-3 compliant logger with filtering and formatting. + +## Documentation + +Documentation is available at: https://docs.dotkernel.org/dot-log/. + +## Badges + ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-log) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-log/4.1.1) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-log/5.0.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-log)](https://github.com/dotkernel/dot-log/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-log)](https://github.com/dotkernel/dot-log/network) [![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-log)](https://github.com/dotkernel/dot-log/stargazers) -[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-log)](https://github.com/dotkernel/dot-log/blob/4.0/LICENSE.md) +[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-log)](https://github.com/dotkernel/dot-log/blob/5.0/LICENSE.md) -[![Build Static](https://github.com/dotkernel/dot-log/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-log/actions/workflows/continuous-integration.yml) +[![Build Static](https://github.com/dotkernel/dot-log/actions/workflows/continuous-integration.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/dot-log/actions/workflows/continuous-integration.yml) [![codecov](https://codecov.io/gh/dotkernel/dot-log/graph/badge.svg?token=JX19KTBRCZ)](https://codecov.io/gh/dotkernel/dot-log) ## Adding The Config Provider @@ -43,7 +51,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 + 'level' => \Dot\Log\Logger::ALERT, // this is equal to 1 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', ], @@ -81,8 +89,6 @@ As per PSR-3 document. The log levels are: emergency (0), alert (1), critical (2), error (3), warn (4), notice (5), info (6), debug (7) (in order of level/importance) -Although the plain Logger in Dot Log is not fully compatible with PSR-3, it provides a way to log all of these message types. - The following example has three file writers using filters: * First Example: `FileWriter` - All messages are logged in `/log/dk.log` @@ -99,7 +105,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', 'filters' => [ @@ -107,7 +113,7 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '>=', - 'level' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Logger::EMERG, ] ], ], @@ -116,7 +122,7 @@ return [ // Only warnings 'OnlyWarningsWriter' => [ 'name' => 'stream', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/warnings_only.log', 'filters' => [ @@ -124,7 +130,7 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '==', - 'level' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Logger::WARN, ], ], ], @@ -133,7 +139,7 @@ return [ // Warnings and more important messages 'WarningOrHigherWriter' => [ 'name' => 'stream', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/important_messages.log', 'filters' => [ @@ -143,7 +149,7 @@ return [ // note, the smaller the level, the more important is the message // 0 - emergency, 1 - alert, 2- error, 3 - warn. .etc 'operator' => '<=', - 'level' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Logger::WARN, ], ], ], @@ -181,7 +187,7 @@ The following formats the message as JSON data: ```php 'formatter' => [ - 'name' => \Dot\Log\Manager\Formatter\Json::class, + 'name' => \Dot\Log\Formatter\Json::class, ], ``` @@ -204,7 +210,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', // explicitly log all messages @@ -213,12 +219,12 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '>=', - 'level' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Logger::EMERG, ], ], ], 'formatter' => [ - 'name' => \Dot\Log\Manager\Formatter\Json::class, + 'name' => \Dot\Log\Formatter\Json::class, ], ], ], @@ -236,7 +242,7 @@ Basic usage of the logger is illustrated below. The messages are written to see which logs are written and which are not written. ```php -use Dot\Log\Manager\Logger; +use Dot\Log\Logger; ``` ... @@ -245,11 +251,11 @@ use Dot\Log\Manager\Logger; $logger = $container->get('dot-log.my_logger'); /** @var Logger $logger */ -$logger->emerg('0 EMERG'); +$logger->emergency('0 EMERG'); $logger->alert('1 ALERT'); -$logger->crit('2 CRITICAL'); -$logger->err('3 ERR'); -$logger->warn('4 WARN'); +$logger->critical('2 CRITICAL'); +$logger->error('3 ERR'); +$logger->warning('4 WARN'); $logger->notice('5 NOTICE'); $logger->info('6 INF'); $logger->debug('7 debug'); diff --git a/composer.json b/composer.json index a5f4b36..3152051 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,7 @@ "log", "logging", "services", - "mezzio", - "laminas" + "PSR-3" ], "authors": [ { diff --git a/docs/book/v4/configuring-writer.md b/docs/book/v4/configuring-writer.md index 3b37d02..caee197 100644 --- a/docs/book/v4/configuring-writer.md +++ b/docs/book/v4/configuring-writer.md @@ -20,7 +20,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 + 'priority' => \Dot\Log\Logger::ALERT, // this is equal to 1 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', ], diff --git a/docs/book/v4/example-with-formatter.md b/docs/book/v4/example-with-formatter.md index de6460b..659993c 100644 --- a/docs/book/v4/example-with-formatter.md +++ b/docs/book/v4/example-with-formatter.md @@ -15,7 +15,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'priority' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', // explicitly log all messages @@ -24,12 +24,12 @@ return [ 'name' => 'priority', 'options' => [ 'operator' => '>=', - 'priority' => \Dot\Log\Manager\Logger::EMERG, + 'priority' => \Dot\Log\Logger::EMERG, ], ], ], 'formatter' => [ - 'name' => \Dot\Log\Manager\Formatter\Json::class, + 'name' => \Dot\Log\Formatter\Json::class, ], ], ], diff --git a/docs/book/v4/filtering-log-messages.md b/docs/book/v4/filtering-log-messages.md index 0276bf2..17fbef0 100644 --- a/docs/book/v4/filtering-log-messages.md +++ b/docs/book/v4/filtering-log-messages.md @@ -31,7 +31,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'priority' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', 'filters' => [ @@ -39,7 +39,7 @@ return [ 'name' => 'priority', 'options' => [ 'operator' => '>=', - 'priority' => \Dot\Log\Manager\Logger::EMERG, + 'priority' => \Dot\Log\Logger::EMERG, ] ], ], @@ -48,7 +48,7 @@ return [ // Only warnings 'OnlyWarningsWriter' => [ 'name' => 'stream', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'priority' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/warnings_only.log', 'filters' => [ @@ -56,7 +56,7 @@ return [ 'name' => 'priority', 'options' => [ 'operator' => '==', - 'priority' => \Dot\Log\Manager\Logger::WARN, + 'priority' => \Dot\Log\Logger::WARN, ], ], ], @@ -65,7 +65,7 @@ return [ // Warnings and more important messages 'WarningOrHigherWriter' => [ 'name' => 'stream', - 'priority' => \Dot\Log\Manager\Logger::ALERT, + 'priority' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/important_messages.log', 'filters' => [ @@ -75,7 +75,7 @@ return [ // note, the smaller the priority, the more important is the message // 0 - emergency, 1 - alert, 2- error, 3 - warn etc. 'operator' => '<=', - 'priority' => \Dot\Log\Manager\Logger::WARN, + 'priority' => \Dot\Log\Logger::WARN, ], ], ], diff --git a/docs/book/v5/configuring-writer.md b/docs/book/v5/configuring-writer.md index c9dd904..90ff424 100644 --- a/docs/book/v5/configuring-writer.md +++ b/docs/book/v5/configuring-writer.md @@ -20,7 +20,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, // this is equal to 1 + 'level' => \Dot\Log\Logger::ALERT, // this is equal to 1 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', ], diff --git a/docs/book/v5/example-with-formatter.md b/docs/book/v5/example-with-formatter.md index 8febee3..c20a822 100644 --- a/docs/book/v5/example-with-formatter.md +++ b/docs/book/v5/example-with-formatter.md @@ -15,7 +15,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', // explicitly log all messages @@ -24,12 +24,12 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '>=', - 'level' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Logger::EMERG, ], ], ], 'formatter' => [ - 'name' => \Dot\Log\Manager\Formatter\Json::class, + 'name' => \Dot\Log\Formatter\Json::class, ], ], ], diff --git a/docs/book/v5/filtering-log-messages.md b/docs/book/v5/filtering-log-messages.md index e4a2d7f..40d01b7 100644 --- a/docs/book/v5/filtering-log-messages.md +++ b/docs/book/v5/filtering-log-messages.md @@ -13,7 +13,7 @@ The log levels are in order of level/importance: * info (6) * debug (7) -Although the plain Logger in `dot-log` is not fully compatible with PSR-3, it provides a way to log all of these message types. +Because the plain Logger in `dot-log` is fully compatible with PSR-3, it provides a way to log all of these message types. The following example has three file writers using filters: @@ -31,7 +31,7 @@ return [ 'writers' => [ 'FileWriter' => [ 'name' => 'FileWriter', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/dk.log', 'filters' => [ @@ -39,7 +39,7 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '>=', - 'level' => \Dot\Log\Manager\Logger::EMERG, + 'level' => \Dot\Log\Logger::EMERG, ] ], ], @@ -48,7 +48,7 @@ return [ // Only warnings 'OnlyWarningsWriter' => [ 'name' => 'stream', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/warnings_only.log', 'filters' => [ @@ -56,7 +56,7 @@ return [ 'name' => 'level', 'options' => [ 'operator' => '==', - 'level' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Logger::WARN, ], ], ], @@ -65,7 +65,7 @@ return [ // Warnings and more important messages 'WarningOrHigherWriter' => [ 'name' => 'stream', - 'level' => \Dot\Log\Manager\Logger::ALERT, + 'level' => \Dot\Log\Logger::ALERT, 'options' => [ 'stream' => __DIR__ . '/../../log/important_messages.log', 'filters' => [ @@ -75,7 +75,7 @@ return [ // note, the smaller the level, the more important is the message // 0 - emergency, 1 - alert, 2- error, 3 - warn etc. 'operator' => '<=', - 'level' => \Dot\Log\Manager\Logger::WARN, + 'level' => \Dot\Log\Logger::WARN, ], ], ], diff --git a/docs/book/v5/overview.md b/docs/book/v5/overview.md index 89f6888..cdd20a6 100644 --- a/docs/book/v5/overview.md +++ b/docs/book/v5/overview.md @@ -1,3 +1,3 @@ # Overview -Robust, composite logger with filtering, formatting, and PSR-3 support. +Robust, composite PSR-3 compliant logger with filtering and formatting. diff --git a/mkdocs.yml b/mkdocs.yml index cfefe4a..5322abc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -4,9 +4,9 @@ extra: project: Packages current_version: v5 versions: + - v5 - v4 - v3 - - v5 nav: - Home: index.md - v5: diff --git a/src/Logger.php b/src/Logger.php index a84d0db..0c20c32 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -24,11 +24,13 @@ use Traversable; use function array_reverse; +use function array_search; use function count; use function error_get_last; use function error_reporting; use function in_array; use function is_array; +use function is_numeric; use function is_string; use function register_shutdown_function; use function restore_error_handler; @@ -108,14 +110,14 @@ class Logger extends AbstractLogger * List of level code => level (short) name */ protected array $levels = [ - self::EMERG => LogLevel::EMERGENCY, - self::ALERT => LogLevel::ALERT, - self::CRIT => LogLevel::CRITICAL, - self::ERR => LogLevel::ERROR, - self::WARN => LogLevel::WARNING, - self::NOTICE => LogLevel::NOTICE, - self::INFO => LogLevel::INFO, - self::DEBUG => LogLevel::DEBUG, + LogLevel::EMERGENCY => self::EMERG, + LogLevel::ALERT => self::ALERT, + LogLevel::CRITICAL => self::CRIT, + LogLevel::ERROR => self::ERR, + LogLevel::WARNING => self::WARN, + LogLevel::NOTICE => self::NOTICE, + LogLevel::INFO => self::INFO, + LogLevel::DEBUG => self::DEBUG, ]; protected SplPriorityQueue $writers; @@ -344,6 +346,12 @@ public function getProcessors(): SplPriorityQueue public function log(mixed $level, string|Stringable $message, iterable $context = []): void { + if (! is_numeric($level)) { + if (isset($this->levels[$level])) { + $level = $this->levels[$level]; + } + } + if (($level < 0) || ($level >= count($this->levels))) { throw new InvalidArgumentException(sprintf( '$level must be an integer >= 0 and < %d; received %s', @@ -365,7 +373,7 @@ public function log(mixed $level, string|Stringable $message, iterable $context $event = [ 'timestamp' => $timestamp, 'level' => $level, - 'levelName' => $this->levels[$level], + 'levelName' => array_search((int) $level, $this->levels, true), 'message' => (string) $message, 'context' => $context, ]; diff --git a/test/LoggerTest.php b/test/LoggerTest.php index 1a2548c..38b2021 100644 --- a/test/LoggerTest.php +++ b/test/LoggerTest.php @@ -114,9 +114,13 @@ public function testLogging(): void $writer = new Mock(); $this->subject->addWriter($writer); $this->subject->log(Logger::INFO, 'tottakai'); + $this->subject->log(4, 'tottakai'); + $this->subject->log('2', 'tottakai'); - $this->assertEquals(1, count($writer->events)); - $this->assertStringContainsString('tottakai', $writer->events[0]['message']); + $this->assertEquals(3, count($writer->events)); + foreach ($writer->events as $event) { + $this->assertStringContainsString('tottakai', $event['message']); + } } /** From 0adf24381c4b212709c4e3cff76c348f7e0b730c Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 11 Feb 2025 13:52:12 +0200 Subject: [PATCH 3/5] issue69 - log message placeholder support Signed-off-by: Jurj-Bogdan --- docs/book/v5/usage.md | 10 +++++++ src/Logger.php | 31 +++++++++++++++++++++- test/LoggerTest.php | 62 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/docs/book/v5/usage.md b/docs/book/v5/usage.md index 08e692e..bf4ad05 100644 --- a/docs/book/v5/usage.md +++ b/docs/book/v5/usage.md @@ -24,3 +24,13 @@ $logger->info('6 INF'); $logger->debug('7 debug'); $logger->log(Logger::NOTICE, 'NOTICE from log()'); ``` + +## Placeholders + +`dot-log` implements placeholder interpolation as described in PSR-3. +Placeholders MUST be delimited with single opening/closing braces: `{placeholder}`, with the names composed only of the characters `A-Z`, `a-z`, `0-9`, underscore `_`, and period `.`. +Placeholders are interpolated as follows: + +* `string` and `numeric` types are replaced directly +* `null` values are not replaced +* Other placeholder values are replaced with the return value of the `gettype` function diff --git a/src/Logger.php b/src/Logger.php index 0c20c32..3956ca5 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -28,16 +28,19 @@ use function count; use function error_get_last; use function error_reporting; +use function gettype; use function in_array; use function is_array; use function is_numeric; use function is_string; +use function preg_match_all; use function register_shutdown_function; use function restore_error_handler; use function restore_exception_handler; use function set_error_handler; use function set_exception_handler; use function sprintf; +use function strtr; use function var_export; use const E_COMPILE_ERROR; @@ -370,11 +373,13 @@ public function log(mixed $level, string|Stringable $message, iterable $context $timestamp = new DateTime(); + $message = $this->handlePlaceholders((string) $message, $context); + $event = [ 'timestamp' => $timestamp, 'level' => $level, 'levelName' => array_search((int) $level, $this->levels, true), - 'message' => (string) $message, + 'message' => $message, 'context' => $context, ]; @@ -389,6 +394,30 @@ public function log(mixed $level, string|Stringable $message, iterable $context } } + protected function handlePlaceholders(string $message, array $context): string + { + if (preg_match_all('/\{([\w.]+)}/', $message, $matches)) { + $replacements = []; + foreach ($matches[1] as $match) { + if (! isset($context[$match])) { + continue; + } + + $placeholderValue = $context[$match]; + + if (is_string($placeholderValue) || is_numeric($placeholderValue)) { + $replacements["{{$match}}"] = (string) $placeholderValue; + } else { + $replacements["{{$match}}"] = gettype($placeholderValue); + } + } + + $message = strtr($message, $replacements); + } + + return $message; + } + /** * Register logging system as an error handler to log PHP errors * diff --git a/test/LoggerTest.php b/test/LoggerTest.php index 38b2021..8e0d425 100644 --- a/test/LoggerTest.php +++ b/test/LoggerTest.php @@ -123,6 +123,68 @@ public function testLogging(): void } } + public static function provideTestPlaceholders(): array + { + $context = [ + 'placeholder1' => 1, + '#placeholder2' => 'placeholder2', + 'placeholder3' => new class { + }, + ]; + + return [ + ["message with no placeholders", $context], + ["{placeholder1, {#placeholder2}, place_holder3} invalid placeholders", $context], + ["{placeholder1}, {#placeholder2}, {place_holder3}", []], + ]; + } + + /** + * @dataProvider provideTestPlaceholders + */ + public function testLoggingWithoutValidPlaceholdersDoesNotModifyMessage(string $message, array $context): void + { + $writer = new Mock(); + $this->subject->addWriter($writer); + $this->subject->log(Logger::INFO, $message, $context); + + $this->assertEquals(1, count($writer->events)); + + $this->assertEquals( + $message, + $writer->events[0]['message'] + ); + } + + public function testLoggingWithValidPlaceholders(): void + { + $message = + "{placeholder1}, {place.holder2}, {place_holder3} and {placeholder4}. {placeholder5} test {placeholder6}"; + $context = [ + 'placeholder1' => 1, + 'place.holder2' => 'placeholder2', + 'place_holder3' => new class { + public function hello(): string + { + return 'Hello world!'; + } + }, + 'placeholder4' => ['array' => 'placeholder4'], + 'placeholder5' => 5.5, + 'placeholder6' => fn($arg1, $arg2) => $arg1 + $arg2, + ]; + + $writer = new Mock(); + $this->subject->addWriter($writer); + $this->subject->log(Logger::INFO, $message, $context); + + $this->assertEquals(1, count($writer->events)); + $this->assertEquals( + '1, placeholder2, object and array. 5.5 test object', + $writer->events[0]['message'] + ); + } + /** * @throws ContainerExceptionInterface */ From 7a108566fd7425bdb1f11fe50c773e49861d012e Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 11 Feb 2025 14:19:19 +0200 Subject: [PATCH 4/5] issue70 && issue72 for branch 5.0 Signed-off-by: Jurj-Bogdan --- README.md | 2 -- SECURITY.md | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3ec9420..8820207 100644 --- a/README.md +++ b/README.md @@ -261,5 +261,3 @@ $logger->info('6 INF'); $logger->debug('7 debug'); $logger->log(Logger::NOTICE, 'NOTICE from log()'); ``` - -Extracted from [this article](https://www.dotkernel.com/dotkernel/logging-with-dot-log-in-mezzio-and-dotkernel) diff --git a/SECURITY.md b/SECURITY.md index 8446926..40cd29f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -3,10 +3,12 @@ ## Supported Versions -| Version | Supported | PHP Version | -|---------|--------------------|----------------------------------------------------------------------------------------------------| +| Version | Supported | PHP Version | +|---------|--------------------|---------------------------------------------------------------------------------------------------------| +| 5.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-log/5.0.0) | +| 4.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-log/4.1.0) | | 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-log/3.4.7) | -| <= 2.x | :x: | | +| <= 2.x | :x: | | ## Reporting Potential Security Issues From e0d7c0789dcdc86e4d92e726dd8828fa2218d0b2 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Fri, 14 Feb 2025 16:22:28 +0200 Subject: [PATCH 5/5] requested changes Signed-off-by: Jurj-Bogdan --- docs/book/v5/adding-config-provider.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/book/v5/adding-config-provider.md b/docs/book/v5/adding-config-provider.md index 98abb06..5b83bb6 100644 --- a/docs/book/v5/adding-config-provider.md +++ b/docs/book/v5/adding-config-provider.md @@ -1,11 +1,12 @@ # Adding The Config Provider * In `config/config.php` add an entry for the config provider `\Dot\Log\ConfigProvider::class` - * Make sure it is added before with the Application-Specific components, eg.: + * Make sure it is added before the Application-Specific components, e.g.: * `\Frontend\App\ConfigProvider.php` * `\Admin\App\ConfigProvider::class` * `\MyProject\ConfigProvider::class` etc. -* Add the logger configuration in an autoload config file, e.g. you can create `config/autoload/logger.global.php`. Follow the `Configuring the writer(s)` chapter for a simple working example. +* Add the logger configuration in an autoload config file, e.g. you can create `config/autoload/logger.global.php`. +Follow the `Configuring the writer(s)` chapter for a simple working example. > `Dot\Log\ConfigProvider` has an abstract factory `LoggerAbstractServiceFactory::class` which corresponds to the alias, not the class name. > Instead of requesting `Dot\Log\Logger::class` from the container, use `dot-log.my_logger`.