Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Журнал

Когда подробности ошибок скрыты от посетителя, узнать о них можно только из журнала (лога) — файла, куда приложение записывает, что и когда произошло. В 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 — он заводит новый файл каждый день и удаляет старые.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.