При выполнении тяжелых и длительных обработок в 1С (например, при загрузке больших объемов данных из внешних источников, синхронизации баз или формировании сложных аналитических отчетов) пользователи и администраторы часто сталкиваются с необходимостью отслеживать прогресс выполнения в реальном времени. Стандартный интерфейс 1С не всегда удобен для внешнего мониторинга, особенно если процессы запускаются в фоне под служебными учетными записями.
В этой статье мы подробно разберем, как организовать удобный веб-мониторинг длительных операций. Мы проанализируем технические проблемы, с которыми столкнулся автор темы, выясним причины возникновения ошибок HTTP 404 Not Found на IIS и разберем, почему ломается PHP-код, выводя на экран странные символы. Также мы рассмотрим альтернативные современные архитектурные подходы: от использования внешних баз данных до создания собственных легковесных HTTP-сервисов в 1С.
---
Рассмотрим классическую ситуацию, описанную автором: в процедуру загрузки данных встроен код, который записывает лог в HTML-файл и сохраняет его в подкаталог публикации базы данных 1С на IIS (например, /db/reports/dataupload.html). При попытке открыть этот адрес в браузере сервер возвращает ошибку HTTP: Not found (Ошибка 404).
Выясним причину этой проблемы:
Когда мы публикуем информационную базу 1С на веб-сервере IIS, платформа создает конфигурационный файл web.config в корневом каталоге публикации (например, в папке /db). В этом файле прописывается сопоставление обработчиков (Handler Mappings). По умолчанию IIS настраивается так, что абсолютно все запросы, приходящие по адресу server.ru/db/*, перехватываются и передаются модулю расширения веб-сервера 1С — библиотеке wsisapi.dll.
Когда вы отправляете запрос к статическому файлу /db/reports/proc.html, IIS не пытается прочитать его с диска стандартными средствами. Вместо этого он передает запрос платформе 1С. Так как платформа ничего не знает о существовании физического файла proc.html внутри своей структуры метаданных, она честно возвращает ошибку 404.
Как решить проблему с разграничением прав на IIS:
Самое простое и безопасное решение — создать отдельный виртуальный каталог в IIS, который будет находиться на уровне корня сайта, а не внутри приложения 1С. Например, настройте путь server.ru/reports/proc.html. В этом случае запросы к отчетам будут обрабатываться стандартным модулем IIS StaticFileModule, минуя библиотеку 1С.
Если вам жизненно важно, чтобы папка с отчетами находилась именно внутри структуры каталога публикации 1С, вам придется явно запретить IIS передавать запросы из этой папки в платформу. Для этого в физической папке /reports на диске создайте текстовый файл с именем web.config и следующим содержимым:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<clear />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
</configuration>
Этот конфигурационный файл очистит (<clear />) все унаследованные от родительского каталога правила (включая обработчик 1С) и заново назначит стандартную обработку статических файлов для текущей папки.
Убедитесь, что файлы отчетов не имеют атрибута «Скрытый» в операционной системе Windows. По умолчанию IIS блокирует доступ к скрытым файлам, возвращая ошибку 404.8 или 404.9. Также проверьте, что расширение файла (например, .json или .log) зарегистрировано в модуле «Типы MIME» в настройках IIS.
---
В процессе обсуждения автор попытался переключиться на использование внешней базы данных MySQL и вывода информации через PHP-скрипт. Однако при выполнении кода он получил на веб-странице странную строку:
0){ echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo "";
Проанализируем ситуацию и выясним, почему это произошло:
Данный симптом однозначно указывает на то, что на веб-сервере IIS не настроен обработчик PHP (FastCGI), либо файл скрипта был сохранен с расширением .html вместо .php.
Когда веб-сервер не знает, как обрабатывать файлы PHP, он просто отдает их содержимое в браузер пользователя как обычный статический текст. Браузер получает исходный код и пытается интерпретировать его как HTML-разметку. Встретив открывающий тег <?php, браузер воспринимает его как неизвестный HTML-тег. Он начинает искать закрывающий символ > и находит его в строке сравнения PHP:
if (mysqli_num_rows($result) > 0)
Символ «больше» (>) закрывает виртуальный тег в глазах браузера. Все, что находилось внутри конструкции <?php ... mysqli_num_rows($result) >, браузер скрывает от пользователя (считая это свойствами тега), а весь последующий PHP-код, начиная с 0){ echo ..., выводит на экран как обычный текст.
Как правильно настроить обработку PHP на IIS:
*.phpFastCgiModulephp-cgi.exePHP_via_FastCGI.php будут корректно исполняться на стороне сервера.---
Давайте подробно рассмотрим четыре варианта реализации мониторинга: от простых файловых до профессиональных современных решений.
Это классический подход, позволяющий полностью изолировать систему логирования от основной базы данных 1С. Вся информация записывается во внешнюю БД, а веб-интерфейс отображает её независимо от того, работает ли в данный момент 1С или нет.
Для реализации этого подхода выполните следующие шаги:
Шаг 1. Настройка записи из 1С во внешнюю базу данных.
Для подключения к MySQL из 1С можно использовать ADO-соединение. Рассмотрим пример записи статуса выполнения операции:
&НаСервере
Процедура ЗаписатьСтатусВВнешнююБД(ИмяПроцесса, Статус, Прогресс)
Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Database=reports;User=root;Password=your_password;Option=3;";
Попытка
Соединение.Open(СтрокаПодключения);
Исключение
ЗаписьЖурналаРегистрации("ВнешнийМониторинг", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
Возврат;
КонецПопытки;
// Записываем или обновляем информацию о процессе
ТекстЗапроса = "INSERT INTO procinfo (process_name, status, progress, updated_at) " +
"VALUES ('" + ИмяПроцесса + "', '" + Статус + "', " + Прогресс + ", NOW()) " +
"ON DUPLICATE KEY UPDATE status='" + Статус + "', progress=" + Прогресс + ", updated_at=NOW()";
Соединение.Execute(ТекстЗапроса);
Соединение.Close();
КонецПроцедуры
Шаг 2. Разработка веб-страницы на PHP.
Создадим исправленный и безопасный скрипт index.php для вывода логов на веб-страницу:
<?php
define('DB_SERVER', '127.0.0.1');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'your_password');
define('DB_NAME', 'reports');
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($link === false) {
die("Ошибка подключения к БД: " . mysqli_connect_error());
}
$sql = "SELECT process_name, status, progress, updated_at FROM procinfo ORDER BY updated_at DESC";
if ($result = mysqli_query($link, $sql)) {
if (mysqli_num_rows($result) > 0) {
echo "<table border='1' style='width:100%; border-collapse: collapse; text-align: left;'>";
echo "<tr style='background-color: #f2f2f2;'><th>Процесс</th><th>Статус</th><th>Прогресс</th><th>Последнее обновление</th></tr>";
while ($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . htmlspecialchars($row['process_name']) . "</td>";
echo "<td>" . htmlspecialchars($row['status']) . "</td>";
echo "<td>" . (int)$row['progress'] . "%</td>";
echo "<td>" . htmlspecialchars($row['updated_at']) . "</td>";
echo "</tr>";
}
echo "</table>";
mysqli_free_result($result);
} else {
echo "<p>Активных процессов не найдено.</p>";
}
} else {
echo "Ошибка запроса: " . mysqli_error($link);
}
mysqli_close($link);
?>
Для быстрого администрирования баз данных (особенно если вы используете SQLite) вы можете использовать готовые инструменты с веб-интерфейсом, такие как phpLiteAdmin или универсальный Adminer.
---
Зачем использовать внешние базы данных и настраивать веб-серверы для PHP, если сама платформа 1С умеет отдавать веб-страницы или JSON-данные «из коробки»? Разработка собственного HTTP-сервиса — самый современный и быстрый способ решения задачи в рамках экосистемы 1С.
Преимущества:
Давайте разберем по шагам, как настроить HTTP-сервис:
Мониторинг.monitoring.СтатусЗадачи и шаблоном /status/{ID}.GET и привяжите к нему функцию в модуле HTTP-сервиса.Пример кода для обработки GET-запроса и возврата JSON со статусом операции:
Функция ПолучитьСтатусВыгрузки(Запрос)
ИдентификаторЗадачи = Запрос.ПараметрыПути.Получить("ID");
// Выполняем запрос к регистру сведений, куда наши фоновые процессы пишут логи
ЗапросБД = Новый Запрос;
ЗапросБД.Текст =
"ВЫБРАТЬ
| ЛогДлительныхОпераций.Статус КАК Статус,
| ЛогДлительныхОпераций.ПроцентВыполнения КАК Прогресс,
| ЛогДлительныхОпераций.ТекстОшибки КАК ТекстОшибки
|ИЗ
| РегистрСведений.ЛогДлительныхОпераций КАК ЛогДлительныхОпераций
|ГДЕ
| ЛогДлительныхОпераций.Идентификатор = &Идентификатор";
ЗапросБД.УстановитьПараметр("Идентификатор", ИдентификаторЗадачи);
РезультатЗапроса = ЗапросБД.Выполнить();
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Если РезультатЗапроса.Пустой() Тогда
СтруктураОтвета = Новый Структура("success, error", Ложь, "Задача не найдена");
Иначе
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
СтруктураОтвета = Новый Структура;
СтруктураОтвета.Вставить("success", Истина);
СтруктураОтвета.Вставить("status", Выборка.Статус);
StructureОтвета.Вставить("progress", Выборка.Прогресс);
СтруктураОтвета.Вставить("error_text", Выборка.ТекстОшибки);
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
Возврат Ответ;
КонецФункции
Теперь любой внешний веб-интерфейс (или даже простой скрипт на фронтенде) может делать GET-запросы по адресу https://server.ru/db/hs/monitoring/status/ИД_ЗАДАЧИ и отображать пользователю красивый прогресс-бар.
---
Если ваша конфигурация разработана на базе БСП (Библиотеки Стандартных Подсистем), в ней уже заложен мощный и протестированный механизм выполнения задач в фоне. Использовать его — самый надежный способ.
Как это работает:
Модуль БСП ДлительныеОперации позволяет запустить любую процедуру общего модуля во временном фоновом задании. Платформа предоставляет функции для передачи прогресса обратно пользователю.
Для сообщения о прогрессе внутри выполняемого фонового задания используется метод:
// Сообщаем прогресс выполнения (от 0 до 100) и текст состояния
ДлительныеОперации.СообщитьПрогресс(50, "Выполнена половина загрузки файлов...");
Внешний сеанс (или другой пользователь) может получить этот прогресс, зная уникальный идентификатор запущенного фонового задания, с помощью функции:
// Получаем статус выполнения фонового задания по его ИД
ПараметрыВыполнения = ДлительныеОперации.ОперацияВыполнена(ИдентификаторЗадания);
Если НЕ ПараметрыВыполнения.Выполнена Тогда
Прогресс = ДлительныеОперации.ПрогрессВыполнения(ИдентификаторЗадания);
// Прогресс содержит структуру с процентом выполнения и текстом сообщения
КонецЕсли;
---
В крупных ИТ-архитектурах логировать процессы в текстовые файлы или кастомные СУБД считается неэффективным. Если в вашей компании развернута система сквозного мониторинга инфраструктуры, лучшим решением будет отправка метрик из 1С в Prometheus с последующей визуализацией в Grafana.
Схема работы:
Этот подход гарантирует высокую скорость работы, надежность хранения логов и освобождает 1С от лишней нагрузки по генерации и отдаче визуальных отчетов.