Журнал
Когда подробности ошибок скрыты от посетителя, узнать о них можно только из журнала (лога) — файла, куда приложение записывает, что и когда произошло. В Slim журнала нет, но он принимает любой журнал по стандарту PSR-3. Обычно подключают Monolog.
Установка
composer require monolog/monologГде лежит журнал
Создайте в корне проекта папку var, а в ней log. В var хранят файлы, которые приложение создаёт во время работы: журналы и кеш. В репозиторий их не добавляют — впишите var/ в .gitignore.
Описание в контейнере
// config/container.php
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
LoggerInterface::class => function () {
$logger = new Logger('app');
$logger->pushHandler(new StreamHandler(__DIR__ . '/../var/log/app.log'));
return $logger;
},Ключ записи — интерфейс LoggerInterface: классы просят в конструкторе интерфейс, а не конкретную библиотеку. StreamHandler сообщает, что записи идут в файл var/log/app.log.
Запись из действия
// src/Action/CreatePostAction.php
use Psr\Log\LoggerInterface;
public function __construct(
private PostRepository $posts,
private LoggerInterface $logger,
// ... остальные зависимости
) {}$id = $this->posts->create(trim($data['title']), trim($data['body']));
$this->logger->info('Создана статья', ['id' => $id]);Создайте статью через форму и откройте var/log/app.log — в нём появится строка с датой, уровнем INFO, текстом и номером статьи. Второй аргумент — массив дополнительных данных.
Уровни
| Метод | Для чего |
|---|---|
debug() | Подробности для отладки |
info() | Обычные события: вход, создание записи |
warning() | Подозрительное, но не ошибка |
error() | Ошибка, запрос не выполнен |
critical() | Отказ важной части: недоступна база |
Ошибки в журнале
Чтобы посредник ошибок записывал исключения в тот же файл, передайте журнал четвёртым аргументом:
// config/middleware.php
use Psr\Log\LoggerInterface;
$logger = $app->getContainer()->get(LoggerInterface::class);
$errorMiddleware = $app->addErrorMiddleware($settings['debug'], true, true, $logger);Запись делает стандартный обработчик Slim. Свой обработчик из прошлого урока его заменяет, поэтому писать в журнал должен сам. Добавьте в его функцию $logger через use и одну строку:
// config/middleware.php
function (ServerRequestInterface $request, Throwable $exception) use ($app, $logger) {
$status = $exception instanceof HttpException ? $exception->getCode() : 500;
if ($status >= 500) {
$logger->error($exception->getMessage(), ['exception' => $exception]);
}
// ... формирование ответа
}Ошибки 404 в журнал не попадают: это не сбой приложения, а неверный адрес.
Проверка
Временно допишите в любое действие строку throw new RuntimeException('Проверка журнала');, откройте страницу и загляните в var/log/app.log — там будет запись уровня ERROR с этим текстом. Затем строку удалите.
Частая ошибка
В журнал нельзя писать пароли, токены и содержимое форм целиком: файл журнала читают многие, и хранится он долго. Записывайте номер пользователя или статьи, а не данные. И следите за размером файла: вместо StreamHandler можно взять RotatingFileHandler — он заводит новый файл каждый день и удаляет старые.