Разработка модуля логирования 1С-Битрикс
Разбор инцидента на продакшне без нормальных логов — занятие мучительное. Стандартный \Bitrix\Main\Diag\Debug::writeToFile() пишет в плоский файл без структуры, без уровней, без ротации. Через неделю работы — файл на 2 ГБ, который невозможно ни проанализировать, ни найти нужную запись. Модуль логирования решает это системно: структурированные записи в БД, уровни severity, теги, контекст, ротация, поиск через административный интерфейс.
Архитектура
Модуль vendor.logger реализует интерфейс PSR-3 (Psr\Log\LoggerInterface), что позволяет подключать его к любым библиотекам, поддерживающим PSR-3 (Guzzle, Doctrine, Symfony компоненты).
Таблицы ORM:
-
b_vendor_log_entry— записи лога: id, level (debug/info/notice/warning/error/critical/alert/emergency), channel, message, context (JSON), extra (JSON), created_at, user_id, request_uri, ip -
b_vendor_log_channel— каналы: id, code, name, min_level, handlers (JSON), is_active -
b_vendor_log_archive— архивированные записи (после ротации): аналогичная структура + archived_at
Реализация PSR-3
class BitrixLogger extends \Psr\Log\AbstractLogger
{
private string $channel;
public function __construct(string $channel = 'app')
{
$this->channel = $channel;
}
public function log($level, $message, array $context = []): void
{
if (!$this->isLevelEnabled($level)) {
return;
}
$extra = [
'user_id' => $GLOBALS['USER']?->GetID(),
'request_uri' => $_SERVER['REQUEST_URI'] ?? '',
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
];
LogEntryTable::add([
'LEVEL' => $level,
'CHANNEL' => $this->channel,
'MESSAGE' => $this->interpolate($message, $context),
'CONTEXT' => $context,
'EXTRA' => $extra,
]);
}
private function interpolate(string $message, array $context): string
{
$replace = [];
foreach ($context as $key => $val) {
$replace['{' . $key . '}'] = is_scalar($val) ? $val : json_encode($val, JSON_UNESCAPED_UNICODE);
}
return strtr($message, $replace);
}
}
Использование в коде
$logger = new \Vendor\Logger\BitrixLogger('payment');
$logger->info('Инициирован платёж', ['order_id' => 42, 'sum' => 1500.00, 'gateway' => 'sberbank']);
$logger->error('Ошибка платёжного шлюза', ['order_id' => 42, 'response' => $gatewayResponse]);
// Глобальный логгер через фасад
\Vendor\Logger\Log::channel('sync')->warning('Синхронизация с 1С: товар не найден', ['xml_id' => 'ABC-123']);
Обработчики (Handlers)
Запись в БД — не единственный обработчик. Модуль поддерживает несколько хэндлеров на один канал:
-
DatabaseHandler — запись в
b_vendor_log_entry(основной) - FileHandler — запись в файл с автоматической ротацией (ежедневно, максимум N файлов)
- SlackHandler — отправка critical/emergency в Slack-канал через Webhook
- TelegramHandler — отправка алертов в Telegram-бот при уровне >= error
Конфигурация каналов хранится в b_vendor_log_channel в поле handlers (JSON). Пример:
{
"handlers": [
{"type": "database", "min_level": "debug"},
{"type": "telegram", "min_level": "error", "chat_id": "-100123456789"}
]
}
Ротация и архивация
Агент ротации запускается раз в сутки:
// Записям старше 30 дней — перенос в b_vendor_log_archive
// Записям старше 90 дней в архиве — удаление
// Параметры настраиваются в административном интерфейсе модуля
\Vendor\Logger\RotationAgent::run();
Перенос выполняется батчами по 1000 записей, чтобы не блокировать таблицу на долгое время.
Перехват ошибок PHP
Модуль может регистрировать глобальный обработчик ошибок PHP:
set_error_handler(function($errno, $errstr, $errfile, $errline) {
$level = ErrorLevelMapper::toLogLevel($errno);
\Vendor\Logger\Log::channel('php')->log($level, $errstr, [
'file' => $errfile,
'line' => $errline,
'errno' => $errno,
]);
return false; // Стандартный обработчик Битрикс тоже срабатывает
});
set_exception_handler(function(\Throwable $e) {
\Vendor\Logger\Log::channel('php')->critical($e->getMessage(), [
'exception' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
]);
});
Административный интерфейс
Поиск по логам — основной инструмент при отладке:
- Фильтрация по уровню, каналу, дате, IP, пользователю, тексту сообщения
- Поиск по контексту (JSON-поле через PostgreSQL
@>или LIKE по serialized) - Детальный просмотр записи: полный контекст, стек вызовов, заголовки запроса
- Статистика: топ ошибок за период, динамика по уровням, разбивка по каналам
- Управление конфигурацией каналов и обработчиков
Сроки разработки
| Этап | Срок |
|---|---|
| ORM-таблицы, PSR-3 реализация | 1 день |
| DatabaseHandler, FileHandler | 1 день |
| Slack и Telegram алерты | 1 день |
| Ротация и архивация (агент) | 1 день |
| Перехват ошибок PHP | 1 день |
| Административный интерфейс, поиск | 2 дня |
| Тестирование | 1 день |
Итого: 8 рабочих дней. Интеграция с внешними системами мониторинга (Sentry, Graylog) — дополнительно 1–2 дня.







