Как организовать запись и получение лога при работе с фоновыми заданиями и обработчиком ожидания

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

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

Проблема распределенных вызовов в кластере серверов

Рассмотрим ситуацию, когда мы пытаемся записывать лог в обычный текстовый файл во временной директории сервера. На первый взгляд это кажется логичным, но здесь кроется серьезная архитектурная ловушка. Разберем по шагам, почему это может не работать.

В системе 1С:Предприятие 8.3 при работе в кластере серверов существует понятие Session Affinity (привязка сеанса). Основной сеанс пользователя обычно привязан к конкретному рабочему процессу (rphost) на конкретном сервере. Однако фоновые задания, которые вы запускаете, могут быть распределены кластером на любой другой сервер, где разрешено выполнение фоновых заданий.

Проанализируем риски: если ваша основная форма создала временный файл на Сервере №1, а фоновое задание запустилось на Сервере №2, оно физически не увидит этот файл. Попытка дозаписи приведет к ошибке или созданию нового пустого файла на другом сервере. Таким образом, использование локальных путей типа КаталогВременныхФайлов() для межоперационного обмена данными в многосерверном кластере недопустимо.

Решение: Если вы все же решили использовать файлы, необходимо использовать общую сетевую папку (UNC-путь), доступ к которой имеют учетные записи, под которыми запущены службы 1С на всех серверах кластера. Но, как мы увидим далее, есть более изящные способы.

Использование механизма СообщенияПользователю

Самый простой и быстрый способ передать информацию из фонового задания на клиента — это использование объекта СообщениеПользователю. Рассмотрим, как это работает на практике. Внутри серверного кода фонового задания мы просто выводим информацию:


// В коде фонового задания
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Обработано объектов: " + Строка(Количество);
Сообщение.Сообщить();

Теперь выясним, как получить эти данные. На стороне клиента мы подключаем обработчик ожидания, который вызывает серверную процедуру. В этой процедуре мы используем метод ПолучитьСообщенияПользователю() для объекта фонового задания.

Разберем важные нюансы этого метода:

  1. Объем памяти: Все сообщения накапливаются в оперативной памяти рабочего процесса. Если ваше задание генерирует десятки тысяч строк лога, это может привести к значительному потреблению памяти процессом rphost и замедлению передачи данных из-за сериализации огромных массивов.
  2. Потеря данных: Сообщения живут ровно столько, сколько живет объект фонового задания в памяти или пока они не будут вычитаны.

Оптимальная работа через БСП (ДлительныеОперации)

Если в вашей конфигурации используется БСП, то наиболее правильным и современным способом будет использование модуля ДлительныеОперации. Рассмотрим этот подход подробнее, так как он инкапсулирует в себе все сложности взаимодействия с фоновыми заданиями.

Для передачи прогресса и лога используем метод ДлительныеОперации.СообщитьПрогресс(). Этот метод позволяет передавать не просто текст, а структуру данных, что гораздо удобнее для парсинга на клиенте.


// Внутри фонового задания
ТекстЛога = "Запись успешно создана";
ПроцентВыполнения = 45;
СтруктураДопПараметров = Новый Структура("Важность, Сообщение", "Инфо", ТекстЛога);
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, СтруктураДопПараметров);

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

Логирование через Регистры Сведений

Рассмотрим ситуацию, когда лог очень большой или его необходимо сохранить для последующего анализа даже после завершения работы пользователя. В этом случае лучшим выбором будет использование Регистра Сведений (РС).

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

Пример записи в лог через регистр:


МенеджерЗаписи = РегистрыСведений.ЛогПроцессов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторЗапуска = ПараметрыЗапуска.ID;
МенеджерЗаписи.Период = ТекущаяДатаСеанса();
МенеджерЗаписи.ТекстСообщения = "Шаг 1 завершен";
МенеджерЗаписи.Записать(Истина);

Использование Временного хранилища

Еще один способ — использование Временного хранилища. Вы можете передать в фоновое задание АдресХранилища, в который оно будет помещать результаты своей работы. Но помните важную особенность: данные, помещенные во временное хранилище из фонового задания, становятся доступны основному сеансу только после того, как задание полностью завершится, либо если используются специальные механизмы передачи идентификаторов, что усложняет реализацию.

Выводы и рекомендации

Подведем итог нашему анализу и выберем оптимальную стратегию:

  1. Для быстрого отображения прогресса и коротких текстовых уведомлений лучше всего подходит связка ДлительныеОперации.СообщитьПрогресс() и клиентский обработчик ожидания.
  2. Для отладочных логов, которые не нужно показывать пользователю, используйте ЗаписьЖурналаРегистрации(). Помните, что чтение из Журнала регистрации в реальном времени — очень тяжелая операция.
  3. Для хранения истории выполнения и больших протоколов используйте независимый Регистр Сведений с уникальным ключом для каждого потока, чтобы избежать взаимоблокировок.
  4. Избегайте файлов в многосерверных кластерах, если не обеспечена общая сетевая доступность ресурсов.

Используя эти подходы, вы сможете создать надежную и производительную систему мониторинга длительных операций в ваших решениях на платформе 1С.

← На главную