Bitrix log ошибок

Просмотров: 9821
Дата последнего изменения: 21.04.2022

Сложность урока:

3 уровень — средняя сложность. Необходимо внимание и немного подумать.

4

5

Недоступно в лицензиях:

Ограничений нет

  Введение

В ядро добавлены логгеры, реализующие интерфейс PSR-3:

  • базовый абстрактный класс BitrixMainDiagLogger, реализующий интерфейс PSR-3;
  • файловый логгер BitrixMainDiagFileLogger;
  • syslog логгер BitrixMainDiagSysLogger.

Логгеры пользуются форматтером логов BitrixMainDiagLogFormatter, который делает замены плейсхолдеров в соответствии с PSR-3.

Примечание: Библиотека доступна с версии main 21.900.0.

  Logger Interface

Интерфейс PsrLogLoggerInterface довольно прост, это — набор функций логирования, поддерживающих уровни логирования. Уровни задаются константами PsrLogLogLevel::*.

interface LoggerInterface
{
    public function emergency($message, array $context = array());
    public function alert($message, array $context = array());
    public function critical($message, array $context = array());
    public function error($message, array $context = array());
    public function warning($message, array $context = array());
    public function notice($message, array $context = array());
    public function info($message, array $context = array());
    public function debug($message, array $context = array());
    public function log($level, $message, array $context = array());
}

В сообщении могут быть {плейсхолдеры}, которые заменяются данными из ассоциативного массива $context.

Также полезным может быть интерфейс PsrLogLoggerAwareInterface, если вы хотите сообщить, что ваш объект готов принять логгер PSR-3:

interface LoggerAwareInterface
{
    public function setLogger(LoggerInterface $logger);
}

  Логгеры в продукте

Логгеры в продукте расширены по сравнению с PSR-3. Можно:

  • установить минимальный уровень логирования, ниже которого логгер ничего не выведет,
  • установить форматтер.

Файловый логгер BitrixMainDiagFileLogger умеет записывать сообщения в файл, указанный в конструкторе. Если размер лога превышает указанный максимальный, производится однократная ротация файла. Ноль означает не делать ротацию. По умолчанию размер 1 Мб.

$logger = new DiagFileLogger($logFile, $maxLogSize);
$logger->setLevel(PsrLogLogLevel::ERROR);
// выведет в лог
$logger->error($message, $context);
// НЕ выведет в лог
$logger->debug($message, $context);

Syslog логгер BitrixMainDiagSysLogger является надстройкой над функцией php syslog. Конструктор принимает параметры, использующиеся функцией openlog.

$logger = new DiagSysLogger('Bitrix WAF', LOG_ODELAY, $facility);
$logger->warning($message);

На файловый логгер переведена функция AddMessage2Log и класс BitrixMainDiagFileExceptionHandlerLog, а также логирование в модуле Проактивная защита (security).

  Форматирование сообщения

В логгер можно установить форматтер сообщения. По умолчанию используется форматтер BitrixMainDiagLogFormatter, реализующий интерфейс BitrixMainDiagLogFormatterInterface:

interface LogFormatterInterface
{
	public function format($message, array $context = []): string;
}

Конструктор форматтера принимает параметры $showArguments = false, $argMaxChars = 30 (показывать значение аргументов в трейсе, максимальная длина аргумента).

$logger = new MainDiagFileLogger(LOG_FILENAME, 0);
$formatter = new MainDiagLogFormatter($showArgs);
$logger->setFormatter($formatter);

Основная задача форматтера — подставлять значения в плейсхолдеры сообщения из массива контекста. Форматтер умеет обрабатывать определенные плейсхолдеры:

  • {date} — текущее время * ;
  • {host} — HTTP host * ;
  • {exception} — объект исключения (Throwable);
  • {trace} — массив бектрейса;
  • {delimiter} — разделитель сообщений * .

* — не обязательно передавать в массиве контекста, подставляется автоматически.

$logger->debug(
    "{date} - {host}n{trace}{delimiter}n", 
    [
        'trace' => DiagHelper::getBackTrace(6, DEBUG_BACKTRACE_IGNORE_ARGS, 3)
    ]
);

