Здесь будет приведена небольшая шпаргалка по использованию monolog и monolog-adapter в Битриксе.
monolog-adapter:
Конфиги вынесены за пределы логики и располагаются в bitrix/.settings.php Логер feedback будет писать данные в журнал событий.
Теперь кратка справка о самом monolog
Уровни:
DEBUG
INFO
NOTICE
WARNING
ERROR
CRITICAL
ALERT
EMERGENCY
- в этом списке они расположены по возрастанию важности.Каналы:
$loggerMonolog = new Logger('logger');$loggerToSlack = new Logger('loggerToSlack');$loggerFormatted = new Logger('loggerFormatted'); |
Хандлеры:
StreamHandler - логирование в файл
$loggerMonolog = new Logger('logger');$loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerToFile.log', Logger::INFO));$loggerMonolog->addWarning('test logs');$loggerMonolog->warning('warning text example');$loggerMonolog->error('error text example');$loggerMonolog->error('error text', array('session' => $_SESSION));$loggerMonolog->info('info text example');$loggerMonolog->addInfo('new message', array('session' => $_SESSION)); |
RotatingFileHandler
$handlerInfoStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/info.log', 0, Logger::INFO); $handlerWarningStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/warning.log', 0, Logger::WARNING); $handlerErrorStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/error.log', 0, Logger::ERROR); $handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $handlerWarningStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $handlerErrorStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $loggerMonolog->pushHandler($handlerInfoStream); $loggerMonolog->pushHandler($handlerWarningStream); $loggerMonolog->pushHandler($handlerErrorStream); |
NativeMailerHandler
$handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::INFO); $handlerMail->setFormatter(new HtmlFormatter()); $handlerMail->setContentType('text/html'); $loggerMonolog->pushHandler($handlerMail); |
SlackWebhookHandler
$handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhXH1o******, null, null, true, "sunglasses", false, false, Logger::INFO); $loggerToSlack->warning('warning text example to slack <!everyone>');$loggerToSlack->info(json_encode(array('session' => $_SESSION))); |
Первый параметр - это webhookUrl
RollbarHandler
для работы с Rollbаr ставим пакет "rollbar/rollbar": "^1"
RollbarHandler используем именно из этого пакета, т.к RollbarHandler из пакета monolog на данный момент устаревший. подробнее:
//use Monolog\Handler\RollbarHandler; use Rollbar\Rollbar; use Rollbar\Payload\Level; use Rollbar\Monolog\Handler\RollbarHandler; Rollbar::init( |
array( 'access_token' => '5a7e9c4897f341e3abc1********', 'environment' => 'development' ));$loggerMonolog->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO)); |
BrowserConsoleHandler
$loggerMonolog->pushHandler(new BrowserConsoleHandler()); |
Форматтеры:
LineFormatter - запись лога представляет из себя строку
HtmlFormatter - записи форматируются в удобную для чтения html таблицу, обычно используется при отправке лога на e-mail
JsonFormatter - запись преобразуется в json-строку
Процессоры:IntrospectionProcessor - добавляет информацию о текущей строке/файле/классе/методе, в которых производится запись в лог
WebProcessor - добавляет в лог текущие url, метод запроса и ip клиента
MemoryUsageProcessor - добавляет в лог сведения о текущем использовании памяти
Один из возможных вариантов применения monolog:
$user = new CUser; $userID = $user->Add($arFields); if (!$userID){ $loggerMonolog = new Logger('loggerErrorUserRegistration'); $loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerErrorUserRegistration.log', Logger::ALERT)); $handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::ALERT); $handlerMail->setFormatter(new HtmlFormatter()); $handlerMail->setContentType('text/html'); $loggerMonolog->pushHandler($handlerMail); $handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/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”, null, null, true, false, false, false, Logger::ALERT); $loggerToSlack = new Logger('loggerToSlack'); $loggerToSlack->pushHandler($handlerSlack); loggerToSlack->setProcessor(new IntrospectionProcessor(Logger::ALERT)); $loggerMonolog->alert('error registration user'); $loggerToSlack->alert('error registration user <!everyone>'); } |
Ссылки:
Полный код для примера:
use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Handler\BrowserConsoleHandler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\HtmlFormatter; use Monolog\Formatter\ScalarFormatter; use Monolog\Formatter\JsonFormatter; use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\NativeMailerHandler; use Monolog\Handler\SlackWebhookHandler; use Monolog\Handler\LogglyHandler; //use Monolog\Handler\RollbarHandler; use Rollbar\Rollbar; use Rollbar\Payload\Level; use Rollbar\Monolog\Handler\RollbarHandler; $loggerBitrix = \Monolog\Registry::getInstance('debug'); $loggerBitrix->info('Debug session', array( 'item_id' => 0, 'Data' => $_SESSION)); $loggerApp = \Monolog\Registry::getInstance('app'); $loggerApp->info('info text example'); $loggerMonolog = new Logger('logger'); $loggerMonolog->pushHandler(new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/loggerToFile.log', Logger::INFO)); $loggerMonolog->pushHandler(new BrowserConsoleHandler()); $handlerInfoStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/info.log', 0, Logger::INFO); $handlerWarningStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/warning.log', 0, Logger::WARNING); $handlerErrorStream = new RotatingFileHandler($_SERVER["DOCUMENT_ROOT"] . '/logs/error.log', 0, Logger::ERROR); $handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $handlerWarningStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $handlerErrorStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); $loggerMonolog->pushHandler($handlerInfoStream); $loggerMonolog->pushHandler($handlerWarningStream); $loggerMonolog->pushHandler($handlerErrorStream); $handlerMail = new NativeMailerHandler('root@localhost.com', "monolog", COption::GetOptionString('main', 'email_from'), Logger::INFO); $handlerMail->setFormatter(new HtmlFormatter()); $handlerMail->setContentType('text/html'); $loggerMonolog->pushHandler($handlerMail); $handlerSlack = new SlackWebhookHandler("https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhX********", null, null, true, "sunglasses", false, false, Logger::INFO); $loggerToSlack = new Logger('loggerToSlack'); $loggerMonolog->pushHandler($handlerSlack); $loggerToSlack->pushHandler($handlerSlack); $loggerMonolog->pushHandler(new LogglyHandler('70997a00-a48f-4e33-9059-812d67a5f383/tag/monolog', Logger::INFO)); Rollbar::init( array( 'access_token' => '5a7e9c4897f341e3abc1*******', 'environment' => 'development' )); $loggerMonolog->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO)); $loggerMonolog->addWarning('test logs'); $loggerMonolog->warning('warning text example'); $loggerMonolog->error('error text example'); $loggerMonolog->error('error text', array('session' => $_SESSION)); $loggerMonolog->info('info text example'); $loggerMonolog->info('info text', array('session' => $_SESSION)); $loggerMonolog->debug('debug text', array('session' => $_SESSION)); $loggerMonolog->info(json_encode(array('session' => $_SESSION))); $loggerMonolog->addInfo('new message', array('session' => $_SESSION)); $loggerToSlack->warning('warning text example to slack <!everyone>'); |
$loggerToSlack->info(json_encode(array('session' => $_SESSION))); $dateFormat = "Y n j, g:i a"; $output = "%datetime% > %level_name% > %message% %context% %extra%\n"; $formatter = new LineFormatter($output, $dateFormat); $streamFormatted = new StreamHandler($_SERVER["DOCUMENT_ROOT"] . '/formattedLog.log', Logger::DEBUG); $streamFormatted->setFormatter($formatter); $loggerFormatted = new Logger('loggerFormatted'); $loggerFormatted->pushHandler($streamFormatted); $loggerFormatted->warning('warning text example'); $loggerFormatted->error('error text example'); $loggerFormatted->error('error text', array('session' => $_SESSION)); $loggerFormatted->info('info text example'); $loggerFormatted->info('info text', array('session' => $_SESSION)); |
Этот же код, но только более красиво оформленный, лежит здесь
После установки monolog-adapter в init.php нужно прописать:
require_once($_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php'); \Bex\Monolog\MonologAdapter::loadConfiguration(); |
monolog-adapter позволяет хранить конфиги monolog в .settings.php. Если воспользоваться этой возможностью, то вышележащий код можно переписать так:
use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Handler\BrowserConsoleHandler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\HtmlFormatter; use Monolog\Formatter\ScalarFormatter; use Monolog\Formatter\JsonFormatter; use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\NativeMailerHandler; use Monolog\Handler\SlackWebhookHandler; use Monolog\Handler\LogglyHandler; //use Monolog\Handler\RollbarHandler; use Rollbar\Rollbar; use Rollbar\Payload\Level; use Rollbar\Monolog\Handler\RollbarHandler; $loggerBitrix = \Monolog\Registry::getInstance('debug'); $loggerBitrix->info('Debug session', array( 'item_id' => 0, 'Data' => $_SESSION )); $loggerToFile = \Monolog\Registry::getInstance('loggerToFile'); $loggerToBrowserConsole = \Monolog\Registry::getInstance('loggerToBrowserConsole'); $loggerToRotatingFile = \Monolog\Registry::getInstance('loggerToRotatingFile'); $loggerToNativeMailer = \Monolog\Registry::getInstance('loggerToNativeMailer'); $loggerToSlackWebhook = \Monolog\Registry::getInstance('loggerToSlackWebhook'); $loggerToRollbar = new Logger('loggerToRollbar'); $configRollbar = \Bitrix\Main\Config\Configuration::getInstance()->get('rollbar'); Rollbar::init( array( 'access_token' => $configRollbar["access_token"], 'environment' => $configRollbar['development'] ) ); $loggerToRollbar->pushHandler(new RollbarHandler(Rollbar::logger(), Logger::INFO)); $loggerToFileFormatted = \Monolog\Registry::getInstance('loggerToFileFormatted'); $loggerToAll = \Monolog\Registry::getInstance('loggerToAll'); $loggerToAll->addWarning('test logs settings all'); $loggerToAll->warning('warning text example settings all'); $loggerToAll->error('error text example settings all'); $loggerToAll->error('error text settings all', array('session' => $_SESSION)); $loggerToAll->info('info text example settings all'); $loggerToAll->info('info text settings all', array('session' => $_SESSION)); $loggerToAll->debug('debug text settings all', array('session' => $_SESSION)); $loggerToAll->info(json_encode(array('session settings all' => $_SESSION))); $loggerToAll->addInfo('new message settings all', array('session' => $_SESSION)); /* monolog-adapter для работы с конфигами использует cascade, а у cascade, как я понял, отсутствует поддержка подобных методов: |
$handlerMail->setContentType('text/html'); $handlerInfoStream->setFilenameFormat('{date}-{filename}', 'Y/m/d'); */ |
Конфиги в .settings.php :
'monolog' => array( 'value' => array( 'formatters' => array( 'NativeMailerFormatter' => array( 'class' => '\Monolog\Formatter\HtmlFormatter', ), 'StreamHandlerFormatter' => array( 'class' => '\Monolog\Formatter\LineFormatter', "format" => "%datetime% > %level_name% > %message% %context% %extra%\n", "dateFormat" => "Y n j, g:i a" ) ), 'handlers' => array( 'default' => array( 'class' => '\Monolog\Handler\StreamHandler', 'level' => 'INFO', 'stream' => '/app.log' ), 'debug_log' => array( 'class' => '\Bex\Monolog\Handler\BitrixHandler', 'level' => 'DEBUG', 'event' => 'DEBUG', 'module' => '' ), 'BitrixIblockHandler' => array( 'class' => '\Bex\Monolog\Handler\BitrixIblockHandler', 'level' => 'DEBUG', 'iblock_id' => 10, 'rotating_count_elements' => 5, 'rotating_count_days' => 2, 'notify_to_admin' => true ), 'StreamHandler' => array( 'class' => '\Monolog\Handler\StreamHandler', 'level' => 'INFO', 'stream' => './loggerToFile.log' ), 'StreamHandlerFormatted' => array( 'class' => '\Monolog\Handler\StreamHandler', 'level' => 'DEBUG', 'stream' => './loggerToFileFormatted.log', 'formatter' => "StreamHandlerFormatter" ), 'BrowserConsoleHandler' => array( 'class' => '\Monolog\Handler\BrowserConsoleHandler', ), 'RotatingFileHandler' => array( 'class' => '\Monolog\Handler\RotatingFileHandler', 'level' => 'INFO', 'maxFiles' => 5, 'filename' => './logs/info.log', ), 'NativeMailerHandler' => array( 'class' => '\Monolog\Handler\NativeMailerHandler', 'to' => 'root@localhost.com', 'subject' => 'monolog info', 'level' => 'INFO', 'from' => "null@" . $_SERVER['SERVER_NAME'], 'formatter' => "NativeMailerFormatter" ), 'SlackWebhookHandler' => array( 'class' => '\Monolog\Handler\SlackWebhookHandler', 'level' => 'INFO', 'webhookUrl' => "https://hooks.slack.com/services/T04NB7T81/BAC35BJT1/95pr8ZlfbvhXH1*******" ) ), 'loggers' => array( 'app' => array( 'handlers' => array('default'), ), 'debug' => array( 'handlers' => array('debug_log'), ), 'loggerToFile' => array( 'handlers' => array('StreamHandler'), ), 'loggerToFileFormatted' => array( 'handlers' => array('StreamHandlerFormatted'), ), 'loggerToBrowserConsole' => array( 'handlers' => array('BrowserConsoleHandler'), ), 'loggerToRotatingFile' => array( 'handlers' => array('RotatingFileHandler'), ), 'loggerToNativeMailer' => array( 'handlers' => array('NativeMailerHandler'), ), 'loggerToSlackWebhook' => array( 'handlers' => array('SlackWebhookHandler'), ), 'loggerToAll' => array( 'handlers' => array('debug_log', 'StreamHandler', 'StreamHandlerFormatted', 'BrowserConsoleHandler', 'RotatingFileHandler', 'NativeMailerHandler', 'SlackWebhookHandler', 'BitrixIblockHandler'), ), ) ), 'readonly' => false ), 'rollbar' => array( 'value' => array( 'access_token' => '5a7e9c4897f341e3abc1be*******', 'environment' => 'development' ) ), |
Ещё я решил дополнить monolog-adapter и добавил возможность логирования в инфоблок
и показ уведомлений в админке:
Пример конфига:
'monolog' => array( 'value' => array( 'formatters' => array( 'StreamHandlerFormatter' => array( 'class' => '\Monolog\Formatter\LineFormatter', "format" => "%datetime% > %level_name% > %message% %context% %extra%\n", "dateFormat" => "Y n j, g:i a" ) ), 'handlers' => array( ........... 'BitrixIblockHandler' => array( 'class' => '\Bex\Monolog\Handler\BitrixIblockHandler', 'level' => 'DEBUG', 'iblock_id' => 10, //id инфоблока, в который будут складываться записи 'rotating_count_elements' => 5, //удалить все записи из инфоблока, кроме первых 'rotating_count_elements' 'rotating_count_days' => 2, // удалить элементы из инфоблока, которые старше 'rotating_count_days' дней 'notify_to_admin' => true //показ уведомлений администратору ), ), 'loggers' => array( 'app' => array( 'handlers' => array('default'), ), 'debug' => array( 'handlers' => array('debug_log'), ), 'loggerToFile' => array( 'handlers' => array('StreamHandler'), ), 'loggerToFileFormatted' => array( 'handlers' => array('StreamHandlerFormatted'), ), 'loggerToBrowserConsole' => array( 'handlers' => array('BrowserConsoleHandler'), ), 'loggerToRotatingFile' => array( 'handlers' => array('RotatingFileHandler'), ), 'loggerToNativeMailer' => array( 'handlers' => array('NativeMailerHandler'), ), 'loggerToSlackWebhook' => array( 'handlers' => array('SlackWebhookHandler'), ), 'loggerToAll' => array( 'handlers' => array('debug_log', 'StreamHandler', 'StreamHandlerFormatted', 'BrowserConsoleHandler', 'RotatingFileHandler', 'NativeMailerHandler', 'SlackWebhookHandler', 'BitrixIblockHandler'), ), ) ), 'readonly' => false ),` |
Пример использования :
use Monolog\Logger; $loggerToAll = \Monolog\Registry::getInstance('loggerToAll');$loggerToAll->addWarning('test logs settings all'); $loggerToAll->warning('warning text example settings all'); $loggerToAll->error('error text example settings all'); $loggerToAll->error('error text settings all', array('session' => $_SESSION)); $loggerToAll->info('info text example settings all'); $loggerToAll->info('info text settings all', array('session' => $_SESSION)); $loggerToAll->debug('debug text settings all', array('session' => $_SESSION)); $loggerToAll->info(json_encode(array('session settings all' => $_SESSION))); $loggerToAll->addInfo('new message settings all', array('session' => $_SESSION)); |
Я послал pull-request в репозиторий monolog-adapter
Скачать форкнутую репу
Слить папку
Выполнить composer dump-autoload --optimize
Мои дополнения состоят из трёх файлов
Надеюсь, возможность логирования в инфоблок кому-нибудь пригодится.
Удачного дня.