Мониторинг вывода развёртывания

Мониторинг вывода развёртывания ловит ошибки, которые не видно при сборке. Сборки проверяют код до запуска — компиляцию, типы, линтер. А мониторинг развёртывания отлавливает то, что проявляется только когда приложение реально обслуживает запросы: необработанные исключения, сбои подключения к базе данных, ошибки HTTP 500, проблемы при запуске.

Deploy output control

Методы развёртывания

Pastukhov Agent поддерживает два способа развёртывания, у каждого свои особенности наблюдения:

Debug Deploy (локальный)

Отладочное развёртывание запускает ваше приложение как локальный процесс. С включённым shallowCopy (по умолчанию) изменённые файлы копируются во временную папку перед запуском — это изолирует приложение от исходного кода и позволяет пересобирать его без конфликтов блокировки файлов. Потоки вывода передаются построчно через stdout/stderr, тут же записываются в .pastukhov/deploy/{имя}.log и транслируются в интерфейс в реальном времени через SignalR.

  • Управление процессом — PID-файлы отслеживают запущенные процессы; при старте автоматически очищаются устаревшие процессы от прошлых сессий;
  • Лимит размера лога — логи ограничены 500 МБ; при превышении лог очищается и развёртывание перезапускается само;
  • Отслеживание сборок — развёртывание может следить за сборками: когда все отслеживаемые сборки успешно завершены, развёртывание перезапускается с новым кодом.

Docker Deploy (удалённый)

Docker-развёртывание отправляет приложение на удалённый сервер по SSH и rsync, затем собирает и запускает его как контейнер. Процесс идёт пронумерованными шагами, каждый записывается с выводом, а итоговое состояние контейнера проверяется проверками здоровья.

⚠️ Экспериментальная функция — Docker Deploy ещё недостаточно протестирован. Используйте его с осторожностью и сообщайте об ошибках. Автор применяет только отладочные развёртывания в изолированных Docker-контейнерах — это проще в управлении и не менее безопасно.

  • SSH + rsync — файлы передаются на удалённый сервер, исключая паттерны вроде .git, node_modules и .pastukhov;
  • Жизненный цикл контейнера — загружает базовый образ, удаляет старый контейнер, собирает новый и запускает его с настроенными портами, томами, сетями и переменными окружения;
  • Проверки здоровья — после развёртывания проверяет, что контейнер запущен, и при желании сверяет endpoint здоровья по HTTP;
  • Тайм-аут на команду — у каждого шага свой тайм-аут; если шаг его превышает, процесс завершается.

Парсинг вывода развёртывания

Вывод во время работы разбирается в реальном времени через .pastukhov/deploy.parser, который использует тот же формат блоков [ERROR]/[/ERROR], что и парсер сборки. Паттерны покрывают типичные ошибки времени выполнения:

  • Необработанные исключения — полные трассировки стека, начинающиеся с «Unhandled exception.»;
  • Системные исключения — отступные трассировки для .NET, Java и других платформ;
  • Ошибки уровня лога — строки, начинающиеся с crit:, fail: или err: (формат Serilog/ILogger);
  • HTTP-ошибки — ответы с кодом состояния 500;
  • Отказы подключения — «Connection refused», ECONNREFUSED, тайм-ауты;
  • Исключения базы данных — SqlException, NpgsqlException с отступными трассировками;
  • Сбои запуска приложения — «Application startup exception» с продолжением строк.

Формат парсера

⚠️ Не правьте файлы парсера вручную — попросите это сделать ИИ-модель. Проще всего: выделите в выводе развёртывания нераспознанный текст (панель статуса или диалог развёртывания) и нажмите плавающую кнопку Fix parser — модель получит выделенный текст с готовым запросом и обновит deploy.parser. Либо используйте .pastukhov/README.md как подсказку в чате.

  • Строки комментариев, начинающиеся с #, игнорируются;
  • Однострочные паттерны — регулярное выражение, которое должно точно совпасть с одной строкой вывода;
  • Многострочные паттерны — обёрнуты в {{...}} и захватывают ноль или более строк подряд после внутреннего регулярного выражения.
# Необработанные исключения со стековыми трассировками
[ERROR]
Unhandled exception.*
{{^\s+at\s+}}              # Соответствует нулю или более строк, начинающимся с пробелов
[/ERROR]

# Уровни ошибок Serilog/ILogger
[ERROR]
(crit|fail|err):.*
[/ERROR]

# Предупреждения
[WARNING]
(warn|warning):.*
[/WARNING]

Парсер работает последовательно: на каждой строке вывода он перебирает блоки по порядку и применяет их паттерны. Когда все паттерны блока совпали подряд, эти строки извлекаются как одна ошибка, и парсер продвигается дальше. Ранние блоки в приоритете — как только нашлось совпадение, более поздние блоки для этих строк пропускаются.

