Files
monitoring/gen_vesti_dash.py
T

188 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# Генератор дашборда VESTI для Grafana (provisioning).
# Соглашения те же, что в node-<host>.json: datasource uid=Prometheus,
# stat-панели с mapping 0/1, timeseries.
import json
DS = {"type": "prometheus", "uid": "Prometheus"}
# --- утилиты ---
def stat_panel(title, expr, mapping, idx, w=3, h=3, x=0, y=0, legend=""):
return {
"datasource": DS,
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"mappings": ([{"options": mapping, "type": "value"}] if mapping else []),
"thresholds": {
"mode": "absolute",
"steps": [{"color": "red", "value": None}, {"color": "green", "value": 1}],
},
"unit": "short",
},
"overrides": [],
},
"gridPos": {"h": h, "w": w, "x": x, "y": y},
"id": idx,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": False},
"textMode": "auto",
},
"pluginVersion": "11.1.0",
"targets": [{"datasource": DS, "expr": expr, "legendFormat": legend, "refId": "A"}],
"title": title,
"type": "stat",
}
def timeseries_panel(title, exprs, idx, w=12, h=8, x=0, y=0, unit="short"):
targets = []
for e, l in exprs:
targets.append({"datasource": DS, "expr": e, "legendFormat": l, "refId": chr(65 + len(targets))})
return {
"datasource": DS,
"fieldConfig": {
"defaults": {
"color": {"mode": "palette-classic"},
"custom": {
"axisCenteredZero": False, "axisColorMode": "text", "axisLabel": "",
"axisPlacement": "auto", "drawStyle": "line", "fillOpacity": 10,
"gradientMode": "none", "hideFrom": {"legend": False, "tooltip": False, "viz": False},
"lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5,
"scaleDistribution": {"type": "linear"}, "showPoints": "never",
"spanNulls": False, "stacking": {"group": "A", "mode": "none"},
"thresholdsStyle": {"mode": "off"},
},
"mappings": [],
"thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": None}]},
"unit": unit,
},
"overrides": [],
},
"gridPos": {"h": h, "w": w, "x": x, "y": y},
"id": idx,
"options": {
"legend": {"calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": True},
"tooltip": {"mode": "multi", "sort": "none"},
},
"targets": targets,
"title": title,
"type": "timeseries",
}
panels = []
y = 0
idx = 1
# Row 1: Доступность (stat, 3x4 = 12 панелей в 2 ряда по 6)
row_title = {
"collapsed": False,
"datasource": DS,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": y},
"id": idx, "panels": [], "title": "Доступность компонентов", "type": "row",
}
idx += 1
y += 1
panels.append(row_title)
stats = [
("Web :8400 (systemd)", "vesti_web_up{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
("Publisher :8410 (healthz)", "vesti_publisher_health{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
("Publisher (Docker)", "vesti_publisher_docker{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
("Telegram tunnel :1080", "vesti_telegram_tunnel{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
("DB vesti.db", "vesti_db_ok{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
("Web systemd unit", "vesti_web_systemd{component=\"vesti\"}", {"0": {"color": "red", "text": "DOWN"}, "1": {"color": "green", "text": "UP"}}),
]
x = 0
for i, (title, expr, mp) in enumerate(stats):
panels.append(stat_panel(title, expr, mp, idx, w=4, h=3, x=(i % 6) * 4, y=y + (i // 6) * 3))
idx += 1
y += 6 # 2 ряда по 3 = 6 строк
# Row 2: Publisher healthz детали (bot/proxy/channels)
row2 = {
"collapsed": False, "datasource": DS,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": y},
"id": idx, "panels": [], "title": "Publisher — детали", "type": "row",
}
idx += 1
y += 1
panels.append(row2)
for i, (title, expr) in enumerate([
("Bot identity", 'vesti_publisher_bot{component="vesti"}'),
("Proxy SOCKS5", 'vesti_publisher_proxy{component="vesti"}'),
("Channels", 'vesti_publisher_channels{component="vesti"}'),
]):
panels.append(stat_panel(title, expr, None, idx, w=4, h=3, x=i * 4, y=y))
idx += 1
y += 3
# Row 3: БД
row3 = {
"collapsed": False, "datasource": DS,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": y},
"id": idx, "panels": [], "title": "База данных VESTI", "type": "row",
}
idx += 1
y += 1
panels.append(row3)
# stat: постов в БД, новых, опубликовано, последний рan
panels.append(stat_panel("Постов в БД", 'vesti_db_posts_total{component="vesti"}', None, idx, w=4, h=3, x=0, y=y))
idx += 1
panels.append(stat_panel("Новых", 'vesti_db_new_total{component="vesti"}', None, idx, w=4, h=3, x=4, y=y))
idx += 1
panels.append(stat_panel("Опубликовано", 'vesti_db_published_total{component="vesti"}', None, idx, w=4, h=3, x=8, y=y))
idx += 1
# временной ряд последнего рan (ts → время)
panels.append(timeseries_panel("Последний рan краулера", [('time() - vesti_db_last_run_ts{component="vesti"}', "сек назад")], idx, w=12, h=4, x=12, y=y, unit="s"))
idx += 1
y += 4
# Row 4: Временные ряды доступности (возврат по вре)
row4 = {
"collapsed": False, "datasource": DS,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": y},
"id": idx, "panels": [], "title": "История доступности (1/0)", "type": "row",
}
idx += 1
y += 1
panels.append(row4)
panels.append(timeseries_panel(
"Доступность компонентов",
[(f'{m}{{component="vesti"}}', t) for m, t in [
("vesti_web_up", "web"),
("vesti_publisher_health", "publisher"),
("vesti_publisher_docker", "docker"),
("vesti_telegram_tunnel", "tunnel"),
("vesti_db_ok", "db"),
("vesti_web_systemd", "web_sys"),
]],
idx, w=24, h=8, x=0, y=y, unit="short"))
idx += 1
y += 8
dashboard = {
"annotations": {"list": []},
"editable": True,
"fiscalYearStartMonth": 0,
"graphTooltip": 1,
"id": None,
"links": [],
"panels": panels,
"refresh": "15s",
"schemaVersion": 1,
"tags": ["vesti", "bigbox"],
"time": {"from": "now-6h", "to": "now"},
"timepicker": [{"refresh": "15s"}],
"title": "VESTI",
"uid": "vesti",
"version": 1,
}
with open("/opt/monitoring/grafana/dashboards/vesti/vesti.json", "w") as f:
json.dump(dashboard, f, indent=2, ensure_ascii=False)
print("written /opt/monitoring/grafana/dashboards/vesti/vesti.json", len(panels), "pabels")