В процессе интеграции различных систем на базе «1С:Предприятие» часто возникает задача контроля внешних подключений. Когда одна база данных обращается к другой через COM-соединение (COMConnector), это происходит незаметно для обычных пользователей. Чтобы понимать, кто, когда и с какого узла запрашивал данные, необходимо реализовать внутреннюю систему логирования. В этой статье мы разберем, как создать собственный механизм фиксации истории подключений, используя возможности платформы.
Прежде всего, нам необходимо место, где будет храниться информация. Оптимальным объектом для этого является Регистр сведений. Проанализируем, какие данные нам могут понадобиться для полноценного мониторинга:
СправочникСсылка.Пользователи или Строка) — под кем было установлено соединение.Строка) — имя сервера или рабочей станции, инициировавшей запрос.Число) — уникальный номер сеанса в информационной базе.Строка) — для идентификации, что это именно внешнее соединение.Дата) — для отслеживания длительности работы.Рекомендуется устанавливать режим записи регистра «Независимый», чтобы иметь возможность записывать данные программно в любой момент.
Выясним, где именно нужно писать код для фиксации события. В конфигурации 1С существует специальный объект — Модуль внешнего соединения. Код в этом модуле исполняется только тогда, когда к базе подключаются через COM или Web-сервисы. Рассмотрим основные обработчики:
Для нашей задачи идеально подходит процедура ПриНачалеРаботыСистемы. Важно помнить: в этом модуле категорически запрещено использовать любые методы взаимодействия с интерфейсом (например, Предупреждение() или ОткрытьФорму()), иначе подключение завершится с ошибкой.
Разберем по шагам, как получить данные о текущем соединении и записать их в наш регистр. Нам понадобится метод ПолучитьСоединенияИнформационнойБазы() и системная функция НомерСоединенияИнформационнойБазы(). Посмотрим на пример кода, который следует разместить в модуле внешнего соединения:
Процедура ПриНачалеРаботыСистемы()
// Устанавливаем привилегированный режим, чтобы запись прошла
// даже если у COM-пользователя ограничены права на регистр
УстановитьПривилегированныйРежим(Истина);
ТекущийНомерСоединения = НомерСоединенияИнформационнойБазы();
МассивСоединений = ПолучитьСоединенияИнформационнойБазы();
ДанныеТекущегоСоединения = Неопределено;
// Ищем наше текущее соединение в списке всех активных сессий
Для Каждого Соединение Из МассивСоединений Цикл
Если Соединение.НомерСоединения = ТекущийНомерСоединения Тогда
ДанныеТекущегоСоединения = Соединение;
Прервать;
КонецЕсли;
КонецЦикла;
Если ДанныеТекущегоСоединения <> Неопределено Тогда
// Записываем данные в регистр сведений
МенеджерЗаписи = РегистрыСведений.ИсторияCOMПодключений.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.Пользователь = ДанныеТекущегоСоединения.Пользователь.Наименование;
МенеджерЗаписи.ИмяКомпьютера = ДанныеТекущегоСоединения.ИмяКомпьютера;
МенеджерЗаписи.НомерСоединения = ТекущийНомерСоединения;
МенеджерЗаписи.Приложение = ДанныеТекущегоСоединения.ИмяПриложения;
Попытка
МенеджерЗаписи.Записать();
Исключение
// В фоновом режиме ошибки записи не должны прерывать работу обмена
ЗаписьЖурналаРегистрации("Ошибка.ЛогированиеCOM", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Чтобы система была законченной, проанализируем ситуацию с завершением работы. Если мы хотим знать, как долго внешняя база «держала» соединение, мы можем использовать процедуру ПриОкончанииРаботыСистемы в том же модуле. В этом случае нам нужно будет найти созданную ранее запись в регистре по номеру соединения и обновить поле ДатаОкончания.
Однако стоит учитывать, что при аварийном разрыве связи или «падении» процесса comcntr.dll на стороне клиента, процедура ПриОкончанииРаботыСистемы может не вызваться. Поэтому поле даты окончания часто оставляют пустым, что также служит индикатором некорректного завершения сеанса.
Как справедливо отмечено в обсуждении, сам факт подключения отловить легко, но понять, к каким данным обращался COM-объект, сложнее. Если стоит задача детального аудита, рассмотрим вариант использования Подписок на события.
Например, создадим подписку на событие ПриЧтении для критически важных справочников или документов. Внутри обработчика подписки мы можем проверить тип текущего соединения:
Если НомерСоединенияИнформационнойБазы() > 0 Тогда
// Проверяем, является ли это внешним соединением
// И логируем обращение к конкретной ссылке объекта
КонецЕсли;
Внимание: такой метод крайне ресурсозатратен. Если внешняя система выгружает тысячи строк документов, постоянная запись в лог при чтении каждого объекта может замедлить обмен в несколько раз и переполнить базу данных лишними записями.
При реализации мониторинга важно помнить о технических нюансах работы через COMConnector:
Если вам не требуется сложная бизнес-логика при подключении, выясним, нельзя ли обойтись стандартными средствами. Платформа 1С автоматически записывает события Сеанс. Начало в Журнал регистрации. Вы можете настроить отбор по колонке «Приложение», выбрав значение «Внешнее соединение». Это позволит видеть историю без внесения изменений в конфигурацию и создания лишних объектов метаданных.
Мы рассмотрели процесс создания системы мониторинга COM-обменов. Основные этапы включают создание регистра сведений, написание кода в модуле внешнего соединения и использование системных функций для идентификации сессии. Несмотря на надежность этого метода, рекомендуется рассматривать переход на HTTP-сервисы, которые позволяют передавать данные более гибко, работают быстрее и легче поддаются логированию на стороне веб-сервера.