Предупреждения разбираются так же: уровни лога, уведомления об устаревании, использование устаревших API. Чтобы добавить свои паттерны под формат ошибок вашего приложения, попросите модель обновить deploy.parser — он сам перезагрузится при сохранении.


Отображение вывода развёртывания

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

Меры на стороне сервера

  • Ограничение файла лога — логи отладочных развёртываний ограничены 500 МБ; при достижении лимита лог очищается и развёртывание перезапускается само, не давая диску расти бесконечно;
  • Усечение вывода — при чтении файлов лога отдаются только последние 100 КБ; более раннее содержимое отбрасывается с пометкой об усечении, так что браузер никогда не получает всю историю;
  • Ограничение SignalR — вывод в реальном времени буферизируется и передаётся порциями раз в 100 мс, а не каждой строкой по мере поступления, — меньше сообщений и нет потока мелких обновлений;
  • Инкрементальная передача — во время активного развёртывания вывод идёт построчно по мере появления, а клиент дописывает новые строки в существующий буфер, не заменяя весь вывод каждый раз.

Меры на стороне клиента

  • Лимит встроенной панели — панель статуса показывает только последние 200 строк вывода, оставаясь лёгкой при любом размере лога;
  • Лимит диалога — диалог вывода показывает до 2000 строк (конец лога) — достаточно, чтобы увидеть последние ошибки и контекст без нагрузки на браузер;
  • Лимит отправки в чат — при отправке вывода на анализ ИИ содержимое ограничивается 20 КБ, чтобы не раздуть контекст разговора;
  • Инкрементальное добавление — клиент дописывает новые строки в буфер, а не заменяет весь вывод при каждом обновлении SignalR, сводя к минимуму перерисовки;
  • Кэширование разобранного вывода — найденные ошибки и предупреждения заранее складываются в карту и переиспользуются, чтобы парсер не пересканировал весь вывод при каждом рендере.

Диалог развёртывания

Диалог вывода открывается по клику на имя развёртывания на панели статуса. В нём три вкладки:

  • Лог — необработанный, нефильтрованный вывод: последние 2000 строк для отладочных развёртываний или полный пошаговый лог для Docker;
  • Ошибки — разобранные записи об ошибках, выделенные красным;
  • Предупреждения — разобранные предупреждения, выделенные жёлтым.

На каждой вкладке есть кнопки копирования и отправки в чат. Отправка ошибок оборачивает их в кодовый блок build.log, чтобы модель могла разобрать сбой и предложить исправление. Если выделить текст на любой вкладке, появится плавающая кнопка Fix parser для быстрого обновления deploy.parser, когда формат ошибки не распознан.


Автоматический конвейер перезапуска

Развёртывания перезапускаются автоматически, когда все отслеживаемые сборки успешно завершились, — получается непрерывный конвейер «сборка → развёртывание → мониторинг»:

  1. Модель правит файлы проекта;
  2. Изменения запускают нужные сборки после заданной задержки;
  3. Парсер сборки извлекает ошибки и предупреждения из вывода;
  4. Автоисправление возвращает ошибки модели на исправление (цикл повторяется, пока сборки не пройдут);
  5. Когда все сборки прошли, служба развёртывания получает уведомление и перезапускает приложение;
  6. Вывод развёртывания разбирается в реальном времени на ошибки времени выполнения.

Этот конвейер работает без вашего участия. Следить за ним можно на панели статуса, а можно просто проверить результаты позже. Для отладочных развёртываний необязательное поле url в конфигурации даёт кликабельную кнопку, открывающую приложение напрямую, — не нужно запоминать адрес и порт отладочного экземпляра.


Эффективные приёмы проверки

  • Используйте мониторинг развёртывания вместе со сборками — сборки ловят статические ошибки, мониторинг — ошибки во время работы. Оба нужны для полного покрытия;
  • Добавляйте паттерны парсера под своё приложение — если приложение пишет ошибки в своём формате, добавьте паттерны в deploy.parser, чтобы они появлялись на вкладке «Ошибки»;
  • Отправляйте ошибки в чат — увидели ошибку развёртывания — нажмите «Отправить», и модель разберёт трассировку и предложит исправление;
  • Следите за размером лога — логи отладочных развёртываний ограничены 500 МБ. Если приложение очень болтливое, настройте уровни логов или увеличьте лимит.

Полная справка по развёртыванию — на странице Сборка и развёртывание, цикл автоматических ошибок — в Автоисправлении, предотвращение ручных перезапусков — в Хуки: управление поведением модели.