Как настроить онлайн-просмотр отчетов по длительным операциям в 1С и исправить ошибки IIS

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

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

В этой статье мы подробно разберем, как организовать удобный веб-мониторинг длительных операций. Мы проанализируем технические проблемы, с которыми столкнулся автор темы, выясним причины возникновения ошибок HTTP 404 Not Found на IIS и разберем, почему ломается PHP-код, выводя на экран странные символы. Также мы рассмотрим альтернативные современные архитектурные подходы: от использования внешних баз данных до создания собственных легковесных HTTP-сервисов в 1С.

---

Почему возникает ошибка HTTP 404 на IIS для каталога отчетов

Рассмотрим классическую ситуацию, описанную автором: в процедуру загрузки данных встроен код, который записывает лог в 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:

  1. Вынос каталога отчетов за пределы публикации 1С (Рекомендуемый способ).

    Самое простое и безопасное решение — создать отдельный виртуальный каталог в IIS, который будет находиться на уровне корня сайта, а не внутри приложения 1С. Например, настройте путь server.ru/reports/proc.html. В этом случае запросы к отчетам будут обрабатываться стандартным модулем IIS StaticFileModule, минуя библиотеку 1С.

  2. Переопределение обработчиков через локальный web.config.

    Если вам жизненно важно, чтобы папка с отчетами находилась именно внутри структуры каталога публикации 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С) и заново назначит стандартную обработку статических файлов для текущей папки.

  3. Проверка MIME-типов и скрытых файлов.

    Убедитесь, что файлы отчетов не имеют атрибута «Скрытый» в операционной системе Windows. По умолчанию IIS блокирует доступ к скрытым файлам, возвращая ошибку 404.8 или 404.9. Также проверьте, что расширение файла (например, .json или .log) зарегистрировано в модуле «Типы MIME» в настройках IIS.

---

Разбор ошибки выполнения PHP-кода (почему ломается верстка)

В процессе обсуждения автор попытался переключиться на использование внешней базы данных 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:

  1. Скачайте стабильную non-thread-safe версию PHP для Windows с официального сайта.
  2. В консоли управления IIS выберите ваш сервер и перейдите в раздел «Сопоставление обработчиков» (Handler Mappings).
  3. Нажмите «Добавить сопоставление модуля» (Add Module Mapping).
  4. Заполните параметры настройки:
    • Путь запроса: *.php
    • Модуль: FastCgiModule
    • Исполняемый файл: путь к вашему файлу php-cgi.exe
    • Имя: PHP_via_FastCGI
  5. Перезапустите IIS. Теперь файлы с расширением .php будут корректно исполняться на стороне сервера.

---

Архитектурные подходы к мониторингу длительных операций в 1С

Давайте подробно рассмотрим четыре варианта реализации мониторинга: от простых файловых до профессиональных современных решений.

Вариант 1. Мониторинг через внешнюю базу данных (MySQL / SQLite) и 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.

---

Вариант 2. Использование собственных HTTP-сервисов 1С

Зачем использовать внешние базы данных и настраивать веб-серверы для PHP, если сама платформа 1С умеет отдавать веб-страницы или JSON-данные «из коробки»? Разработка собственного HTTP-сервиса — самый современный и быстрый способ решения задачи в рамках экосистемы 1С.

Преимущества:

Давайте разберем по шагам, как настроить HTTP-сервис:

  1. В конфигураторе добавьте новый объект метаданных «HTTP-сервисы» с именем Мониторинг.
  2. Укажите корневой шаблон (Root URL): monitoring.
  3. Добавьте шаблон URL с именем СтатусЗадачи и шаблоном /status/{ID}.
  4. Для этого шаблона добавьте метод 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/ИД_ЗАДАЧИ и отображать пользователю красивый прогресс-бар.

---

Вариант 3. Использование стандартных механизмов БСП (ДлительныеОперации)

Если ваша конфигурация разработана на базе БСП (Библиотеки Стандартных Подсистем), в ней уже заложен мощный и протестированный механизм выполнения задач в фоне. Использовать его — самый надежный способ.

Как это работает:

Модуль БСП ДлительныеОперации позволяет запустить любую процедуру общего модуля во временном фоновом задании. Платформа предоставляет функции для передачи прогресса обратно пользователю.

Для сообщения о прогрессе внутри выполняемого фонового задания используется метод:


// Сообщаем прогресс выполнения (от 0 до 100) и текст состояния
ДлительныеОперации.СообщитьПрогресс(50, "Выполнена половина загрузки файлов...");

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


// Получаем статус выполнения фонового задания по его ИД
ПараметрыВыполнения = ДлительныеОперации.ОперацияВыполнена(ИдентификаторЗадания);
Если НЕ ПараметрыВыполнения.Выполнена Тогда
    Прогресс = ДлительныеОперации.ПрогрессВыполнения(ИдентификаторЗадания);
    // Прогресс содержит структуру с процентом выполнения и текстом сообщения
КонецЕсли;

---

Вариант 4. Современный Enterprise-подход (Grafana + Prometheus)

В крупных ИТ-архитектурах логировать процессы в текстовые файлы или кастомные СУБД считается неэффективным. Если в вашей компании развернута система сквозного мониторинга инфраструктуры, лучшим решением будет отправка метрик из 1С в Prometheus с последующей визуализацией в Grafana.

Схема работы:

  1. В коде длительной операции 1С пошагово собирает метрики (например, количество обработанных строк, скорость загрузки в секунду, статус задачи).
  2. Через HTTP POST-запросы 1С отправляет эти метрики в промежуточный шлюз Pushgateway (компонент Prometheus).
  3. Сервер Prometheus забирает метрики из Pushgateway.
  4. В Grafana настраивается дашборд, который в реальном времени строит графики загрузки, показывает текущие статусы фоновых заданий, а при возникновении ошибок шлет уведомления в Telegram или Slack.

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

← На главную