Как реализовать логирование входящих SOAP-запросов и ответов в 1С:Предприятии?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с внешними интеграциями через SOAP веб-сервисы часто возникает необходимость протоколировать входящие данные. Это критически важно для отладки, разбора конфликтных ситуаций с внешними системами и мониторинга производительности. Однако стандартные средства 1С не всегда предоставляют "сырой" XML-запрос напрямую в коде метода веб-сервиса. В этой статье мы разберем несколько эффективных способов логирования — от простых программных методов внутри 1С до системных настроек сервера.

Способ 1: Программная сериализация параметров в методе веб-сервиса

Рассмотрим ситуацию, когда веб-сервис уже работает, и нам нужно сохранить данные, которые пришли в параметрах метода. Основная сложность здесь заключается в том, что 1С автоматически десериализует входящий XML-пакет в объекты XDTO или примитивные типы. Чтобы сохранить их обратно в XML для лога, нам потребуется воспользоваться объектом ФабрикаXDTO.

Проанализируем решение, к которому пришел автор темы. Вместо того чтобы пытаться записать всё сообщение целиком (что затруднительно, так как 1С передает в метод уже "разобранные" параметры), мы соберем все входящие переменные в массив и последовательно запишем их в один XML-файл.

Разберем программную реализацию по шагам:

Во-первых, в самом методе веб-сервиса необходимо сформировать массив из входящих параметров и передать его в процедуру логирования:


Функция CreateDocument(DocumentSet, ID, DocumentObjects)
    
    МассивВходныхПараметров = Новый Массив;
    МассивВходныхПараметров.Добавить(DocumentSet); // Объект XDTO
    МассивВходныхПараметров.Добавить(ID);          // Примитивный тип (строка/число)
    МассивВходныхПараметров.Добавить(DocumentObjects); // Еще один объект XDTO
    
    ЗаписатьЛогВходящихДанных(МассивВходныхПараметров);
    
    // Далее идет основная логика создания документа...
    
КонецФункции

Во-вторых, создадим универсальную функцию записи. Обратите внимание, что мы должны различать объекты XDTO и простые типы данных, так как методы их записи в XML различаются.


Процедура ЗаписатьЛогВходящихДанных(ВходящиеПараметры)
    
    // Генерируем уникальное имя файла, можно добавить дату и время для удобства поиска
    ИмяФайла = "C:\Logs\SOAP_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + ".xml";
    
    ЗаписьXML = Новый ЗаписьXML; 
    ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь); 
    ЗаписьXML.ОткрытьФайл(ИмяФайла, ПараметрыЗаписиXML); 
    
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    ЗаписьXML.ЗаписатьНачалоЭлемента("SoapRequestLog");
    
    Для каждого Элемент из ВходящиеПараметры Цикл 
        
        ЗаписьXML.ЗаписатьНачалоЭлемента("Parameter");
        
        // Проверяем, является ли параметр сложным объектом XDTO
        Если ТипЗнч(Элемент) = Тип("ОбъектXDTO") Тогда
            // Используем фабрику для сериализации объекта
            ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, Элемент);
        Иначе
            // Для простых типов (строки, числа, даты) используем стандартную запись
            ЗаписатьXML(ЗаписьXML, Элемент, НазначениеТипаXML.Явное);
        КонецЕсли;
        
        ЗаписьXML.ЗаписатьКонецЭлемента(); // Parameter
        
    КонецЦикла;
    
    ЗаписьXML.ЗаписатьКонецЭлемента(); // SoapRequestLog
    ЗаписьXML.Закрыть();
    
КонецПроцедуры

Важный нюанс: этот метод логирует только те данные, которые успешно прошли валидацию XDTO. Если внешняя система пришлет некорректный XML (не соответствующий схеме), выполнение даже не дойдет до кода вашего метода — 1С вернет ошибку на уровне платформы.

Способ 2: Использование информационных регистров

