Простой и функциональный модуль CMS Bitrix для логгирования данных проекта в файлы.
Модуль можно использовать для логирования "узких" мест в проекте и дебага при разработке.
В модуле реализовано:
- Запись логов в файлы
- Оповещение о критических проблемах в проекте
- Очищение устаревших лог-файлов
- Таймеры выполнения
- SQL трекер на основе diag
Самый простой способ добавить модуль в свой проект - это выполнить установку через маркетплейс http://marketplace.1c-bitrix.ru/solutions/intensa.logger/.
Также возможно установить модуль вручную. Для этого нужно:
- Клонировать репозиторий в директорию с модулями
/bitrix/modules/
или/local/modules/
- Перейти в директорию
intensa.logger/lib
(командаcd intensa.logger/lib
) - Установить зависимости
composer install --no-dev
- Выполнить установку модуля через админ часть сайта
/bitrix/admin/partner_modules.php
При установке модуль создает:
- Защищённую директорию
/logs/
в корне проекта. Используется для хранения лог-файлов - Почтовое события для оповещений фатальных уровней логгирования
- Агент для удаления устаревших лог-файлов
По умолчанию хранилищем лог-файлов является директория /logs/ в корне проекта. При необходимости в настройках модуля можно изменить данное значение. Защита логов от просмотра в браузере реализована через файл .htaccess
В проектов, использующих в качестве веб-сервера nginx, необходимо обезопасить хранилище самостоятельно - закрыв директорию от просмотра в браузере в конфигах nginx или же изменить пути хранилища логов (вынести хранилище из document_root).
Для удобства хранения и доступа к файлам логов реализован функционал хранения по дням.
Например, все собранные логи за 19 августа 2021 года можно найти в директории /logs/2021-08-19/
.
Название лог файла совпадает с кодом логгера, передоваемым в конструктор класса ILog
В модуле реализованы следующие уровни логирования:
- DEBUG
- INFO
- NOTICE
- WARNING
- ERROR
- CRITICAL
- ALERT
- EMERGENCY
Для каждого уровня лога реализован одноименный метод. Но необошлось и без особенностей, а именно реализован метод log(), который записывает логи с уровнем info и метод fatal(), который является алиасом для alert(). Данные особенность является наследием и с этим приходится жить 🙂
Уровни CRITICAL, ALERT, EMERGENCY по мимо записи данных в лог файл отправляют сообщение администратору сайта, адрес электронной почты можно указать в настройках модуля.
Какой уровень лога использовать в том или ином месте проекта решает сам разработчик. Так как уровень лога - это классификация проблемы. Ниже будут приведены примеры использования логгера.
- Дата и время записи лога
- Уровень логирования
- ID процесса PHP
- Место вызова метода логирования
- Информационное сообщение
- Контекст логирования
// подключение модуля
\Bitrix\Main\Loader::includeModule('intensa.logger');
// инициализация объекта логгера.
// в конструктор передаем код логгера, ему будет соответствовать имя лог-файла
$logger = new \Intensa\Logger\ILog('logger_code');
// пример записи логов уровня INFO
// вторым параметром можно передать данные любого типа
$context = ['яблоко', 'мандарин', 'банан'];
$logger->info('сообщение', $context);
$logger->log('сообщение', $context);
// пример записи логов уровня ERROR
$logger->error('что-то пошло не так', $context);
// пример записи логов уровня ALERT
// в данном случае будет отправлено письмо с информацией из лога
$logger->alert('алярм! мы все сломали', $context);
$logger->fatal('и опять сломали!', $context);
Содержимое лог файла:
[2021-11-24 01:24:30][:info][pid:2696] сообщение Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
[2021-11-24 01:24:30][:info][pid:2696] сообщение Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
[2021-11-24 01:24:30][:error][pid:2696] что-то пошло не так Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
[2021-11-24 01:24:30][:alert][pid:2696] алярм! мы все сломали Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
[2021-11-24 01:24:30][:alert][pid:2696] и опять сломали! Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
// подключение модуля
\Bitrix\Main\Loader::includeModule('intensa.logger');
// инициализация объекта логгера.
// в конструктор передаем код логгера, ему будет соответствовать имя лог-файла
$logger = new \Intensa\Logger\ILog('logger_timer');
$context = ['яблоко', 'мандарин', 'банан'];
$logger->info('Логируем какие-то данные', $context);
// запуск таймера. необходимо передать код таймера
$logger->startTimer('timer_1');
sleep(1);
// остановка таймера. необходимо передать код таймера.
$logger->stopTimer('timer_1');
$logger->startTimer('timer_2');
// можно запускать один таймер внутри другого
$logger->startTimer('timer_internal');
sleep(2);
$logger->stopTimer('timer_internal');
sleep(3);
$logger->stopTimer('timer_2');
// если у таймера не указана точка остановки, то время остановки определяется в дeструкторе класса
$logger->startTimer('dont_stop');
Содержимое лог файла:
[2021-11-24 01:29:47][:info][pid:2704] Логируем какие-то данные Array
(
[0] => яблоко
[1] => мандарин
[2] => банан
)
[2021-11-24 01:29:48][:info][pid:2704] Timer timer_1 Array
(
[CODE] => timer_1
[START_TIME] => 2021-11-24 01:29:47.000000
[STOP_TIME] => 2021-11-24 01:29:48.000000
[EXEC_TIME] => 1.000375032
)
[2021-11-24 01:29:50][:info][pid:2704] Timer timer_internal Array
(
[CODE] => timer_internal
[START_TIME] => 2021-11-24 01:29:48.000000
[STOP_TIME] => 2021-11-24 01:29:50.000000
[EXEC_TIME] => 2.000512838
)
[2021-11-24 01:29:53][:info][pid:2704] Timer timer_2 Array
(
[CODE] => timer_2
[START_TIME] => 2021-11-24 01:29:48.000000
[STOP_TIME] => 2021-11-24 01:29:53.000000
[EXEC_TIME] => 5.000887871
)
[2021-11-24 01:29:53][:info][pid:2704] Timer dont_stop Array
(
[CODE] => dont_stop
[START_TIME] => 2021-11-24 01:29:53.000000
[STOP_TIME] => 2021-11-24 01:29:53.000000
[EXEC_TIME] => 0.010784864
[STOP_POINT] => __destruct
)
Формат логов таймера:
- CODE - код таймера, задает разработчиком при вызове таймера
- START_TIME - время запуска
- STOP_TIME - время остановки
- EXEC_POINT - время исполнения (разница между временем остановки и временем запуска)
- START_POINT - место определения точки запуска (вызов метода startTimer())
- STOP_POINT - место определения точки остановки (вызов метода stopTimer()). Значение "__destruct" означает о том, что не был вызван метод stopTimer() для текущего счетчика и остановка произошла в деструкторе класса.
\Bitrix\Main\Loader::includeModule('intensa.logger');
$logger = new \Intensa\Logger\ILog('logger_sql');
// запускаем трекер sql запросов
$logger->startSqlTracker('get_users');
// пример кода, который делает запрос к базе данных
$users = [];
$result = \Bitrix\Main\UserTable::getList([
'select' => ['ID','SHORT_NAME'],
'order' => ['LAST_LOGIN'=>'DESC'],
'limit' => 3
]);
// остановка трекера
$logger->stopSqlTracker('get_users');
Содержимое лог файла:
[2021-11-24 01:29:48][:info][pid:1138] SqlTracker get_users: Array
(
[0] => Array
(
[query] => SELECT
`main_user`.`ID` AS `ID`,
CONCAT(`main_user`.`LAST_NAME`, ' ', UPPER(SUBSTR(`main_user`.`NAME`, 1, 1)), '.') AS `SHORT_NAME`
FROM `b_user` `main_user`
ORDER BY `main_user`.`LAST_LOGIN` DESC
LIMIT 0, 3
[time] => 0.0076520442962646
)
)
Ниже описаны доступные методы класса ILog
, которые помогут костомизировать поведение каждого отдельного объекта логгера.
\Bitrix\Main\Loader::includeModule('intensa.logger');
$logger = new \Intensa\Logger\ILog('logger_sql');
// Метод заставляет логгер перезаписывать файл при каждом новом вызове логирующего метода
// Обычно данная фича может приходится при дебаге
$logger->rewrite();
// Через этот метод можно установить дополнительный email для получения алерт сообщений на почту
$logger->setAlertEmail('additional_admin@no-reply.com');
$logger->setAlertEmail('additional_admin2@no-reply.com');
// Позволяет отключить отладку для конкретного логгера.
// Данная настройка уберет из лог файла информацию о месте вызова логгера
// Рекомендуется использовать данную настройку для логгеров записывающих большое кол-во данных при одном вызове
// Снижает количество оперативной памяти выделяемой php
$logger->notUseBacktrace();
// Включает отладку для конкретного логгера.
// Используется в случае когда глобально в настройках модуля выключена настройка отладки
$logger->useBacktrace();
Для запуска юнит тестов необходимо:
- Перейти в директорию
/lib/
- Установить зависимости. Выполнить
composer install
- Выполнить
./vendor/bin/phpunit tests
Шишкин Иван - i.shishkin@intensa.ru - telegram @ishishkin