При работе с внешними интеграциями через SOAP веб-сервисы часто возникает необходимость протоколировать входящие данные. Это критически важно для отладки, разбора конфликтных ситуаций с внешними системами и мониторинга производительности. Однако стандартные средства 1С не всегда предоставляют "сырой" XML-запрос напрямую в коде метода веб-сервиса. В этой статье мы разберем несколько эффективных способов логирования — от простых программных методов внутри 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С вернет ошибку на уровне платформы.
Если записывать логи в текстовые файлы неудобно (например, к ним нет прямого доступа у администратора базы), рассмотрим вариант с хранением в Регистре сведений. Это позволит анализировать запросы прямо из интерфейса 1С.
Выясним преимущества и недостатки этого метода:
ХранилищеЗначения для тела запроса.При записи в регистр рекомендуется использовать асинхронный подход. Вместо записи в основном потоке, можно передавать данные во временное хранилище и запускать фоновое задание, которое выполнит запись в лог, не заставляя внешнюю систему ждать ответа.
Для системных администраторов и разработчиков, которым нужно видеть абсолютно все запросы (включая битые и неавторизованные), лучшим решением будет настройка Технологического журнала 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 фиксирует начало и окончание обработки вызова веб-сервиса. В логах будет доступна информация о времени выполнения, пользователе и возникших ошибках. Однако стоит помнить, что ТЖ создает значительную нагрузку на дисковую подсистему при интенсивном трафике.
Если ваша база опубликована на Apache (как в примере из обсуждения на Linux), вы можете задействовать модули самого веб-сервера. Например, модуль mod_dumpio позволяет записывать весь входящий и исходящий трафик в лог-файл Apache.
Проанализируем ситуацию: если запрос не доходит до 1С из-за ошибок сети или авторизации, только логи веб-сервера помогут понять причину. Для Apache это настраивается в файле конфигурации httpd.conf:
DumpIOInput On и DumpIOOutput On.LogLevel dumpio:trace7.Предупреждение: это создаст очень объемные логи, так как в них попадет каждый байт трафика. Используйте этот метод только для временной отладки сложных проблем.
Как справедливо заметили участники обсуждения, SOAP в 1С является довольно жестким стандартом. Если у вас есть возможность влиять на протокол взаимодействия, рассмотрим переход на HTTP-сервисы.
В чем профит для логирования?
Запрос.ПолучитьТелоКакСтроку() или Запрос.ПолучитьТелоКакДвоичныеДанные().Пример получения данных в HTTP-сервисе:
Функция Post(Запрос)
ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();
// Сразу записываем строку в лог-файл или регистр
ЗаписатьТекстЛога(ТелоЗапроса);
// Только после этого начинаем чтение XML
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТелоЗапроса);
// ... логика парсинга ...
КонецФункции
Выбор метода зависит от ваших целей. Если нужно быстро "подсмотреть", что присылает корректно работающий клиент — используйте программную сериализацию через ФабрикуXDTO (Способ 1). Если система работает нестабильно и запросы пропадают — настраивайте Технологический журнал или логи веб-сервера. Для новых проектов наиболее гибким вариантом будет использование HTTP-сервисов вместо SOAP, что даст полный контроль над процессом получения данных.