From af357a0a6fd73c289ec8a20111125a8b5ee63b58 Mon Sep 17 00:00:00 2001 From: Ivan Vasilev Date: Fri, 30 Oct 2026 00:30:31 +0300 Subject: [PATCH] Prometheus on a node with its own panel: scrape core through the agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The installer pointed it at the node's own panel and left AGENT_METRICS_PORT unset, so the agent refused /prom/… and core never saw it. A node's own panel now ignores the local Prometheus and shows no install buttons. --- awg-ui/src/tabs/settings/prometheus/index.tsx | 11 +++++++++++ internal/cli/monitor.go | 7 ++++--- internal/ui/monitor.go | 9 +++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/awg-ui/src/tabs/settings/prometheus/index.tsx b/awg-ui/src/tabs/settings/prometheus/index.tsx index 88fc544..c9aa0e2 100644 --- a/awg-ui/src/tabs/settings/prometheus/index.tsx +++ b/awg-ui/src/tabs/settings/prometheus/index.tsx @@ -15,6 +15,7 @@ export interface MonitorStatus { ready: boolean; can_install: boolean; command: string; host: { id: number; name: string } | null; // Prometheus на ноде (или будет поставлен туда); null — на этом сервере job: { action: 'install' | 'remove'; running: boolean; exit: number | null; log: string } | null; // последняя операция + on_node?: boolean; // панель на ноде другой панели: Prometheus этой машины ставит и читает та } // Прогресс операции из строк «N/M шаг», которые печатает сам установщик (cli/src/monitor.ts). Шаг N считаем @@ -81,6 +82,16 @@ export default function PrometheusInstall({ token, showMsg }: PageProps) { }; if (!status) return

Загрузка…

; + if (status.on_node) return ( +
+
+ + Встроенный Prometheus + Этот сервер подключён нодой к другой панели. Prometheus на нём собирает её метрики, поэтому ставится, удаляется и смотрится («Монитор») из неё, а не отсюда. + +
+
+ ); const job = status.job; const working = !!pending || !!job?.running || settle !== null; diff --git a/internal/cli/monitor.go b/internal/cli/monitor.go index 61d388f..4c9c1b5 100644 --- a/internal/cli/monitor.go +++ b/internal/cli/monitor.go @@ -177,9 +177,10 @@ func (c *CLI) monitorInstall() { if !reDebian.MatchString(osFamily()) { mfail("Автоустановка поддерживает только Debian и Ubuntu. На другом дистрибутиве поставьте Prometheus сами и подключите его кнопкой в панели (токен метрик).") } - // Нода без своей панели (в том числе сервер, с которого панель переехала): метрики панели - // Prometheus получает от агента, а тот — от core. - viaAgent := c.isNode && !contains(c.all, "ui") + // Нода: метрики панели Prometheus получает от агента, а тот — от core. Так и у ноды со своей + // панелью: Prometheus на машине один, и нужен он core — иначе core его не видит (агент + // отдаёт /prom/… только при AGENT_METRICS_PORT), а панель ноды обходится без «Монитора». + viaAgent := c.isNode target, newPort := os.Getenv("UI_PORT"), false if viaAgent { if target = os.Getenv("AGENT_METRICS_PORT"); target == "" { diff --git a/internal/ui/monitor.go b/internal/ui/monitor.go index bdb0aea..1f10250 100644 --- a/internal/ui/monitor.go +++ b/internal/ui/monitor.go @@ -15,6 +15,7 @@ import ( "math" "net/http" "net/url" + "os" "sort" "strconv" "strings" @@ -81,6 +82,7 @@ type Monitor struct { a *App promURL string localEnabled bool + onNode bool // панель на ноде другой панели: Prometheus этой машины собирает метрики core, не наши http *http.Client srcMu sync.Mutex @@ -102,6 +104,7 @@ func newMonitor(a *App) *Monitor { return &Monitor{ a: a, promURL: envOr("PROM_URL", "http://127.0.0.1:9090"), localEnabled: strings.ToLower(envOr("LOCAL_NODE", "on")) != "off", + onNode: os.Getenv("CORE_HOST") != "", http: &http.Client{Transport: &http.Transport{Proxy: nil}}, } } @@ -132,7 +135,7 @@ func (m *Monitor) forgetSource() { } func (m *Monitor) findSource() *promSource { - if m.promReady() { + if !m.onNode && m.promReady() { return &promSource{local: true} } ids := m.a.nodes.IDs() @@ -316,6 +319,8 @@ func (m *Monitor) target(src *promSource, qs url.Values) int { switch { case src != nil && !src.local: return src.node + case m.onNode: + return -1 // ставит его core: кнопка здесь поставила бы Prometheus для core case m.localEnabled: return 0 case src != nil: @@ -377,7 +382,7 @@ func (m *Monitor) router() *Router { jobOut = jsjson.Object{{Key: "action", Val: job.action}, {Key: "running", Val: job.running}, {Key: "exit", Val: job.exit}, {Key: "log", Val: job.log}} } return c.JSON(200, jsjson.Object{{Key: "ready", Val: ready}, {Key: "can_install", Val: job.can}, {Key: "job", Val: jobOut}, - {Key: "command", Val: "awg-ctrl monitor install"}, {Key: "host", Val: m.host(target)}}) + {Key: "command", Val: "awg-ctrl monitor install"}, {Key: "host", Val: m.host(target)}, {Key: "on_node", Val: m.onNode}}) }) // Установка и удаление — одно и то же: просим awg-ctrl сервера, он запускает CLI от root. ask := func(action string) handler {