По умолчанию логирование ошибок в Битрикс отключено, она полагается на внутренний механизм логирования PHP. Без дополнительного написания кода можно включить запись в файл, так как в Битрикс уже есть класс для записи в файл FileExceptionHandlerLog
. Для записи в БД нужно наследовать класс ExceptionHandlerLog.
Я следовал инструкции https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&CHAPTER_ID=02795&LESSON_PATH=3913.3516.5062.2795#exception_handling и вот что у меня получилось:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?php use Bitrix\Main\Diag\ExceptionHandlerFormatter; use Bitrix\Main\Diag\ExceptionHandlerLog; /** * @see \Bitrix\Main\Application::createExceptionHandlerLog */ class ErrorLogging extends ExceptionHandlerLog { private string $table_name = 'error_log_'; private $level; private \Bitrix\Main\Diag\FileExceptionHandlerLog $file_logger; private \Bitrix\Main\DB\MysqliConnection|\Bitrix\Main\DB\Connection $connection; private array $dont_show; /** * @param \Throwable $exception * @param int $logType */ public function write($exception, $logType) { if (in_array($logType, $this->dont_show)) { return; } $log_type = $this::logTypeToString($logType); $text = ExceptionHandlerFormatter::format($exception, false, $this->level); try { $this->connection->add($this->getTableName(), ['message' => $exception->getMessage(), 'stack_trace' => $text, 'error_level' => $log_type, 'context' => json_encode(['uri' => $_SERVER['REQUEST_URI']])]); } catch (\Bitrix\Main\DB\SqlException $e) { $this->file_logger->write($exception, $logType); $this->file_logger->write($e, $logType); } } public function initialize(array $options) { try { $this->connection = \Bitrix\Main\Application::getConnection('log_db'); $t = $this->getTableName(); $exist = $this->connection->isTableExists($t); if (!$exist) { $this->createTable(); } $this->level = $options['level'] ?? 0; $this->dont_show = $options['dont_show'] ?? []; } finally { $this->file_logger = new \Bitrix\Main\Diag\FileExceptionHandlerLog(); $this->file_logger->initialize($options); } } public function getTableName(): string { return ($this->table_name . date('Y_m_01')); } protected function createTable() { $table_name = $this->getTableName(); $sql = "CREATE TABLE `{$table_name}` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `error_level` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'utf8mb4_unicode_ci', `message` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', `stack_trace` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', `context` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`id`) USING BTREE ) COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB ;"; $this->connection->queryExecute($sql); } } |
Раздел .settings должен быть таким:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
'connections' => array ( 'value' => array ( 'default' => array ( 'className' => '\\Bitrix\\Main\\DB\\MysqliConnection', 'host' => 'localhost', 'database' => 'bitrix_local', 'login' => 'root', 'password' => '', 'options' => 2.0, ), // База данных для логов отдельная всегда 'log_db' => [ 'className' => '\\Bitrix\\Main\\DB\\MysqliConnection', 'host' => 'localhost', 'database' => 'bitrix_log', 'login' => 'root', 'password' => '', 'options' => 2.0 ], ), 'readonly' => true, ), |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
'exception_handling' => array ( 'value' => array ( 'debug' => false, 'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_DEPRECATED, 'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_DEPRECATED, 'ignore_silence' => true, 'assertion_throws_exception' => false, 'assertion_error_type' => 256, 'log' => [ 'class_name' => 'ErrorLogging', // Название своего класса // Система ищет или в папке bitrix, или в local, то есть система сама подставит перед apps/... 'required_file' => 'apps/logger/logger.php', // Если БД недоступна, то хотя бы запишет в файл 'settings' => [ 'file' => 'local/log/bitrix.log', 'log_size' => 1000000, // Битрикс по умолчанию генерирует уйму, просто кучу исторических ошибок. Чтобы не забить, игнориуем один из типов 'dont_show' => [\Bitrix\Main\Diag\ExceptionHandlerLog::LOW_PRIORITY_ERROR] ], ], ), 'readonly' => false, ), |
Логика класса
- Создание экземпляра класса
- Создание таблицы, если ее не существует. Каждый месяц будет создаваться новая таблица
- Записать ошибку
- Если не удалось записать или нет соединение с БД, записать в файл, чтобы не потерят логи
- Все