Журнал событий - чтение, очистка, свои записи
Читаем журнал событий сайта, добавляем в него свои записи и разбираемся, почему он разрастается до гигабайтов.
Решение
Смотрим последние записи журнала:
$res = CEventLog::GetList(['TIMESTAMP_X' => 'DESC'], []); // свежие записи сверху// на большом журнале выборку ограничивают фильтром по типу события и датам$i = 0;while ($row = $res->Fetch()) { printf("%-20s %-24s %s\n", $row['TIMESTAMP_X'], $row['AUDIT_TYPE_ID'], mb_substr($row['DESCRIPTION'], 0, 40)); if (++$i >= 20) break;}В журнал попадают действия пользователей и системные происшествия: вход в админку, смена прав, ошибки модулей. Срабатывания обработчиков событий туда не пишутся вовсе - это два разных механизма с похожими названиями.
Фильтруем по типу события:
$res = CEventLog::GetList(['TIMESTAMP_X' => 'DESC'], [ 'AUDIT_TYPE_ID' => 'USER_LOGIN_FAIL', // неудачные попытки входа '>=TIMESTAMP_X' => date('d.m.Y', strtotime('-7 days')),]);printf("неудачных входов за неделю: %d\n", $res->SelectedRowsCount());Всплеск неудачных входов с разных адресов - это обычный перебор паролей извне, а не сбой самого сайта. Такие записи как раз и выглядят странными, когда журнал событий открывают в первый раз.
Добавляем свою запись:
CEventLog::Log( 'SECURITY', // уровень: SECURITY, INFO, WARNING, ERROR 'MY_IMPORT_FAILED', // свой тип события, придумывается автором 'my.module', $orderId, // идентификатор объекта, к которому относится 'обмен оборвался на позиции 145');Свой тип события ничем не ограничен и появляется в фильтре журнала сразу после первой же записи. Это удобное место для следов фоновых процессов: хранилище уже есть, интерфейс просмотра тоже, а чистится журнал сам по расписанию.
Настраиваем срок хранения:
// сколько дней держать записи: чистку выполняет агент главного модуляCOption::SetOptionString('main', 'event_log_cleanup_days', '30');COption::SetOptionString('main', 'event_log_logout', 'Y'); // писать выходыЖурнал растёт быстро на посещаемом сайте и без ограничения занимает заметное место в базе данных. Чистку выполняет агент главного модуля, поэтому при выключенных агентах записи копятся дальше, сколько бы дней ни было задано в настройке хранения.
Разбор инцидента по журналу упирается в две вещи: включён ли был нужный тип события и не успел ли агент вычистить записи по сроку хранения. Обе проверяются за минуту и экономят час поисков в заведомо пустом журнале. На проектах, где разбор инцидентов вероятен, срок хранения ставят с запасом и включают запись входов и смены прав до того, как что-нибудь случится.
Состав записываемых типов задаётся настройками главного модуля отдельно для каждого вида событий. Отключённый тип не пишется вовсе, и восстановить пропущенные события задним числом уже невозможно.
Типичные проблемы
Журнал занимает несколько гигабайт в базе.
Не задан срок хранения либо не работают агенты. Чистку выполняет агент главного модуля, и без него записи копятся бесконечно.
Нужного события в журнале нет.
Его тип отключён в настройках главного модуля. Пропущенные записи задним числом не восстанавливаются.
Много записей о неудачном входе.
Обычный перебор паролей извне. Это не сбой сайта, но повод включить ограничение попыток входа.
Своя запись не появилась в журнале.
Не указан уровень или тип события. Вызов без обязательных аргументов молча ничего не пишет.
Записи есть, а кто их сделал - непонятно.
Действие выполнено агентом или консольным скриптом, где текущего пользователя нет. Идентификатор пользователя в таких записях пуст.
Частые вопросы
Чем журнал отличается от журнала ошибок PHP?
Журнал событий пишет действия внутри платформы, журнал PHP - ошибки выполнения кода. Ошибка модуля попадает в оба, но с разной подробностью.
Можно ли получать письмо о новой записи?
Штатной рассылки нет, но обработчик события записи в журнал легко её добавляет. Так делают уведомления о неудачных входах и о критичных ошибках.
Как посмотреть, кто удалил элемент?
По записи журнала с типом события удаления, если этот тип включён. В ней хранятся идентификатор пользователя и объекта.
Стоит ли писать в журнал из своего кода?
Для редких значимых событий - да: хранение и чистка уже настроены. Для потока отладочных сообщений лучше свой файл: журнал не рассчитан на тысячи записей в минуту.
Смежное
-
События на практике - оглавление подтемы
-
Логирование решения: логгер по стандарту, настройка, контекст - журнал самого решения рядом со штатным
-
Обработчик события: регистрация, аргументы, отмена действия - откуда брать события
-
База растёт: журналы, статистика, старые данные и чистка - когда журнал занял половину базы
-
Агенты и cron - кто чистит журнал
-
Основы безопасности - что показывают неудачные входы
-
Ядро D7 - основы - устройство ядра целиком
-
Журнал обмена: как читать и что означают его сообщения - соседний журнал со своими правилами
-
Отладка на боевом сайте: журналы, режим ошибок, поиск виновника - журналы при разборе сбоя
-
Свой журнал решения: файл, ротация, что писать - журнал своего кода, а не платформы
-
История изменений своей таблицы: версии, автор, откат - своя история вместо журнала событий