fix(ops/metrics): Prometheus не видел ни одного Alertmanager — цель file_sd осталась пустой #3160

Merged
bot-backend merged 1 commit from fix/3155-prometheus-no-alertmanager into main 2026-08-27 18:12:11 +00:00
5 changed files with 56 additions and 22 deletions

View file

@ -213,6 +213,38 @@ jobs:
echo "::warning title=Алерты выключены::METRICS_TELEGRAM_BOT_TOKEN/CHAT_ID не заданы. Метрики и логи собираются, но при срабатывании правила НИКТО не будет уведомлён. Канал доставки — открытый вопрос #3078."
fi
# ── Цели file_sd для Prometheus (#3155) ────────────────────────
# Включатель профиля и цель для Prometheus обязаны стоять в ОДНОМ
# условии. Пока они жили порознь, вышло так: 27.08 профиль alerts
# подняли, Alertmanager стартовал Up и healthy, а файл целей остался
# плейсхолдером [] — Prometheus не видел ни одного приёмника
# (activeAlertmanagers: []) и сложил 1568 уведомлений в
# prometheus_notifications_dropped_total. Ни ошибки в логах, ни
# красного деплоя: снаружи алертинг выглядел рабочим.
#
# Пишем ДО `up`: свежесозданный контейнер обязан увидеть готовый
# файл. И пишем усечением на месте (`:>` вместо rm) — инод
# сохраняется, поэтому работающий Prometheus подхватывает
# содержимое сам, без пересоздания. Это ровно та ловушка одиночного
# бинд-маунта, что описана у Alertmanager ниже, только здесь её
# удаётся обойти, не трогая контейнер.
AM_TARGETS_FILE=ops/metrics/prometheus/alertmanager_targets.gen.yml
: > "$AM_TARGETS_FILE"
echo "# Файл рендерится деплоем (deploy-metrics.yml), правки руками затрутся." >> "$AM_TARGETS_FILE"
if [ "$PROFILES" = "alerts" ]; then
echo '- targets: ["alertmanager:9093"]' >> "$AM_TARGETS_FILE"
echo " labels:" >> "$AM_TARGETS_FILE"
echo " host: infra" >> "$AM_TARGETS_FILE"
echo "Prometheus: приёмник alertmanager:9093 прописан в целях."
else
# Пустой список, а НЕ отсутствующий файл: одиночный бинд-маунт
# несуществующего пути docker подменяет каталогом, и Prometheus
# не стартует вовсе.
echo "# Профиль alerts выключен — приёмников нет." >> "$AM_TARGETS_FILE"
echo "[]" >> "$AM_TARGETS_FILE"
echo "Prometheus: профиль alerts выключен — целей нет, это штатно."
fi
# ── read-only роль для датасорса GlitchTip ─────────────────────
# Идемпотентно. Прав на запись не выдаём вовсе: датасорс Grafana
# обязан быть безопасен даже при полном доступе к дашбордам.

7
.gitignore vendored
View file

@ -102,3 +102,10 @@ ds-bundle/
# Боевой конфиг Alertmanager собирается на хосте из .tmpl (deploy-metrics.yml):
# содержит токен бота и идентификатор чата, поэтому в репозиторий не попадает.
ops/metrics/alertmanager/alertmanager.yml
# Цели file_sd для Prometheus рендерит тот же деплой — по условию, которым
# включает профиль alerts. Отслеживаемая версия правилась руками и жила отдельно
# от включателя: 27.08 профиль включили, а файл так и остался плейсхолдером,
# и Prometheus не видел ни одного приёмника (#3155). Производный файл убирает
# сам зазор — правится только там же, где принимается решение о профиле.
ops/metrics/prometheus/alertmanager_targets.gen.yml

View file

@ -52,9 +52,11 @@ services:
- ./ops/metrics/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./ops/metrics/prometheus/rules:/etc/prometheus/rules:ro
# file_sd для job "alertmanager" — см. комментарий в prometheus.yml.
# Файл производный: рендерится деплоем (deploy-metrics.yml) по тому же
# условию, что включает профиль alerts, и потому в репозитории его нет.
# Забыть этот монт — значит вернуть "no such host" из-за отсутствующего
# файла целей (был инцидент, когда похожий пропущенный монт положил Caddy).
- ./ops/metrics/prometheus/alertmanager_targets.yml:/etc/prometheus/alertmanager_targets.yml:ro
- ./ops/metrics/prometheus/alertmanager_targets.gen.yml:/etc/prometheus/alertmanager_targets.gen.yml:ro
- prometheus_data:/prometheus
expose:
- "9090"

View file

@ -1,14 +0,0 @@
# file_sd target-файл для job "alertmanager" (см. prometheus.yml).
#
# Пустой список ([]) — штатное состояние, пока профиль "alerts" в
# docker-compose.metrics.yml выключен (#3078, канал доставки не решён):
# сервиса alertmanager не существует, и Prometheus просто не видит для
# него ни одной цели — без ошибок разрешения имени и без up{job=...}=0.
#
# Prometheus перечитывает этот файл на лету (file_sd), рестарт не нужен.
# Когда профиль alerts включат — заменить [] на:
#
# - targets: ["alertmanager:9093"]
# labels:
# host: infra
[]

View file

@ -22,15 +22,22 @@ rule_files:
# Пока профиль alerts выключен, сервиса alertmanager не существует. Со
# static_configs это раз в интервал давало "lookup alertmanager: no such
# host" в логах и up{job="alertmanager"}=0. file_sd_configs вместо
# static_configs делает цель опциональной идиоматично для Prometheus: файл
# целей по умолчанию содержит пустой список ([]) — алертов нет и ошибок
# разрешения имени тоже нет. Prometheus перечитывает file_sd на лету, так что
# включение профиля alerts сводится к наполнению файла, без рестарта и без
# правки этого конфига.
# static_configs делает цель опциональной идиоматично для Prometheus: пустой
# список ([]) — алертов нет и ошибок разрешения имени тоже нет. Prometheus
# перечитывает file_sd на лету, так что включение профиля сводится к
# наполнению файла, без рестарта и без правки этого конфига.
#
# Файл ПРОИЗВОДНЫЙ (суффикс .gen, в .gitignore): его рендерит deploy-metrics.yml
# тем же условием, которым включает профиль. Одно условие — один результат.
# Отслеживаемая git'ом версия этого не давала: 27.08 профиль подняли, а файл
# так и остался плейсхолдером []. Alertmanager был Up и healthy, Prometheus же
# не видел ни одного приёмника (activeAlertmanagers: []), и 1568 уведомлений
# ушли в prometheus_notifications_dropped_total — молча, без единой ошибки ни
# в одном логе. Держать включатель и цель в разных местах больше нельзя.
alerting:
alertmanagers:
- file_sd_configs:
- files: ["/etc/prometheus/alertmanager_targets.yml"]
- files: ["/etc/prometheus/alertmanager_targets.gen.yml"]
scrape_configs:
# Сам Prometheus. Нужен не для красоты: по нему строится алерт на здоровье
@ -46,7 +53,7 @@ scrape_configs:
# просто не появится в выдаче вместо ошибки "no such host".
- job_name: alertmanager
file_sd_configs:
- files: ["/etc/prometheus/alertmanager_targets.yml"]
- files: ["/etc/prometheus/alertmanager_targets.gen.yml"]
- job_name: loki
static_configs: