Собственный лог-файл для скриптов в MODX

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

Все, кто работают с MODX, прекрасно знакомы с журналом ошибок, в который следует заглядывать в первую очередь, если что-то на сайте работает не так, как ожидается. Система записи системных сообщений в файл (лог) есть в любой CMS и фреймворке, этим никого не удивишь. Более того, при написании кода иногда полезно бывает записывать в лог отладочную информацию, которая может помочь впоследствии выявить проблему, если что-то пойдет не так.

Очень актуально это становится, когда приходится писать код для интеграции со сторонними системами. Например, когда другая система связывается с сайтом и записывает какие-то данные или даже просто обращается по API. В таком случае, запись входящих данных – производственная необходимость. Это нужно делать, чтобы быть уверенным, что данные приходят безопасные и обрабатываются правильно.

В MODX все такие события пишутся в файл /core/cache/logs/error.log. Начиная с версии 2.7.0 стало возможным на уровне системных настроек менять путь и имя файла для такого журнала ошибок (системные настройки error_log_filename и error_log_filepath). Но самое интересное, что если пользоваться MODX в режиме API, т.е. когда он вызывается внутри скрипта, возможность переопределять поведение регистрации ошибок имеется уже давно. Хотя по аннотациям к коду все не так однозначно, что в общем-то ожидаемо в случае MODX :).

У корневого класса MODX есть два метода, которые позволяют изменить поведение записи в журнал. Это setLogLevel и setLogTarget. Первый меняет уровень регистрации ошибок. Если коротко, то он говорит, какого уровня ошибки стоит записывать в журнал. Если установить xPDO::LOG_LEVEL_FATAL, то будут записывать только самые грубые ошибки, при которых вообще ничего не работает. А вот если xPDO::LOG_LEVEL_DEBUG, то будут записываться даже отладочные сообщения, которые обычно не нужны, но бывают полезны, если нужно разобраться в поведении приложения.

А вот метод setLogTarget любопытный. Исходя из описания, он позволяет поменять конечную цель, куда будут отправляться сообщения об ошибках. На выбор есть три варианта: ECHO, HTML и FILE. Первые два отправляют сообщения об ошибках прямо в стандартный поток вывода. HTML тоже самое, что и ECHO, но добавляет возможность форматирования сообщений с помощью HTML-тегов, что удобно, когда сообщения выводятся в браузер пользователя. Параметр со значением FILE позволяет записывать сообщения в файл, что следует из названия. Но для FILE существует еще вариант, когда можно указать вместо строки массив формата ['target' => 'FILE', 'options' => ['filename' => 'error.log', 'filepath' => 'core/cache/logs']]. И вот здесь уже можно проявить фантазию.

Покажу на практическом примере. У меня есть скрипт, который принимает запросы от стороннего сервиса и обновляет параметры отдельных товаров. Мне важно быть уверенным, что данные во-первых приходят, во-вторых я могу в любом момент сделать отчет, чтобы показать клиенту, что было обновлено, а что нет и нет ли ошибок. Мой код инициализации MODX в скрипте выглядит вот так:

require __DIR__ . '/config.core.php';
require MODX_CORE_PATH . 'model/modx/modx.class.php';

$modx = new modX();
$modx->initialize('mgr');
$modx->getService('error','error.modError', '', '');
	
$modx->setLogTarget(['target' => 'FILE', 'options' => ['filename' => 'import.log']]);
$modx->setLogLevel(xPDO::LOG_LEVEL_DEBUG);

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

Опытные программисты могут меня пожурить, что мол на пустом месте выдумал проблему и будут отчасти правы. Потому расскажу, как еще можно добиться записи результатов выполнения скрипта в файл. Сделать это очень просто средствами операционной системы, в моем случае Linux, при условии, что скрипт отдает все свои сообщения в стандартный поток вывода. Да, эта тот самый вариант с ECHO. А после вызываем наш скрипт и указываем, что нужно весь поток вывода записать в файл, например вот так: php /some/path/script.php > ~/core/cache/logs/import.log. Но в таком случае стоит учесть, что в лог будут попадать всё, что пишется в этот самый поток вывода, т.е. все конструкции echo, print_r и var_dump.

P.S. Напоминаю, что вы всегда можете поддержать меня финансово, что ускорит выход заметок о MODX в блоге.

На чытанне спатрэбілася 3 хвіліны Нататка змяшчае 635 слоў

Сябры, акрамя блога, я амаль што рэгулярна пішу адмысловую рассылку пра праграмванне і тэхналогіі, дзе раз на двы тыдні збіраю самыя цікавыя навіны тэхналогій і раблю агляд цікавых інструментаў, якія мне трапіліся. Таму хутчэй падпісвайцеся, каб не прапусціць штосці цікавае наступным разам!