Logging brick
Помилку треба не лише показати користувачу, а й залишити слід
для діагностики. PHP error_log вистачає на ранньому
кроці ErrorHandling, але для рівнів, ротації й каналів потрібен
Monolog. addLogging() на
ConceptStack реєструє
extension-logger-monolog
як LoggerInterface. Повертає
LoggingBuilder. Рецепт —
Логування.
Handlers додаються явно (toRotatingFile,
toStderr, withHandler): без sink
logger не має куди писати — свідомий fail-fast замість
«тихого» no-op. ErrorHandling з
setLogReporting(logger: true) вимагає цієї
capability. Окремі sinks валідації / SQL
(withLogging на Validation / Database) — це
не цей brick.
Методи LoggingBuilder:
| Метод | Параметри | Опис | Залежність |
|---|---|---|---|
setLevel() |
string $level |
Default Monolog level для наступних helper-ів (DEBUG, INFO, ERROR, …) | — |
setChannel() |
string $channel |
Ім’я каналу Monolog (з’являється в рядку логу) | — |
toRotatingFile() |
string $path, int $maxFiles = 7, ?string $level = null |
RotatingFileHandler | — |
toStderr() |
?string $level = null |
StreamHandler на php://stderr |
— |
withHandler() |
HandlerInterface $handler |
Будь-який готовий Monolog handler | — |
withMasking() |
— | Маскування чутливих полів у логах | addMasking() |
setLevel()
$stack->addLogging()
->setLevel('DEBUG');
Базовий поріг для наступних toRotatingFile() /
toStderr(), якщо їм не передати власний
$level. На проді часто ERROR /
WARNING, локально — DEBUG. Невідома
назва → Monolog Debug.
setChannel()
$stack->addLogging()
->setChannel('recipes');
Ім’я в рядку логу (наприклад recipes.INFO: …) —
щоб у спільному файлі / агрегаторі відрізняти додатки або
середовища без окремих шляхів.
toRotatingFile()
$stack->addLogging()
->setLevel('ERROR')
->setChannel('recipes')
->toRotatingFile($rootPath . 'storage/logs/app.log', 7);
Типовий sink для довгоживучого додатку: файл + ротація, щоб диск не заповнювався. Абсолютний шлях, кількість ротацій; опційний третій аргумент — рівень лише для цього handler. Можна викликати кілька разів (кілька handlers: наприклад ERROR у файл і WARNING у stderr).
toStderr()
$stack->addLogging()
->toStderr('WARNING');
Коли логи збирає Docker / Kubernetes з stdout/stderr, а не
volume з файлами — пишіть у php://stderr. Зручно
для CLI і контейнерів без окремого log-директору.
withHandler()
$stack->addLogging()
->withHandler(new StreamHandler('php://stdout', Level::Info));
Escape hatch: Syslog, Slack, Elasticsearch тощо — будь-який
готовий Monolog\Handler\HandlerInterface, коли
toRotatingFile / toStderr недостатньо.
Glue збирає handler сам і передає в Stack; можна викликати
кілька разів поряд із іншими sinks.
withMasking()
$stack->addMasking()
->setPatterns([ /* regex у рядках message/trace */ ])
->setKeyPatterns([ /* /^email$/i, /.*password.*/i, … */ ]);
$stack->addLogging()
->toRotatingFile($rootPath . 'storage/logs/app.log')
->withMasking();
Без цього виклику addMasking() лише реєструє правила —
app-логер їх не застосовує. Opt-in навмисний: той самий masker
пізніше можна повісити на query log, не чіпаючи інші sinks.
Key patterns ховають значення структурованого context;
string patterns — фрагменти вже «розчинені» в тексті.
Навіщо обидва й типовий рецепт —
Логування і маскування;
API правил —
Masking brick.
Що реєструє brick
LoggerInterface(PSR-3 + Concept) — інжект у controllers/services- Handlers з builder — у Monolog logger
Після цього в ErrorHandling можна переключити
setLogReporting(logger: true, …) — report піде
в той самий канал, що й ручні $logger->info().
Рецепт — 8. Логування і маскування. Поруч — ErrorHandling brick (спочатку показуємо помилку, потім підключаємо Monolog + masking).