Документация/Контейнер/Сервисы/Log

Сервис логирования

Сервис Log — это механизм логирования во фреймворке HLEB2, позволяющий сохранять ошибки и сообщения в специальное хранилище логов. Принцип сохранения логов во фреймворке основан на PSR-3.

По умолчанию во фреймворке используется встроенный механизм логирования, сохраняющий логи в файл. Логируются все ошибки PHP и работы самого приложения, а также информационные и отладочные логи, заданные разработчиком в коде.

Стандартные файловые логи фреймворка сохраняются в папку /storage/logs/ проекта.

Способы использования Log в контроллерах (и всех классах, унаследованных от Hleb\Base\Container) на примере добавления информационного сообщения:

// variant 1
use Hleb\Reference\LogInterface;
$this->container->get(LogInterface::class)->info('Sample message');

// variant 2
$this->container->log()->info('Sample message');

Пример логирования в коде приложения:

// variant 1
use Hleb\Static\Container;
use 
Hleb\Reference\LogInterface;
$data Container::get(LogInterface::class)->info('Sample message');

// variant 2
use Hleb\Static\Log;
Log::info('Sample message');

// variant 3
logger()->info('Sample message');

Также объект Log может быть получен через внедрение зависимостей по интерфейсу Hleb\Reference\Interface\Log.

Для упрощения примеров, далее они будут содержать только обращение через функцию logger().

При выполнении одного из предыдущих примеров в директории /storage/logs/ будет создан файл лога (если не существовал ранее) с добавлением строчки, которая примерно будет выглядеть так:

[13:01:12.211556 10.01.2024 UTC+03] Web:INFO Sample message {/path/to/project/app/Controllers/TestController.php on line 31} {App\Controllers\TestController->get()} GET http://example-domain.ru/test-log 127.0.0.1 #{"request-id":"71cc0539-af41-556d-9c48-2a6cd2d8090f","debug":true}

Из текста лога видно, что было выведено сообщение 'Sample message' с указанием заданного уровня 'INFO', а также дополнительная информация о вызове лога, точное время и базовые данные запроса.

Конфиденциальную информацию и данные в составе логов, раскрытие которых может привести к нарушениям безопасности проекта, не рекомендуется отправлять в сторонние сервисы для хранения логов, так как они могут быть подвержены взлому.


#Уровни логирования

При выборе уровня логирования нужно руководствоваться содержанием и важностью выводимых данных. Список от обычных сообщений до критических ошибок по возрастанию:

debug() - отладочные сообщения, обычно используются только при разработке проекта. По умолчанию в настройках фреймворка задан максимальным уровень ниже (info) и эти сообщения не будут сохранены в лог.

info() - информационные сообщения, которые необходимы для представления о том, как функционирует та или иная часть кода, все ли условия выполняются. Здесь может быть выведен конкретный SQL запрос, чтобы можно было затем проверить правильность выполнения.

notice() - уведомления о событиях в системе. Например, может сигнализировать о приближении к критическому порогу некоторого важного значения, но который еще не был достигнут.

warning() - для логирования исключительных случаев, не в качестве критических ошибок, а предупреждений. К примеру, использование устаревших API, неправильное использование API, другие нежелательные случаи.

error() - ошибки выполнения, возникающие при определённых условиях. Эти ошибки не требуют немедленных действий, но должны быть зарегистрированы и контролироваться.

critical() - критические ошибки в программе, как, например, недоступность одного из компонентов.

alert() - общая недоступность системы, это может быть неработоспособность базы данных, всего веб-сайта и т.д. Действия по исправлению должны быть приняты немедленно.

emergency() - система полностью непригодна для использования.


#Контекст логирования

Согласно PSR-3 вы можете передать вторым аргументом именованный массив данных для подстановки в текст сообщения, например:

logger()->error('Failed to create user {name}', ['name' => 'Ivar']);

Во встроенном логе фреймворка вы также можете добавить в массив другие данные и они будут выведены по ключу в лог в разделе с 'request-id'. Сторонние механизмы логирования могут не поддерживать эту возможность.


#Альтернативный Logger

Фреймворк HLEB2 поддерживает только один актуальный экземпляр механизма логирования, если нужно заменить его на сторонний, то это нужно сделать при инициализации фреймворка. Эта необходимость обоснована тем, что логирование ошибок должно начинаться с самого начала загрузки и работы самого фреймворка.


#Настройки логирования

В файле /config/common.php:
log.enabled - включение/отключение сохранения в логи, может быть полезным при кратковременном отключении логирования для снятия нагрузки на приложение.
max.log.level - установка максимального уровня логирования (от сообщений до критических ошибок). Например, если установить уровень 'warning', то логи с уровнями 'debug', 'info' и 'notice' сохраняться не будут.
max.cli.log.level - максимальный уровень логирования при использовании фреймворка через консольные команды из терминала или планировщика задач.
error.reporting - этот параметр относится к уровню ошибок, но имеет отношение и к логированию, так как определяет ошибки, которые попадут в лог.
log.sort - при стандартном файловом логировании разбивает логи по источнику (домену сайта).
log.stream - выводит логи в указанный поток вывода, если он указан, например в '/dev/stdout'.
log.format - доступно два формата для стандартного логирования, 'row'(по умолчанию) и 'json', последний преобразует вывод логов в JSON-формате.

В файле /config/main.php:
db.log.enabled - сохранение в логи всех запросов к базам данных.


#Примеры использования

Обобщённые примеры, показывающие отличие в логировании ошибок и обычных информационных логов:

// Will output to the log.
logger()->info('Info message');

try {
    throw new 
ErrorException('Warning message');
} catch(
\ErrorException $e) {
    
// Will output an error to the log and continue execution.
    
logger()->warning($e);
}
// Will output an error to the log and interrupt execution.
throw new ErrorException('Error message');

#Просмотр логов

При стандартном хранении логов в файлах, последние добавленные логи можно вывести в терминале с использованием консольной команды:

$php console --logs 3 5

Указанная команда выведет по три последних лога для пяти крайних по дате файлов с логами.

В журнале логов (по умолчанию в файлах) каждый лог имеет метку "request-id", по которому можно выбрать все логи конкретного запроса.
Для UNIX-систем и macOS вы можете использовать команду 'grep' для поиска по типу ошибки:

$grep -m10 :ERROR ./storage/logs/*

Гибкость этой команды позволяет производить поиск по различным условиям, в том числе и по "request-id" запроса.

Для Windows альтернативой будет команда 'findstr':

D:\project>findstr /S /C:":ERROR" "storage/logs/*"


#Ротация логов

В комплекте с фреймворком поставляется класс App\Commands\RotateLogs, это реализация консольной команды для удаления устаревших файлов с логами.

$php console rotate-logs 5

Данная команда удалит все файлы логов созданные ранее пяти дней назад. По умолчанию - три дня. Команда предназначена как для ручной ротации, так и добавления в планировщике задач (на ежедневное выполнение).

Чтобы фреймворк отслеживал автоматически максимальный размер файловых логов, необходимо настроить опцию 'max.log.size' в файле /config/common.php. Значение указывается как целое число в мегабайтах. Но при активности этого параметра, и при непредсказуемо большом количестве логов за текущий день, могут быть удалены все логи за предыдущий.

Кеширование Path

Страница создана: @fomiash
К началу страницы