Значения из массива контекста форматтер старается привести к удобному виду в зависимости от типа значения. Принимаются строки, массивы, объекты.

Использование

В простом виде объект может принять логгер снаружи, поддерживая интерфейс PsrLogLoggerAwareInterface. Можно использовать соответствующий трейт:

use BitrixMainDiag;
use PsrLog;

class MyClass implements LogLoggerAwareInterface
{
	use LogLoggerAwareTrait;
	
	public function doSomething()
	{
	    if ($this->logger)
	    {
	        $this->logger->error('Error!');
	    }
	}
}

$object = new MyClass();
$logger = new DiagFileLogger("/var/log/php/error.log");
$object->setLogger($logger);
$object->doSomething();

Однако, не удобно менять код на работающем проекте, чтобы передать логгер в нужный объект. Для этого в классе логгера предусмотрена своя фабрика. На вход фабрике передается строка-идентификатор логгера:

use BitrixMainDiag;
use PsrLog;

class MyClass implements LogLoggerAwareInterface
{
	use LogLoggerAwareTrait;
	
	public function doSomething()
	{
	    if ($logger = $this->getLogger())
	    {
	        $logger->error('Error!');
	    }
	}

	protected function getLogger()
	{
		if ($this->logger === null)
		{
			$logger = DiagLogger::create('myClassLogger', [$this]);
			$this->setLogger($logger);
		}

		return $this->logger;
	}
}

Настройка

В корневой секции файла .settings.php логгеры указываются в ключе loggers. Синтаксис описания совпадает с настройками ServiceLocator. Отличие состоит в том, что сервис-локатор является реестром, а здесь настраивается фабрика.

В замыкание-конструктор constructor можно передать дополнительные параметры через второй параметр фабрики DiagLogger::create('logger.id', [$this]). Параметры позволяют гибко включать логирование в зависимости от переданных параметров, в том числе вызывать методы самого объекта.

Дополнительно можно указать минимальный уровень журналирования (level) и собственный форматтер (formatter). Форматтер ищется в сервис локаторе по его идентификатору.

// /bitrix/.settings.php
return [
	//...
	'services' => [
		'value' => [
			//...
			'formatter.Arguments' => [
				'className' => 'BitrixMainDiagLogFormatter',
				'constructorParams' => [true],
			],
		],
		'readonly' => true,
	]
	'loggers' => [
		'value' => [
			//...
			'main.HttpClient' => [
//				'className' => '\Bitrix\Main\Diag\FileLogger',
//				'constructorParams' => ['/home/bitrix/www/log.txt'],
//				'constructorParams' => function () { return ['/home/bitrix/www/log.txt']; },
				'constructor' => function (BitrixMainWebHttpClient $http, $method, $url) { 
					$http->setDebugLevel(BitrixMainWebHttpDebug::ALL);
					return new BitrixMainDiagFileLogger('/home/bitrix/www/log.txt');
				},
				'level' => PsrLogLogLevel::DEBUG,
				'formatter' => 'formatter.Arguments',
			],
		],
		'readonly' => true,
	],
	//...
];

При указании замыкания-конструктора constructor желательно использовать файл .settings_extra.php, чтобы не потерять код при сохранении настроек из API.

Существует PsrLogNullLogger, его можно установить, если не хочется писать if($logger) перед каждым вызовом логгера. Однако, следует учитывать, стоит ли делать дополнительную работу по формированию сообщения и контекста.

  Классы

Список классов, поддерживающих фабрику логгеров:

Класс Id логгера Передаваемые параметры
BitrixMainWebHttpClient main.HttpClient [$this, $this->queryMethod, $this->effectiveUrl]

Объяснять, что такое логи — нет необходимости. Когда есть логи, то проще разобраться с возникшими проблемами и выяснить, почему они начались. Основные моменты в использовании логов.

Логи не должны занимать всё свободное пространство на диске, т.е. в логи нужно помещать только нужную информацию, а не всё подряд. Устаревшие логи должны удаляться. Для удаления устаревших логов лучше всего настроить задание на cron.

