Commit 6db4ffa5 authored by Vitaly Lipatov's avatar Vitaly Lipatov

check_system/check-blocked: add bandwidth row from telegraf InfluxDB

Rename gre.beget/ikev2.beget to gre.beget.ogw/ikev2.beget.ogw to match telegraf gateway names. Add /api/bandwidth endpoint querying InfluxDB for 30-min average throughput. Display as first table row. Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 3eb6e240
......@@ -15,6 +15,7 @@ import os
import sys
import time
import urllib.parse
import urllib.request
LISTEN_HOST = "0.0.0.0"
LISTEN_PORT = 80
......@@ -24,6 +25,12 @@ RESULTS_FILE = os.environ.get(
"/root/check-blocked-results.json",
)
INFLUXDB_URL = os.environ.get(
"INFLUXDB_URL",
"http://telegraf.office.etersoft.ru:8086",
)
INFLUXDB_DB = "gateways"
HTML_PAGE = """\
<!DOCTYPE html>
<html lang="ru">
......@@ -57,6 +64,8 @@ HTML_PAGE = """\
.http { background: #ffe0cc; color: #8a4500; }
.block { background: #f8d7da; color: #721c24; }
.speed { display: block; font-size: 0.75em; color: #666; margin-top: 2px; }
.bw { background: #e8f4fd; color: #1a5276; font-weight: 500; }
.bw td:first-child { font-weight: 600; font-family: system-ui, sans-serif; }
.legend { margin-top: 16px; color: #888; font-size: 0.8em; }
.legend span { margin-right: 16px; }
.legend-dot { display: inline-block; width: 10px; height: 10px;
......@@ -88,7 +97,13 @@ function el(tag, attrs, children) {
return e;
}
function render(data) {
function fmtBps(bps) {
var mbit = bps / 1000000;
if (mbit < 1) return mbit.toFixed(1) + ' Mbit/s';
return Math.round(mbit) + ' Mbit/s';
}
function render(data, bw) {
var c = document.getElementById('content');
c.textContent = '';
......@@ -116,6 +131,22 @@ function render(data) {
// Build body rows
var rows = [];
// Bandwidth row (first)
if (bw) {
var bwCells = [el('td', {text: 'Bandwidth (30m avg)'})];
data.gateways.forEach(function(gw) {
var val = bw[gw];
if (val !== undefined) {
bwCells.push(el('td', {text: fmtBps(val)}));
} else {
bwCells.push(el('td', {text: '-'}));
}
});
var bwRow = el('tr', {cls: 'bw'}, bwCells);
rows.push(bwRow);
}
data.results.forEach(function(r) {
var link = el('a', {href: 'https://' + r.site + '/', text: r.site, target: '_blank'});
var cells = [el('td', null, [link])];
......@@ -144,14 +175,16 @@ function render(data) {
}
function refresh() {
fetch('/api/results')
.then(function(r) { return r.json(); })
.then(render)
.catch(function() {
var c = document.getElementById('content');
c.textContent = '';
c.appendChild(el('div', {cls: 'no-data', text: 'Failed to load results'}));
});
Promise.all([
fetch('/api/results').then(function(r) { return r.json(); }),
fetch('/api/bandwidth').then(function(r) { return r.json(); }).catch(function() { return null; })
]).then(function(arr) {
render(arr[0], arr[1]);
}).catch(function() {
var c = document.getElementById('content');
c.textContent = '';
c.appendChild(el('div', {cls: 'no-data', text: 'Failed to load results'}));
});
}
refresh();
......@@ -162,6 +195,30 @@ setInterval(refresh, 5 * 60 * 1000);
"""
def query_bandwidth():
"""Query average bandwidth (bit/s) per gateway from InfluxDB over last 30 min."""
q = ("SELECT non_negative_derivative(mean(bytes_recv),1s)*8"
" FROM net WHERE time > now() - 30m"
" GROUP BY time(30m), gateway")
params = urllib.parse.urlencode({"db": INFLUXDB_DB, "q": q})
url = "%s/query?%s" % (INFLUXDB_URL, params)
try:
with urllib.request.urlopen(url, timeout=5) as resp:
data = json.loads(resp.read())
except Exception:
return {}
result = {}
for series in data.get("results", [{}])[0].get("series", []):
gw = series.get("tags", {}).get("gateway", "")
values = series.get("values", [])
if values:
# Take the last 30-min window value
bps = values[-1][1]
if bps is not None:
result[gw] = bps
return result
class Handler(http.server.BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
sys.stderr.write("[%s] %s\n" % (self.log_date_time_string(), fmt % args))
......@@ -206,6 +263,9 @@ class Handler(http.server.BaseHTTPRequestHandler):
else:
self.send_json({"error": "no results yet"}, 404)
elif path == "/api/bandwidth":
self.send_json(query_bandwidth())
else:
self.send_json({"error": "not found"}, 404)
......
......@@ -24,8 +24,8 @@ dgw socks5h://91.232.225.12:1080
igw socks5h://91.232.225.13:1080
gre.hetzner socks5h://91.232.225.122:1080
ikev2.hetzner socks5h://91.232.225.120:1080
gre.beget socks5h://91.232.225.124:1080
ikev2.beget socks5h://91.232.225.130:1080
gre.beget.ogw socks5h://91.232.225.124:1080
ikev2.beget.ogw socks5h://91.232.225.130:1080
"
# Default sites to check
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment