feat(observability): алерты адресуются в топик форумной группы + проверка конфига до подъёма (#3078) #3111

Merged
lekss361 merged 1 commit from feat/3078-alert-topic into main 2026-08-26 11:15:55 +00:00
Owner

Бот для тревог — тот же, что пересылает сообщения поддержки, а его чат форумный. Без message_thread_id Alertmanager кладёт алерты в общую тему, вперемешку с клиентской перепиской.

Поле действительно поддерживается

Проверено amtool check-config на том же образе, что поднимается в проде (prom/alertmanager:v0.28.0): конфиг с message_thread_id: 42 принимается. Схема Alertmanager строгая и неизвестные поля отвергает — значит успешная проверка означает поддержку, а не молчаливое игнорирование. Контрольный конфиг без этого поля тоже валиден.

Почему подставляется целая строка, а не значение

envsubst не умеет условий. При шаблоне вида message_thread_id: ${METRICS_TELEGRAM_TOPIC_ID} незаданный топик дал бы в конфиге:

        message_thread_id:

И это не деградация: Alertmanager с таким конфигом не стартует вовсе — алертинг исчезает целиком, а контейнер просто не поднимается. Поэтому деплой формирует либо всю строку с отступом, либо пустую:

if [ -n "${METRICS_TELEGRAM_TOPIC_ID:-}" ]; then
    METRICS_TELEGRAM_TOPIC_LINE="        message_thread_id: ${METRICS_TELEGRAM_TOPIC_ID}"
else
    METRICS_TELEGRAM_TOPIC_LINE=""
fi

Топик необязателен — без него поле отсутствует и алерты уходят в общую тему, как раньше.

Результат подстановки проверен глазами в обоих режимах:

С ТОПИКОМ                          БЕЗ ТОПИКА
  chat_id: -100123                   chat_id: -100123
  message_thread_id: 42              (пустая строка)
  api_url: "https://api..."          api_url: "https://api..."

Отступ 8 пробелов, вровень с соседними полями.

Попутно: проверка конфига до подъёма стека

Добавлен amtool check-config перед compose up — по образцу caddy validate ниже в этом же файле, и по той же причине: битый конфиг Alertmanager не деградирует, а выключает алертинг молча. amtool берётся из того же образа, что и сам Alertmanager (версия читается из docker-compose.metrics.yml), иначе проверялась бы не та версия схемы.

Тесты

backend/tests/ops/test_3078_alert_topic.py, 4 штуки. Рендерят шаблон обоими способами и разбирают результат как YAML — проверяется фактический конфиг, а не наличие нужных слов в тексте:

  1. топик проставляется во всех получателях, включая telegram-heartbeat — иначе «мониторинг жив» капал бы мимо темы и это заметили бы не сразу;
  2. без топика поля нет вовсе, а не пустое значение; chat_id при этом не пострадал;
  3. деплой собирает строку целиком и объявляет переменную в списке envsubst — забыть её значит оставить в конфиге литерал ${METRICS_TELEGRAM_TOPIC_LINE}, на котором Alertmanager не стартует;
  4. проверка конфига стоит до подъёма.

Фальсификация: на исходных файлах краснеют 3 из 4. Проходит только второй — он фиксирует сохранённое поведение при незаданном топике, а не регресс.

Проверено помимо тестов: YAML воркфлоу парсится, в коммите нет CR, tests/ops целиком — 35 passed.

Что нужно от владельца

Переменные секретные, поэтому задаются вручную на Beget: METRICS_TELEGRAM_BOT_TOKEN, METRICS_TELEGRAM_CHAT_ID и — опционально — METRICS_TELEGRAM_TOPIC_ID. После этого запускаю деплой и проверяю, что тревога реально доходит в чат, а не что контейнер стал зелёным.

Refs #3078

Бот для тревог — тот же, что пересылает сообщения поддержки, а его чат форумный. Без `message_thread_id` Alertmanager кладёт алерты в общую тему, вперемешку с клиентской перепиской. ## Поле действительно поддерживается Проверено `amtool check-config` на **том же образе, что поднимается в проде** (`prom/alertmanager:v0.28.0`): конфиг с `message_thread_id: 42` принимается. Схема Alertmanager строгая и неизвестные поля отвергает — значит успешная проверка означает поддержку, а не молчаливое игнорирование. Контрольный конфиг без этого поля тоже валиден. ## Почему подставляется целая строка, а не значение `envsubst` не умеет условий. При шаблоне вида `message_thread_id: ${METRICS_TELEGRAM_TOPIC_ID}` незаданный топик дал бы в конфиге: ```yaml message_thread_id: ``` И это **не деградация**: Alertmanager с таким конфигом не стартует вовсе — алертинг исчезает целиком, а контейнер просто не поднимается. Поэтому деплой формирует либо всю строку с отступом, либо пустую: ```bash if [ -n "${METRICS_TELEGRAM_TOPIC_ID:-}" ]; then METRICS_TELEGRAM_TOPIC_LINE=" message_thread_id: ${METRICS_TELEGRAM_TOPIC_ID}" else METRICS_TELEGRAM_TOPIC_LINE="" fi ``` Топик необязателен — без него поле отсутствует и алерты уходят в общую тему, как раньше. Результат подстановки проверен глазами в обоих режимах: ``` С ТОПИКОМ БЕЗ ТОПИКА chat_id: -100123 chat_id: -100123 message_thread_id: 42 (пустая строка) api_url: "https://api..." api_url: "https://api..." ``` Отступ 8 пробелов, вровень с соседними полями. ## Попутно: проверка конфига до подъёма стека Добавлен `amtool check-config` **перед** `compose up` — по образцу `caddy validate` ниже в этом же файле, и по той же причине: битый конфиг Alertmanager не деградирует, а выключает алертинг молча. `amtool` берётся из того же образа, что и сам Alertmanager (версия читается из `docker-compose.metrics.yml`), иначе проверялась бы не та версия схемы. ## Тесты `backend/tests/ops/test_3078_alert_topic.py`, 4 штуки. Рендерят шаблон обоими способами и **разбирают результат как YAML** — проверяется фактический конфиг, а не наличие нужных слов в тексте: 1. топик проставляется во **всех** получателях, включая `telegram-heartbeat` — иначе «мониторинг жив» капал бы мимо темы и это заметили бы не сразу; 2. без топика поля **нет вовсе**, а не пустое значение; `chat_id` при этом не пострадал; 3. деплой собирает строку целиком **и объявляет переменную в списке `envsubst`** — забыть её значит оставить в конфиге литерал `${METRICS_TELEGRAM_TOPIC_LINE}`, на котором Alertmanager не стартует; 4. проверка конфига стоит до подъёма. **Фальсификация:** на исходных файлах краснеют 3 из 4. Проходит только второй — он фиксирует сохранённое поведение при незаданном топике, а не регресс. Проверено помимо тестов: YAML воркфлоу парсится, в коммите нет CR, `tests/ops` целиком — 35 passed. ## Что нужно от владельца Переменные секретные, поэтому задаются вручную на Beget: `METRICS_TELEGRAM_BOT_TOKEN`, `METRICS_TELEGRAM_CHAT_ID` и — опционально — `METRICS_TELEGRAM_TOPIC_ID`. После этого запускаю деплой и проверяю, что тревога **реально доходит в чат**, а не что контейнер стал зелёным. Refs #3078
lekss361 added 1 commit 2026-08-26 11:11:32 +00:00
feat(observability): алерты адресуются в топик форумной группы (#3078)
All checks were successful
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m2s
CI / backend-tests (pull_request) Successful in 17m24s
5b7ef161e3
Бот, которым шлются тревоги, — тот же, что пересылает сообщения поддержки, а
его чат форумный. Без message_thread_id Alertmanager кладёт тревоги в общую
тему, вперемешку с клиентской перепиской.

Поле поддерживается: проверено amtool check-config на том же образе, что
поднимается в проде (prom/alertmanager:v0.28.0). Схема Alertmanager строгая и
неизвестные поля отвергает, так что успешная проверка означает именно
поддержку, а не молчаливое игнорирование.

Подставляется ЦЕЛАЯ СТРОКА, а не значение: envsubst не умеет условий, и при
шаблоне вида `message_thread_id: ${TOPIC_ID}` незаданный топик дал бы
`message_thread_id:` без значения. Это не деградация - Alertmanager с таким
конфигом не стартует вовсе, то есть алертинг исчезает целиком. Деплой
формирует либо всю строку с отступом, либо пустую.

Топик необязателен: без него поле отсутствует, алерты уходят в общую тему,
поведение прежнее.

Попутно добавлена проверка конфига через amtool ДО подъёма стека - по образцу
`caddy validate` ниже в этом же файле. amtool берётся из того же образа, что и
сам Alertmanager, иначе проверялась бы не та версия схемы. Битый конфиг теперь
роняет деплой громко, а не выключает алертинг тихо.

Тесты (4) рендерят шаблон обоими способами и разбирают результат как YAML -
проверяется фактический конфиг, а не наличие нужных слов в тексте. Отдельно
проверено, что переменная объявлена в списке envsubst: забыть её - значит
оставить в конфиге литерал плейсхолдера.

Фальсификация: на исходных файлах краснеют 3 из 4; проходит только тест,
фиксирующий сохранённое поведение при незаданном топике. tests/ops целиком -
35 passed.
lekss361 merged commit a941d1899f into main 2026-08-26 11:15:55 +00:00
lekss361 deleted branch feat/3078-alert-topic 2026-08-26 11:15:55 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3111
No description provided.