Логи должны быть удобными для изучения — логи с ошибками и логи с диагностическими данными должны помещаться в разные файлы. Желательно разделять логи на временные интервалы — например, ежедневные логи (наиболее распространенный вариант, или, например, по месяцам, или неделям).

Все логи нужно держать в одной папке, чтобы было удобней их изучать (/logs/, /_logs/, /local/logs/ и т.п. ). В целях защиты следует закрыть доступ к папке с логами по http — настраивается в .htacces,

deny from all

и/или добавить к названию файла уникальный идентификатор.

Папку для логов надо предварительно создать и убедиться, что битрикс (веб-сервер) имеет права на запись в нее.

В системе 1С-Битрикс существует 2 вида логов:

ADDMESSAGE2LOG(…)

Это функция из старого ядра. Многие модули пишут через нее отладочную информацию.

Пример настройки места хранения логов, выводимых данной функцией, выглядит так (папка logs/bx должна быть создана):

define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"] . "/logs/bx/" . date("Y-m-d") . ".log");

Прописать данную настройку можно, например, в dbconn.php.

СЕКЦИЯ EXCEPTION_HANDLING В ФАЙЛЕ .SETTINGS.PHP

Это уже функционал нового ядра D7.

Битрикс через данный функционал пишет информацию обо всех ошибках и исключениях. Что именно пишется — зависит от настроек.

Пример настройки логов с разделением по дате:

'exception_handling' => array (
  'value' => array (
      'debug' => false, // disables error output to screen
       // ошибки для вывода в лог
      'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_STRICT & ~E_WARNING,
      'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_COMPILE_WARNING,
      'ignore_silence' => true,
      'assertion_throws_exception' => true,
      'assertion_error_type' => 256,
      'log' => array (
          'settings' => array (
              'file' => "logs/bx_error/" . date("Y-m-d") . ".log",
			  'log_size' => 1000000, // ~ 1Mb per file
          ),
      ),
  ),
  'readonly' => true,
),

ФУНКЦИИ ОТЛАДКИ В ЯДРЕ D7

На замену функции AddMessage2Log в ядре D7 пришли новые функции:

use BitrixMainDiagDebug;
Debug::dumpToFile($_SERVER); // для случаев, когда нужен var_dump
Debug::writeToFile($_SERVER); // когда нужен print_r

Также в ядре D7 появились методы, для измерения времени. В старом ядре аналогов не было.

use BitrixMainDiagDebug;
Debug::startTimeLabel("foo");
foo();
Debug::endTimeLabel("foo");

Debug::startTimeLabel("bar");
bar();
Debug::endTimeLabel("bar");

print_r(Debug::getTimeLabels());

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

Какие именно ошибки вы хотите отслеживать?
Дебаг в файл:

Существует возможность записывать в отдельный отладочный файл все запросы к базе данных и время их выполнения, для этого необходимо инициализировать переменную $DBDebugToFile, значением «true» в файле /bitrix/php_interface/dbconn.php.
В новом ядре за это отвечают функции: BitrixMainDiagDebug::dumpToFile и BitrixMainDiagDebug::writeToFile.

Ручное добавление через addMessage2Log:

// В файле /bitrix/php_interface/dbconn.php определить константу LOG_FILENAME, в которой задать путь к лог-файлу
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/log.txt");

В дальнейшем любые массивы, тексты можно отправлять в этот файл посредством

AddMessage2Log("Произвольный текст сообщения или массив", "my_module_id(необязательно)");

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

Чтобы вы долго не искали где и что находится, привожу список путей на сервере ко всем нужным файлам.

Лог Apache

/var/log/httpd/error_log

Лог Nginx

/var/log/nginx/error.log

Лог PHP

/var/log/php/exceptions.log

Лог почты

Путь к логам почты прописан в /home/bitrix/.msmtprc. По-умолчанию после настройки почты для первого сайта логи пишутся сюда:
/home/bitrix/msmtp_default.log

bash, cron

/var/spool/mail/root
/var/spool/mail/bitrix

