Здесь будет приведена небольшая шпаргалка по использованию 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 на данный момент устаревший. подробнее: глава “Using 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 , но пока его не приняли (и не знаю, примут ли вообще), моими дополнениями можно воспользоваться так:
Скачать форкнутую репу , именно ветку loggingtoiblock
Слить папку из репы с этой папкой:

Выполнить composer dump-autoload --optimize
Мои дополнения состоят из трёх файлов , в существующие файлы изменения не вносились.
Надеюсь, возможность логирования в инфоблок кому-нибудь пригодится.
Удачного дня.