phpsoftbox / logger
Logger component for the PhpSoftBox HTTP framework
Requires
- php: ^8.5
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
Requires (Dev)
- phpsoftbox/cs-fixer: ^1.2.2
- phpsoftbox/http-message: ^1.0
- phpunit/phpunit: ^13.3
Suggests
None
Provides
- psr/log-implementation: 3.0.0
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-29 11:54:00 UTC
README
PSR-3 совместимый логгер с модульной архитектурой для проектов PhpSoftBox. Поддерживает настраиваемые обработчики, форматтеры и процессоры, строгую типизацию и единый конфигуратор.
Возможности
- Реализация
Psr\Log\LoggerInterface. - Обработчики: Stream, Buffer, Console, RotatingFile, Syslog, InMemory (тестовый), Null.
- Форматтеры: Line, JSON.
- Процессоры: глобальные и локальные, встроен
RedactSecretsProcessor. - Конфигуратор
LoggerFactoryсоздаёт каналы из PHP-конфигураций.
Установка
composer require phpsoftbox/logger
Пакет объявляет provide: psr/log-implementation — удовлетворяет зависимостям, требующим реализацию PSR-3.
Быстрый пример
use PhpSoftBox\Logger\Logger; use PhpSoftBox\Logger\Handler\StreamHandler; use PhpSoftBox\Logger\Processor\RedactSecretsProcessor; $logger = new Logger( name: 'api', handlers: [new StreamHandler(__DIR__.'/var/log/api.log')], processors: [new RedactSecretsProcessor()], ); $logger->info('User {user} logged in', ['user' => 'Alice', 'password' => 'secret']);
Конфигуратор
use PhpSoftBox\Logger\Configurator\LoggerFactory; use PhpSoftBox\Logger\Handler\StreamHandler; use PhpSoftBox\Logger\Handler\NullHandler; $factory = new LoggerFactory([ 'channels' => [ 'default' => [ 'name' => 'app', 'processors' => [\PhpSoftBox\Logger\Processor\RedactSecretsProcessor::class], 'handlers' => [ new StreamHandler(__DIR__ . '/var/log/app.log'), new NullHandler(), [ 'type' => 'buffer', 'buffer_size' => 100, 'handler' => new StreamHandler(__DIR__ . '/var/log/buffered.log'), ], ], ], ], ]); $logger = $factory->create('default');
HTTP middleware
use PhpSoftBox\Logger\LoggerMiddleware; $middleware = new LoggerMiddleware($logger);
Интеграция с DI (пример PHP-DI)
use DI\ContainerBuilder; use PhpSoftBox\Logger\Configurator\LoggerFactory; use PhpSoftBox\Logger\Configurator\LoggerFactoryInterface; use PhpSoftBox\Logger\Handler\StreamHandler; use PhpSoftBox\Logger\Logger; $builder = new ContainerBuilder(); $builder->addDefinitions([ LoggerFactoryInterface::class => static function (): LoggerFactoryInterface { return new LoggerFactory([ 'channels' => [ 'default' => [ 'handlers' => [new StreamHandler(__DIR__.'/var/log/app.log')], ], ], ]); }, Logger::class => static function (LoggerFactoryInterface $factory): Logger { return $factory->create('default'); }, 'logger.audit' => static function (Logger $logger): Logger { return $logger->withChannel('audit'); }, ]); $container = $builder->build(); $appLogger = $container->get(Logger::class); $auditLogger = $container->get('logger.audit');
Форматтеры и контекст
LineFormatter и JsonFormatter приводят context/extra через ContextNormalizer, поэтому запись в лог не падает
из-за содержимого контекста:
- некорректный UTF-8 заменяется на
U+FFFD,NAN/INF— строками"NAN"/"INF"; - исключение —
class,message,code,file,line,traceи цепочкаprevious; DateTimeInterface— строка RFC 3339,JsonSerializable— результатjsonSerialize(), enum — значение (имя для чистого enum),Stringable— строка, прочие объекты —[object Class], ресурсы —[resource type];- вложенность глубже 9 уровней обрезается до
[max depth].
Конфигурация форматтера в LoggerFactory:
'formatter' => 'line', // LineFormatter::DEFAULT_FORMAT 'formatter' => ['type' => 'line', 'format' => '...', 'date_format' => DATE_ATOM, 'stacktrace_multiline' => true], 'formatter' => ['type' => 'json', 'format' => '...', 'flags' => JSON_UNESCAPED_UNICODE],
Формат строки по умолчанию одинаков для 'line' и массива без format:
[%datetime%] %level_name%: %message% %context% %extra%.
RedactSecretsProcessor
- Ключ context/extra скрывается целиком, если его имя содержит одно из ключевых слов
(
RedactSecretsProcessor::DEFAULT_KEYS:password,passwd,token,secret,authorization,api_key,apikey,private_key,cookie), без учёта регистра:access_token,client_secret,X-Auth-Token. - В строковых значениях скрываются пары
ключ=значение/ключ: значение/"ключ":"значение"иAuthorization: Bearer …— строка запроса, заголовок, фрагмент JSON. Обычный текст не меняется. - Сообщение не обрабатывается: передавайте секреты через плейсхолдеры (
'{password}') — процессоры выполняются до интерполяции, и подставляется уже скрытое значение.
Файлы и ротация
StreamHandlerоткрывает файл один раз (режимa,fflushпосле каждой записи). При внешней ротации (logrotate) в долгоживущих процессах используйтеcopytruncate, иначе запись продолжится в переименованный файл.RotatingFileHandlerротирует по размеру (maxBytes, хранитmaxFilesархивовpath.1…path.N). Если файл уже ротировал другой процесс (FPM, несколько воркеров с одним логом), обработчик замечает это перед записью и переоткрывает файл по исходному пути.
Долгоживущие процессы
BufferHandler без вложенного обработчика и с buffer_size: 0 и InMemoryHandler накапливают записи без предела.
В воркерах очищайте их после задачи/запроса через хуки ServicesResetter
(['logger.buffer' => 'clear']) или задавайте buffer_size.
BufferHandler
buffer_size: 0 = без лимита.flush_on_overflow: true — сбрасывает при переполнении, false — удаляет старейшую запись.- Методы
flush(),drain(),clear()позволяют контролировать буфер вручную.
LineFormatter
По умолчанию LineFormatter выводит stack trace в несколько строк (удобно для чтения).
Это поведение можно отключить:
use PhpSoftBox\Logger\Formatter\LineFormatter; $formatter = new LineFormatter(stacktraceMultiline: false);
Через конфиг LoggerFactory:
[
'type' => 'line',
'stacktrace_multiline' => false,
]
Использование LogRecord::withChannel/withDatetime
Процессоры и обработчики должны возвращать новые экземпляры LogRecord при изменении канала или времени записи. Методы withChannel() и withDatetime() гарантируют неизменяемость и корректную передачу данных по цепочке.
Тесты
composer install ./vendor/bin/phpunit
Лицензия
MIT