Лог запущенных задач в BitrixVM

/opt/webdir/temp

Обработка ошибок в Битрикс

При разработке под Битрикс можно пользоваться не только логами, установленными в конфигурации сервера, но и своими. Для этого нужно настроить обработчик ошибок в секции exception_handling в файле /bitrix/.settings.php.

'exception_handling' =>
    array (
        'value' =>
            array (
              'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE & ~E_DEPRECATED,
              'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING,
              'ignore_silence' => true,
              'assertion_throws_exception' => false,
              'assertion_error_type' => 256,
              'debug' => true,
              'log' => array (
                            'settings' => array (
                            'file' => 'bitrix/modules/error.log',
                            'log_size' => 1000000,
                            ),
            ),
    ),
),
  • handled_errors_types — типы обрабатываемых ошибок

  • exception_errors_types — типы ошибок, в случае которых системой выбрасывается исключение, и работа скрипта останавливается

  • ignore_silence — отменить действие оператора подавления ошибок (значок @ перед функцией, например @file(), документация).

  • assertion_throws_exception — выбрасывают ли утверждения (assert()) исключения.

  • assertion_error_type — тип ошибки для неверного утверждения (по умолчанию — 256 E_USER_ERROR)

  • debug — если выставить debug = true, информация об ошибке будет выведена пользователю в браузер. Если debug = false, при возникновении ошибки будет выведено стандартное сообщение от Битрикс, кроме ошибок E_ERROR | E_PARSE

if ($this->debug)
{
    error_reporting($this->handledErrorsTypes);
    @ini_set('display_errors', 'On');
    @ini_set('display_startup_errors', 'On');
    @ini_set('report_memleaks', 'On');
}
else
{
    error_reporting(E_ERROR | E_PARSE);
}

При отключении режима отладки, также сбрасываются настройки для assert()

if ($this->debug)
{
  assert_options(ASSERT_ACTIVE, 1);
  assert_options(ASSERT_WARNING, 0);
  assert_options(ASSERT_BAIL, 0);
  assert_options(ASSERT_QUIET_EVAL, 0);
  assert_options(ASSERT_CALLBACK, array($this, "handleAssertion"));
}
else
{
   assert_options(ASSERT_ACTIVE, 0);
}
  • log — секция с указанием логгера. Если пусто, то запись ошибок происходить не будет. В данном случае по умолчанию всю работу на себя возьмет объект класса BitrixMainDiagFileExceptionHandlerLog.
  • settings — секция с настройками обработчика ошибок. Можно задавать произвольные параметры. Они все передадутся массивом в метод initialize() обработчика.
  • file — относительный путь к файлу логов от корневой директории сайта (BitrixMainApplication::getDocumentRoot().’/’.$file).
  • log_size — максимальный размер файла логов в байтах.

Можно использовать собственный обработчик ошибок для записи логов. Для этого в секции log нужно указать:

'class_name' => 'MyLog',
'extension' => 'MyLogExt',
'required_file' => 'modules/mylog.module/mylog.php'
  • class_name — имя класса-обработчика. Класс должен наследоваться от BitrixMainDiagExceptionHandlerLog. Метод write в 16 версии отличается от реализации в 15 версии, эта несовместимость может сломать сайт, будьте внимательны.
  • extension — подключаемое расширение, содержащее класс-обработчик
  • required_file — файл, содержащий нужный класс.

Модули АХТУНГ 500 И АХТУНГ 500 ПРО

Модули Ахтунг 500 и Ахтунг 500 ПРО предназачены для мгновенного оповещения об ошибках по e-mail и через браузер, когда администратор находится на сайте.

Мониторинг ошибок происходит не только через обработчик ошибок Битрикса, но и через чтение файлов логов сервера, есть поиск.

Перейти к подробному описанию Ахтунг 500 ПРО

Понравилась статья? Поделить с друзьями:
  • Bitlocker ошибка во время шифрования
  • Bitlocker ошибка 0x8004259a
  • Bitlocker выдает ошибку
  • Bitlocker driver ошибка 24620
  • Bitcomet disk boost service ошибка