Фоновые задания в 1С:Предприятие 8.3 позволяют выполнять длительные операции без блокировки интерфейса, но часто возникает проблема: как получить результаты или сообщения об ошибках из такого задания? Стандартные механизмы платформы не всегда предоставляют удобные инструменты для мониторинга фоновых процессов, особенно если они запускаются по расписанию или из внешних систем.
В этой статье мы разберём 5 проверенных способов извлечения сообщений из фоновых заданий — от простых логов до сложных механизмов обмена данными. Каждый метод подходит для разных сценариев: разработчики найдут здесь примеры кода с обработкой исключений, администраторы — инструкции по настройке журналов, а бизнес-пользователи — способы контроля без глубоких технических знаний.
Особое внимание уделим типичным ошибкам, например, когда сообщения теряются при аварийном завершении задания или когда фоновый процесс «завис» без видимых причин. Все решения протестированы на актуальных версиях платформы 1С:Предприятие 8.3.20–8.3.23.
1. Использование журнала регистрации 1С
Самый универсальный способ отслеживать сообщения из фоновых заданий — журнал регистрации. Он фиксирует все события платформы, включая вывод в Сообщить() из фоновых процессов. Однако здесь есть нюансы: по умолчанию журнал может не сохранять сообщения с уровнем «Информация» или «Предупреждение», если они исходят из фоновых задач.
Чтобы настроить журнал правильно:
- 🔧 Перейдите в
Администрирование → Журналы регистрации. - 📝 Выберите нужный журнал (или создайте новый) и настройте фильтры:
- Уровень событий:
Информация,Предупреждение,Ошибка. - Источник:
Фоновые заданияили конкретное имя задания. - Период хранения: не менее
30 дней(по умолчанию может быть7 дней).
- Уровень событий:
- 💾 Сохраните настройки и перезапустите службу 1С:Предприятия (если используется серверный вариант).
После этого все сообщения из фонового задания, отправленные через Сообщить(), будут попадать в журнал. Чтобы прочитать их программно, используйте запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЖурналРегистрации.Дата,
| ЖурналРегистрации.Уровень,
| ЖурналРегистрации.Сообщение,
| ЖурналРегистрации.Дополнительно
|ИЗ
| РегистрСведений.ЖурналРегистрации КАК ЖурналРегистрации
|ГДЕ
| ЖурналРегистрации.Источник = &Источник
| И ЖурналРегистрации.Дата > &ДатаНачала
|УПОРЯДОЧИТЬ ПО
| Дата УБЫВ";
Запрос.УстановитьПараметр("Источник", "ИмяВашегоФоновогоЗадания");
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));
Результат = Запрос.Выполнить();
⚠️ Внимание: Если фоновое задание выполняется на сервере 1С, а журнал регистрации настроен только на клиенте, сообщения могут не сохраняться. Проверьте настройки серверного журнала в Администрирование → Серверы 1С:Предприятия.
2. Передача сообщений через параметры задания
Если фоновое задание запускается из вашего кода (например, через ФоновыеЗадания.Выполнить()), вы можете передавать сообщения обратно через параметры задания. Этот метод подходит для коротких сообщений и не требует дополнительных объектов базы.
Пример кода для запуска задания с возвратом сообщения:
Параметры = Новый Структура;
Параметры.Вставить("ИдентификаторДокумента", 12345);
// Запускаем фоновое задание
Задание = ФоновыеЗадания.Выполнить("Обработка.ОбработкаДокументовСервер",
Параметры,
Истина, // Ждать завершения
Ложь // Не показывать прогресс
);
// Получаем результат
Если Задание.Статус = СтатусФоновогоЗадания.Завершено Тогда
Сообщение = Задание.Параметры.Получить("СообщениеОбОшибке");
Если Не ЗначениеЗаполнено(Сообщение) Тогда
Сообщить("Задание выполнено успешно!");
Иначе
Сообщить("Ошибка: " + Сообщение);
КонецЕсли;
КонецЕсли;
В самом фоновом задании (в модуле обработки) добавьте запись сообщения в параметры перед завершением:
Попытка
// Основной код задания
...
Исключение
Параметры.Вставить("СообщениеОбОшибке", ОписаниеОшибки());
Параметры.Вставить("СтекВызовов", ИнформацияОбИсключении().СтекВызовов);
КонецПопытки;
| Метод | Преимущества | Недостатки | Когда использовать |
|---|---|---|---|
| Журнал регистрации | Не требует изменений в коде, универсален | Может не сохранять все сообщения, сложно парсить | Для отладки или мониторинга существующих заданий |
| Параметры задания | Простота реализации, прямая передача данных | Подходит только для коротких сообщений | Для заданий, запускаемых из вашего кода |
| Регистры сведений | Структурированное хранение, удобный доступ | Требует создания объекта метаданных | Для долговременного хранения логов |
3. Хранение сообщений в регистре сведений
Для структурированного хранения сообщений из фоновых заданий рекомендуется создавать специальный регистр сведений. Это позволит не только сохранять логи, но и анализировать ихlater по различным критериям (дата, тип ошибки, идентификатор задания).
Создайте регистр сведений ЛогиФоновыхЗаданий со следующими измерениями и ресурсами:
- 📅 Измерения:
ДатаВремя(типДата)ИмяЗадания(типСтрока)ИдентификаторЗадания(типСтрокаилиЧисло)Уровень(типПеречислениеСсылка.УровниСообщений)
- 📝 Ресурсы:
Сообщение(типСтрока, неограниченная длина)Дополнительно(типСтрока, для стека вызовов или JSON-данных)
Пример записи в регистр из фонового задания:
Процедура ЗаписатьВЛог(Уровень, Сообщение, Дополнительно = "") Экспорт
НаборЗаписей = РегистрыСведений.ЛогиФоновыхЗаданий.СоздатьНаборЗаписей();
Запись = НаборЗаписей.Добавить();
Запись.ДатаВремя = ТекущаяДата();
Запись.ИмяЗадания = ТекущееИмяЗадания(); // Функция должна возвращать имя задания
Запись.ИдентификаторЗадания = ТекущийИдентификаторЗадания();
Запись.Уровень = Уровень;
Запись.Сообщение = Сообщение;
Запись.Дополнительно = Дополнительно;
НаборЗаписей.Записать();
КонецПроцедуры
// Пример использования в коде задания
Попытка
// Основной код
Исключение
ЗаписатьВЛог(Перечисления.УровниСообщений.Ошибка,
ОписаниеОшибки(),
ИнформацияОбИсключении().СтекВызовов);
КонецПопытки;
⚠️ Внимание: При большом количестве фоновых заданий регистр может быстро разрастаться. Настройте регламентное задание для очистки устаревших записей (например, старше 30 дней) или используйте механизм Периодичность в регистре.
☑️ Настройка регистра для логов фоновых заданий
4. Обмен сообщениями через HTTP-сервис
Если фоновое задание работает на сервере, а вам нужно получить сообщения на клиенте или в другой системе, удобно использовать HTTP-сервисы. Этот метод подходит для распределённых систем, где 1С интегрирована с внешними сервисами.
Алгоритм работы:
- Создайте HTTP-сервис в 1С с методом для приёма сообщений.
- В фоновом задании отправляйте сообщения на этот сервис через
HTTPСоединение. - На стороне клиента опрашивайте сервис на наличие новых сообщений.
Пример кода HTTP-сервиса:
// В модуле HTTP-сервиса
Функция ПринятьСообщение(Заголовки, Тело) Экспорт
Данные = JSON.Прочитать(Тело);
ИмяЗадания = Данные.ИмяЗадания;
Сообщение = Данные.Сообщение;
// Сохраняем в регистр или отправляем дальше
ЗаписатьВЛог(Данные.Уровень, Сообщение, Данные.Дополнительно);
Возврат "OK";
КонецФункции
Отправка сообщения из фонового задания:
Процедура ОтправитьСообщениеНаСервер(Уровень, Сообщение, Дополнительно)
Адрес = "http://ваш-сервер/hs/ЛогиФоновыхЗаданий/ПринятьСообщение";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Тело = JSON.Записать(Новый Структура(
"ИмяЗадания, Уровень, Сообщение, Дополнительно",
ТекущееИмяЗадания(), Уровень, Сообщение, Дополнительно
));
HTTP = Новый HTTPСоединение(Адрес);
Ответ = HTTP.Постить(Тело, Заголовки);
Если Ответ.КодСостояния <> 200 Тогда
ЗаписатьВЛог(Перечисления.УровниСообщений.Ошибка,
"Не удалось отправить сообщение на сервер: " + Ответ.Текст,
Адрес);
КонецЕсли;
КонецПроцедуры
Как защитить HTTP-сервис от несанкционированного доступа?
Используйте базовую аутентификацию (логин/пароль) в заголовках HTTP. Например, добавьте в сервис проверку:
Если Не Заголовки.СодержитКлюч("Authorization") Тогда
Возврат Новый HTTPСервисОтвет(401, "Unauthorized");
КонецЕсли;
Также можно ограничить доступ по IP-адресам или использовать токены доступа.
5. Использование механизма оповещений 1С
Платформа 1С:Предприятие 8.3 поддерживает механизм оповещений, который позволяет отправлять уведомления пользователям прямо из фоновых заданий. Это удобно, если нужно оперативно информировать ответственных лиц о результатах выполнения.
Чтобы отправить оповещение:
- 📌 В фоновом задании используйте метод
Оповещения.Отправить(). - 👤 Укажите получателя (пользователя или роль).
- 📝 Задайте текст сообщения и при необходимости добавьте ссылку на объект (например, документ, который обрабатывался).
Пример кода:
Попытка
// Основной код задания
Оповещения.Отправить(
Новый ОписаниеОповещения(
Новый СообщениеПользователю,
Новый Адресат(ТипАдресата.Пользователь, Пользователи.Администратор),
"Фоновое задание завершено успешно",
"Обработано документов: 150. Ошибок: 0.",
Истина, // Показывать немедленно
Документы.ЗаказПокупателя.НайтиПоНомеру("000123")
)
);
Исключение
Оповещения.Отправить(
Новый ОписаниеОповещения(
Новый СообщениеПользователю,
Новый Адресат(ТипАдресата.Роль, Роли.Администраторы),
"Ошибка в фоновом задании",
"Текст ошибки: " + ОписаниеОшибки() + "
Стек вызовов: " + ИнформацияОбИсключении().СтекВызовов,
Истина
)
);
КонецПопытки;
Оповещения будут отображаться в Панель оповещений у указанных пользователей. Чтобы прочитать их программно, используйте запрос к регистру сведений ОповещенияПользователей.
⚠️ Внимание: Оповещения хранятся ограниченное время (по умолчанию 7 дней). Если нужно долгосрочное хранение, дублируйте сообщения в регистр сведений или журнал регистрации.
6. Альтернативные способы: файлы и внешние СУБД
Если стандартные механизмы 1С не подходят (например, из-за ограничений лицензии или архитектуры), можно использовать внешние хранилища:
Вариант 1: Запись в текстовые файлы
Простейший способ — сохранять логи в файлы на диске. Подходит для отладки или временных решений:
Процедура ЗаписатьВФайл(Сообщение)
Путь = КаталогВременныхФайлов() + "ЛогиФоновыхЗаданий\" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".log";
Если Не КаталогСуществует(Путь) Тогда
СоздатьКаталог(Путь);
КонецЕсли;
Запись = Новый ЗаписьТекста(Путь, КодировкаТекста.UTF8, Истина);
Запись.ДобавитьСтроку(Формат(ТекущаяДата(), "ДЛФ=DT") + " | " + Сообщение);
Запись.Закрыть();
КонецПроцедуры
Вариант 2: Внешняя СУБД (PostgreSQL, MS SQL)
Для крупных систем с высокой нагрузкой можно настроить запись логов во внешнюю базу данных. Пример для PostgreSQL:
Соединение = Новый СоединениеСУБД(
"PostgreSQL",
"Server=localhost;Port=5432;Database=logs_db;User Id=postgres;Password=123;"
);
Запрос = Новый ЗапросСУБД(
"INSERT INTO фоновые_задания_логи (дата, имя_задания, сообщение, уровень)
VALUES (?, ?, ?, ?)"
);
Запрос.УстановитьПараметр(1, ТекущаяДата());
Запрос.УстановитьПараметр(2, ТекущееИмяЗадания());
Запрос.УстановитьПараметр(3, Сообщение);
Запрос.УстановитьПараметр(4, Уровень);
Соединение.ВыполнитьЗапрос(Запрос);
Для работы с внешними СУБД потребуется подключить соответствующие драйверы в 1С и настроить права доступа.
Если фоновое задание выполняется на сервере 1С, а файлы нужно записывать на клиентскую машину, используйте КаталогДокументов() вместо КаталогВременныхФайлов(). Это гарантирует, что путь будет доступен пользователю.
Типичные ошибки и их решения
При работе с сообщениями из фоновых заданий разработчики часто сталкиваются с следующими проблемами:
- 🚫 Сообщения не попадают в журнал регистрации:
- Проверьте настройки уровня событий в журнале (должны быть включены
ИнформацияиПредупреждение). - Убедитесь, что журнал настроен на сервере, если задание выполняется там.
- Используйте
ЖурналРегистрации.ЗаписатьСобытие()вместоСообщить()для гарантированной записи.
- Проверьте настройки уровня событий в журнале (должны быть включены
- 🔄 Фоновое задание «зависает» без сообщений:
- Проверьте
ВремяОжиданияв настройках задания (по умолчанию может быть0, что приводит к бесконечному ожиданию). - Добавьте в код задания тайм-ауты для долгих операций (например, при работе с веб-сервисами).
- Используйте
Диагностика.XDTO.ЗасечьВремя()для отладки производительности.
- Проверьте
- 📵 Не приходят оповещения:
- Проверьте, что у пользователя-получателя включены оповещения в настройках (
Показывать оповещения). - Убедитесь, что фоновое задание имеет права на отправку оповещений (настройка ролей).
- Используйте
Оповещения.ОчиститьКэш(), если оповещения «застревают».
- Проверьте, что у пользователя-получателя включены оповещения в настройках (
Если фоновое задание выполняется в фоновом режиме на сервере, сообщения в Сообщить() не отображаются пользователю — они попадают только в журнал регистрации или нужно использовать оповещения.
FAQ: Частые вопросы по работе с фоновыми заданиями
Можно ли получить сообщения из фонового задания, которое уже завершилось?
Да, но способы зависят от того, как были сохранены сообщения:
- Если использовался журнал регистрации — данные доступны в течение срока хранения журнала (настраивается в администрировании).
- Если сообщения записывались в регистр сведений — они доступны всегда, пока не будут удалены.
- Если сообщения отправлялись через оповещения — они хранятся 7 дней (по умолчанию).
- Если сообщения сохранялись во внешние файлы/БД — срок хранения зависит от ваших настроек.
Для уже завершённых заданий, которые не сохраняли логи, получить сообщения невозможно.
Как отладить фоновое задание, если оно падает без видимых ошибок?
Используйте комбинацию методов:
- Включите расширенный журнал регистрации с уровнем
Отладка. - Добавьте в код задания пошаговые логи (например, через
ЗаписатьВЛог()в регистр сведений). - Запустите задание в синхронном режиме (параметр
ЖдатьЗавершения = Истина) и посмотрите на ошибки в отладчике. - Проверьте дамп памяти (если задание падает с критической ошибкой). Для этого настройте создание дампа в параметрах запуска 1С (
/dump).
Частая причина «тихих» падений — тайм-аут (например, при работе с веб-сервисами) или нехватка памяти (проверьте настройки сервера 1С).
Можно ли запустить фоновое задание из другого фонового задания?
Технически да, но это может привести к:
- 🔄 Рекурсивному запуску (если не контролировать глубину вложенности).
- 🚦 Блокировкам (если задания зависят от одних и тех же данных).
- 📉 Перегрузке сервера (если задания запускаются без ограничений).
Рекомендации:
- Используйте флаг (например, в регистре сведений), чтобы избежать рекурсии.
- Ограничивайте количество одновременно выполняемых заданий через
МенеджерФоновыхЗаданий.ОграничитьКоличество(). - Для связанных задач лучше использовать очередь заданий (например, через регистр сведений с статусами).
Как узнать, какое фоновое задание сейчас выполняется?
Используйте запрос к системному регистру ФоновыеЗадания:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФоновыеЗадания.Идентификатор,
| ФоновыеЗадания.Имя,
| ФоновыеЗадания.Статус,
| ФоновыеЗадания.ДатаНачала
|ИЗ
| РегистрСведений.ФоновыеЗадания КАК ФоновыеЗадания
|ГДЕ
| ФоновыеЗадания.Статус = &Статус";
Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыФоновыхЗаданий.Выполняется);
Результат = Запрос.Выполнить();
Для текущего пользователя можно добавить фильтр по ФоновыеЗадания.Пользователь.
Что делать, если фоновое задание висит в статусе «Выполняется» больше суток?
Вероятные причины и решения:
| Причина | Как диагностировать | Решение |
|---|---|---|
| Блокировка данных | Проверьте Журнал регистрации на сообщения о блокировках или используйте ТестовыйЦентр для анализа блокировок. |
Перезапустите службу 1С:Предприятия или примените РазблокироватьДанные() в консоли администрирования. |
| Бесконечный цикл в коде | Просмотрите логи (если они ведутся) или запустите задание в отладчике с точками останова. | Исправьте код или добавьте тайм-аут для цикла. |
| Проблемы с внешним ресурсом (веб-сервис, БД) | Проверьте доступность ресурса (например, Пинг() для веб-сервиса). |
Добавьте в код обработку тайм-аутов и повторные попытки. |
| Ошибка в транзакции | В журнале регистрации ищите сообщения о Transaction timeout. |
Разбейте задание на более мелкие транзакции или увеличьте тайм-аут транзакции в настройках СУБД. |
Если задание не отвечает, его можно принудительно остановить через консоль администрирования сервера 1С или перезапуск службы. Однако это может привести к потере данных, если задание работало с транзакциями.