Если записывать логи в текстовые файлы неудобно (например, к ним нет прямого доступа у администратора базы), рассмотрим вариант с хранением в Регистре сведений. Это позволит анализировать запросы прямо из интерфейса 1С.

Выясним преимущества и недостатки этого метода:

  1. Удобство поиска: Можно быстро найти запрос по контрагенту, дате или сумме документа.
  2. Производительность: Запись больших объемов XML в базу данных может замедлить работу. Чтобы этого избежать, используйте тип ХранилищеЗначения для тела запроса.
  3. Очистка: Необходимо настроить регламентное задание для удаления старых записей, чтобы база не разрасталась.

При записи в регистр рекомендуется использовать асинхронный подход. Вместо записи в основном потоке, можно передавать данные во временное хранилище и запускать фоновое задание, которое выполнит запись в лог, не заставляя внешнюю систему ждать ответа.

Способ 3: Настройка Технологического журнала (ТЖ)

Для системных администраторов и разработчиков, которым нужно видеть абсолютно все запросы (включая битые и неавторизованные), лучшим решением будет настройка Технологического журнала 1С. Это позволит перехватывать события на уровне платформы.

Рассмотрим пример настройки файла logcfg.xml для сбора событий веб-сервисов:


<config xmlns="http://v8.1c.ru/7.4/puls/logcfg">
  <log location="/var/log/1c/logs" history="72">
    <event>
      <eq property="Name" value="WS-SRV"/>
    </event>
    <property name="All"/>
  </log>
</config>

Событие WS-SRV фиксирует начало и окончание обработки вызова веб-сервиса. В логах будет доступна информация о времени выполнения, пользователе и возникших ошибках. Однако стоит помнить, что ТЖ создает значительную нагрузку на дисковую подсистему при интенсивном трафике.

Способ 4: Логирование на стороне веб-сервера (Apache/IIS)

Если ваша база опубликована на Apache (как в примере из обсуждения на Linux), вы можете задействовать модули самого веб-сервера. Например, модуль mod_dumpio позволяет записывать весь входящий и исходящий трафик в лог-файл Apache.

Проанализируем ситуацию: если запрос не доходит до 1С из-за ошибок сети или авторизации, только логи веб-сервера помогут понять причину. Для Apache это настраивается в файле конфигурации httpd.conf:

Предупреждение: это создаст очень объемные логи, так как в них попадет каждый байт трафика. Используйте этот метод только для временной отладки сложных проблем.

Способ 5: Архитектурный переход на HTTP-сервисы

Как справедливо заметили участники обсуждения, SOAP в 1С является довольно жестким стандартом. Если у вас есть возможность влиять на протокол взаимодействия, рассмотрим переход на HTTP-сервисы.

В чем профит для логирования?

  1. Вы получаете доступ к сырому телу запроса через Запрос.ПолучитьТелоКакСтроку() или Запрос.ПолучитьТелоКакДвоичныеДанные().
  2. Вы можете сохранить оригинальный XML (или JSON) еще до того, как начнете его парсить.
  3. Даже если формат сообщения невалиден, вы сможете залогировать факт обращения и содержимое "мусорного" запроса.

Пример получения данных в HTTP-сервисе:


Функция Post(Запрос)
    
    ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();
    // Сразу записываем строку в лог-файл или регистр
    ЗаписатьТекстЛога(ТелоЗапроса);
    
    // Только после этого начинаем чтение XML
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(ТелоЗапроса);
    // ... логика парсинга ...
    
КонецФункции

Резюме

Выбор метода зависит от ваших целей. Если нужно быстро "подсмотреть", что присылает корректно работающий клиент — используйте программную сериализацию через ФабрикуXDTO (Способ 1). Если система работает нестабильно и запросы пропадают — настраивайте Технологический журнал или логи веб-сервера. Для новых проектов наиболее гибким вариантом будет использование HTTP-сервисов вместо SOAP, что даст полный контроль над процессом получения данных.

← На главную