Деплой метрик кладёт правила на диск, но Prometheus их не перечитывает — правка алерта не вступает в силу, а деплой зелёный #3467

Open
opened 2026-09-12 10:22:15 +00:00 by bot-backend · 1 comment
Collaborator

Найдено 12.09.2026 при приёмке PR #3464 (правка текста двух тревог).

Улика

  1. PR #3464 смержен в main (cfcdb939), Deploy Metrics / server (push) = success.
  2. Новый текст правил на диске инфра-хоста и внутри контейнера:
    docker exec gendesign-prometheus grep -n "container_memory_working_set_bytes" /etc/prometheus/rules/infra.yml
    139:          container_memory_working_set_bytes{name!=""}
    
  3. API Prometheus отдаёт СТАРОЕ правило:
    GET http://localhost:9090/api/v1/rules
    ContainerNearMemoryLimit => container_spec_memory_limit_bytes{name!=""} > 0 and ...
    
  4. Контейнер не перезапускался с 2026-08-27T18:12:24Z — 16 суток.
  5. .forgejo/workflows/deploy-metrics.yml перезагружает только Caddy (caddy reload после caddy validate). Prometheus не перезагружается ничем.
  6. --web.enable-lifecycle у Prometheus включён — то есть POST /-/reload доступен, просто никто его не зовёт.

Следствие

Любая правка ops/metrics/prometheus/** — правила алертов, prometheus.yml, scrape-конфиги — доезжает до диска и не вступает в силу до случайного рестарта контейнера. Деплой при этом зелёный, файл на месте, всё выглядит примененным.

Это тот же класс, что #3448: объявлено ≠ исполняется, и у него нет отрицательного признака — «работает» и «лежит на диске без эффекта» снаружи неотличимы.

Правильный образец лежит в том же файле: у Caddy есть и валидация, и reload. У Prometheus — ни того, ни другого.

Чинить

Шаг в deploy-metrics.yml по образцу Caddy: promtool check config + promtool check rules внутри контейнера (promtool 3.1.0 там есть), и POST /-/reload только если проверка прошла — иначе Prometheus молча останется на старом конфиге, а шаг покажется успешным.

Тем же вопросом проверить соседей стека (Alertmanager, Loki, Grafana, Alloy): меняет ли деплой их конфиг с диска и перечитывает ли его кто-нибудь.

Приёмка

После мержа GET /api/v1/rules отдаёт ContainerNearMemoryLimit с выражением, начинающимся с container_memory_working_set_bytes — то есть правка #3464 наконец вступает в силу. Это же и доказательство, что шаг работает.

Refs #3464, #3448, #3078.

Найдено 12.09.2026 при приёмке PR #3464 (правка текста двух тревог). ## Улика 1. PR #3464 смержен в `main` (`cfcdb939`), `Deploy Metrics / server (push) = success`. 2. Новый текст правил **на диске инфра-хоста и внутри контейнера**: ``` docker exec gendesign-prometheus grep -n "container_memory_working_set_bytes" /etc/prometheus/rules/infra.yml 139: container_memory_working_set_bytes{name!=""} ``` 3. **API Prometheus отдаёт СТАРОЕ правило:** ``` GET http://localhost:9090/api/v1/rules ContainerNearMemoryLimit => container_spec_memory_limit_bytes{name!=""} > 0 and ... ``` 4. Контейнер не перезапускался с **2026-08-27T18:12:24Z** — 16 суток. 5. `.forgejo/workflows/deploy-metrics.yml` перезагружает **только Caddy** (`caddy reload` после `caddy validate`). Prometheus не перезагружается ничем. 6. `--web.enable-lifecycle` у Prometheus **включён** — то есть `POST /-/reload` доступен, просто никто его не зовёт. ## Следствие Любая правка `ops/metrics/prometheus/**` — правила алертов, `prometheus.yml`, scrape-конфиги — доезжает до диска и **не вступает в силу** до случайного рестарта контейнера. Деплой при этом зелёный, файл на месте, всё выглядит примененным. Это тот же класс, что #3448: **объявлено ≠ исполняется**, и у него нет отрицательного признака — «работает» и «лежит на диске без эффекта» снаружи неотличимы. Правильный образец лежит в том же файле: у Caddy есть и валидация, и reload. У Prometheus — ни того, ни другого. ## Чинить Шаг в `deploy-metrics.yml` по образцу Caddy: `promtool check config` + `promtool check rules` внутри контейнера (promtool 3.1.0 там есть), и `POST /-/reload` **только если проверка прошла** — иначе Prometheus молча останется на старом конфиге, а шаг покажется успешным. Тем же вопросом проверить соседей стека (Alertmanager, Loki, Grafana, Alloy): меняет ли деплой их конфиг с диска и перечитывает ли его кто-нибудь. ## Приёмка После мержа `GET /api/v1/rules` отдаёт `ContainerNearMemoryLimit` с выражением, начинающимся с `container_memory_working_set_bytes` — то есть правка #3464 наконец вступает в силу. Это же и доказательство, что шаг работает. Refs #3464, #3448, #3078.
Author
Collaborator

Одна половина задачи в main НЕ доехала — датасорсы Grafana

#3467 закрыт мержем PR #3476, и Prometheus теперь действительно перечитывает конфигурацию: живая проверка 12.09 — GET /api/v1/rules отдаёт ContainerNearMemoryLimit, начинающийся с container_memory_working_set_bytes, то есть правка #3464 вступила в силу без рестарта контейнера (StartedAt по-прежнему 2026-08-27T18:12:24Z). Это ровно тот критерий приёмки, что стоял в issue. Хорошо.

Параллельно ту же задачу вела вторая ветка (PR #3475, закрыт как поглощённый). Поглощение неполное: в main попали Prometheus, ловушка инода, alert-ack и Alertmanager, но не попала перезагрузка датасорсов Grafanagrep -ic 'grafana.*datasources.*reload' по .forgejo/workflows/deploy-metrics.yml из main = 0.

Замер, который был сделан в закрытой ветке (стенд grafana:11.5.1)

  • дашборды перечитываются сами: updateIntervalSeconds: 30 в ops/metrics/grafana/provisioning/dashboards/dashboards.yml, маунт каталогом — новый файл появился без рестарта;
  • датасорсы — нет: изменённый url не применился и через 75 с; POST /api/admin/provisioning/datasources/reload применил сразу.

То есть правка ops/metrics/grafana/provisioning/datasources/datasources.yml сегодня ложится на диск и молча не вступает в силу — дословно та же болезнь, из-за которой это issue и заведено, только у другого сервиса.

Что осталось сделать

Один шаг в серверной джобе deploy-metrics.yml: POST /api/admin/provisioning/datasources/reload в контейнер Grafana (пароль раскрывается внутри контейнера, в argv хоста и в лог деплоя не попадает — конструкция проверена живьём и отдаёт JSON датасорсов, rc=0). Плюс строка в гейт backend/tests/ops/test_3467_prometheus_reload.py, который уже лежит в main.

Переоткрывать это issue или заводить новое — на усмотрение владельца; факт зафиксирован здесь, чтобы не потеряться между двумя ветками.

Отдельно из того же разбора: #3486 — тот же разрыв у трёх postgres-экспортёров (queries.yml одиночным маунтом), латентный, иноды пока совпадают.

## Одна половина задачи в main НЕ доехала — датасорсы Grafana #3467 закрыт мержем PR #3476, и Prometheus теперь действительно перечитывает конфигурацию: живая проверка 12.09 — `GET /api/v1/rules` отдаёт `ContainerNearMemoryLimit`, начинающийся с `container_memory_working_set_bytes`, то есть правка #3464 вступила в силу **без рестарта контейнера** (`StartedAt` по-прежнему `2026-08-27T18:12:24Z`). Это ровно тот критерий приёмки, что стоял в issue. Хорошо. Параллельно ту же задачу вела вторая ветка (PR #3475, закрыт как поглощённый). Поглощение неполное: в `main` попали Prometheus, ловушка инода, alert-ack и Alertmanager, но **не попала перезагрузка датасорсов Grafana** — `grep -ic 'grafana.*datasources.*reload'` по `.forgejo/workflows/deploy-metrics.yml` из `main` = **0**. ### Замер, который был сделан в закрытой ветке (стенд `grafana:11.5.1`) - дашборды перечитываются **сами**: `updateIntervalSeconds: 30` в `ops/metrics/grafana/provisioning/dashboards/dashboards.yml`, маунт каталогом — новый файл появился без рестарта; - **датасорсы — нет**: изменённый `url` не применился и через 75 с; `POST /api/admin/provisioning/datasources/reload` применил сразу. То есть правка `ops/metrics/grafana/provisioning/datasources/datasources.yml` сегодня ложится на диск и молча не вступает в силу — дословно та же болезнь, из-за которой это issue и заведено, только у другого сервиса. ### Что осталось сделать Один шаг в серверной джобе `deploy-metrics.yml`: `POST /api/admin/provisioning/datasources/reload` в контейнер Grafana (пароль раскрывается внутри контейнера, в argv хоста и в лог деплоя не попадает — конструкция проверена живьём и отдаёт JSON датасорсов, rc=0). Плюс строка в гейт `backend/tests/ops/test_3467_prometheus_reload.py`, который уже лежит в `main`. Переоткрывать это issue или заводить новое — на усмотрение владельца; факт зафиксирован здесь, чтобы не потеряться между двумя ветками. Отдельно из того же разбора: #3486 — тот же разрыв у трёх postgres-экспортёров (`queries.yml` одиночным маунтом), латентный, иноды пока совпадают.
Sign in to join this conversation.
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#3467
No description provided.