Prometheus on a node with its own panel: scrape core through the agent
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.
This commit is contained in:
@@ -15,6 +15,7 @@ export interface MonitorStatus {
|
|||||||
ready: boolean; can_install: boolean; command: string;
|
ready: boolean; can_install: boolean; command: string;
|
||||||
host: { id: number; name: string } | null; // Prometheus на ноде (или будет поставлен туда); null — на этом сервере
|
host: { id: number; name: string } | null; // Prometheus на ноде (или будет поставлен туда); null — на этом сервере
|
||||||
job: { action: 'install' | 'remove'; running: boolean; exit: number | null; log: string } | null; // последняя операция
|
job: { action: 'install' | 'remove'; running: boolean; exit: number | null; log: string } | null; // последняя операция
|
||||||
|
on_node?: boolean; // панель на ноде другой панели: Prometheus этой машины ставит и читает та
|
||||||
}
|
}
|
||||||
|
|
||||||
// Прогресс операции из строк «N/M шаг», которые печатает сам установщик (cli/src/monitor.ts). Шаг N считаем
|
// Прогресс операции из строк «N/M шаг», которые печатает сам установщик (cli/src/monitor.ts). Шаг N считаем
|
||||||
@@ -81,6 +82,16 @@ export default function PrometheusInstall({ token, showMsg }: PageProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!status) return <section className="st-section"><p className="st-hint">Загрузка…</p></section>;
|
if (!status) return <section className="st-section"><p className="st-hint">Загрузка…</p></section>;
|
||||||
|
if (status.on_node) return (
|
||||||
|
<section className="st-section">
|
||||||
|
<div className="st-row">
|
||||||
|
<span className="st-row-text">
|
||||||
|
<span className="st-row-name">Встроенный Prometheus</span>
|
||||||
|
<span className="st-hint">Этот сервер подключён нодой к другой панели. Prometheus на нём собирает её метрики, поэтому ставится, удаляется и смотрится («Монитор») из неё, а не отсюда.</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
const job = status.job;
|
const job = status.job;
|
||||||
const working = !!pending || !!job?.running || settle !== null;
|
const working = !!pending || !!job?.running || settle !== null;
|
||||||
|
|||||||
@@ -177,9 +177,10 @@ func (c *CLI) monitorInstall() {
|
|||||||
if !reDebian.MatchString(osFamily()) {
|
if !reDebian.MatchString(osFamily()) {
|
||||||
mfail("Автоустановка поддерживает только Debian и Ubuntu. На другом дистрибутиве поставьте Prometheus сами и подключите его кнопкой в панели (токен метрик).")
|
mfail("Автоустановка поддерживает только Debian и Ubuntu. На другом дистрибутиве поставьте Prometheus сами и подключите его кнопкой в панели (токен метрик).")
|
||||||
}
|
}
|
||||||
// Нода без своей панели (в том числе сервер, с которого панель переехала): метрики панели
|
// Нода: метрики панели Prometheus получает от агента, а тот — от core. Так и у ноды со своей
|
||||||
// Prometheus получает от агента, а тот — от core.
|
// панелью: Prometheus на машине один, и нужен он core — иначе core его не видит (агент
|
||||||
viaAgent := c.isNode && !contains(c.all, "ui")
|
// отдаёт /prom/… только при AGENT_METRICS_PORT), а панель ноды обходится без «Монитора».
|
||||||
|
viaAgent := c.isNode
|
||||||
target, newPort := os.Getenv("UI_PORT"), false
|
target, newPort := os.Getenv("UI_PORT"), false
|
||||||
if viaAgent {
|
if viaAgent {
|
||||||
if target = os.Getenv("AGENT_METRICS_PORT"); target == "" {
|
if target = os.Getenv("AGENT_METRICS_PORT"); target == "" {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -81,6 +82,7 @@ type Monitor struct {
|
|||||||
a *App
|
a *App
|
||||||
promURL string
|
promURL string
|
||||||
localEnabled bool
|
localEnabled bool
|
||||||
|
onNode bool // панель на ноде другой панели: Prometheus этой машины собирает метрики core, не наши
|
||||||
http *http.Client
|
http *http.Client
|
||||||
|
|
||||||
srcMu sync.Mutex
|
srcMu sync.Mutex
|
||||||
@@ -102,6 +104,7 @@ func newMonitor(a *App) *Monitor {
|
|||||||
return &Monitor{
|
return &Monitor{
|
||||||
a: a, promURL: envOr("PROM_URL", "http://127.0.0.1:9090"),
|
a: a, promURL: envOr("PROM_URL", "http://127.0.0.1:9090"),
|
||||||
localEnabled: strings.ToLower(envOr("LOCAL_NODE", "on")) != "off",
|
localEnabled: strings.ToLower(envOr("LOCAL_NODE", "on")) != "off",
|
||||||
|
onNode: os.Getenv("CORE_HOST") != "",
|
||||||
http: &http.Client{Transport: &http.Transport{Proxy: nil}},
|
http: &http.Client{Transport: &http.Transport{Proxy: nil}},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +135,7 @@ func (m *Monitor) forgetSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Monitor) findSource() *promSource {
|
func (m *Monitor) findSource() *promSource {
|
||||||
if m.promReady() {
|
if !m.onNode && m.promReady() {
|
||||||
return &promSource{local: true}
|
return &promSource{local: true}
|
||||||
}
|
}
|
||||||
ids := m.a.nodes.IDs()
|
ids := m.a.nodes.IDs()
|
||||||
@@ -316,6 +319,8 @@ func (m *Monitor) target(src *promSource, qs url.Values) int {
|
|||||||
switch {
|
switch {
|
||||||
case src != nil && !src.local:
|
case src != nil && !src.local:
|
||||||
return src.node
|
return src.node
|
||||||
|
case m.onNode:
|
||||||
|
return -1 // ставит его core: кнопка здесь поставила бы Prometheus для core
|
||||||
case m.localEnabled:
|
case m.localEnabled:
|
||||||
return 0
|
return 0
|
||||||
case src != nil:
|
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}}
|
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},
|
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.
|
// Установка и удаление — одно и то же: просим awg-ctrl сервера, он запускает CLI от root.
|
||||||
ask := func(action string) handler {
|
ask := func(action string) handler {
|
||||||
|
|||||||
Reference in New Issue
Block a user