修改为直接与blackbox通信

This commit is contained in:
CN-JS-HuiBai
2026-04-06 00:24:33 +08:00
parent d4d2927963
commit e8b60ce28b
6 changed files with 167 additions and 36 deletions

View File

@@ -6,6 +6,7 @@ const db = require('./db');
const prometheusService = require('./prometheus-service');
const cache = require('./cache');
const geoService = require('./geo-service');
const latencyService = require('./latency-service');
const checkAndFixDatabase = require('./db-integrity-check');
const http = require('http');
const WebSocket = require('ws');
@@ -451,7 +452,14 @@ app.get('/api/sources', async (req, res) => {
// Test connectivity for each source
const sourcesWithStatus = await Promise.all(rows.map(async (source) => {
try {
const response = await prometheusService.testConnection(source.url);
let response;
if (source.type === 'blackbox') {
// Simple check for blackbox exporter
const res = await fetch(`${source.url.replace(/\/+$/, '')}/metrics`, { timeout: 3000 }).catch(() => null);
response = (res && res.ok) ? 'Blackbox Exporter Ready' : 'Connection Error';
} else {
response = await prometheusService.testConnection(source.url);
}
return { ...source, status: 'online', version: response };
} catch (e) {
return { ...source, status: 'offline', version: null };
@@ -466,15 +474,15 @@ app.get('/api/sources', async (req, res) => {
// Add a new Prometheus source
app.post('/api/sources', requireAuth, async (req, res) => {
let { name, url, description, is_server_source } = req.body;
let { name, url, description, is_server_source, type } = req.body;
if (!name || !url) {
return res.status(400).json({ error: 'Name and URL are required' });
}
if (!/^https?:\/\//i.test(url)) url = 'http://' + url;
try {
const [result] = await db.query(
'INSERT INTO prometheus_sources (name, url, description, is_server_source) VALUES (?, ?, ?, ?)',
[name, url, description || '', is_server_source === undefined ? 1 : (is_server_source ? 1 : 0)]
'INSERT INTO prometheus_sources (name, url, description, is_server_source, type) VALUES (?, ?, ?, ?, ?)',
[name, url, description || '', is_server_source === undefined ? 1 : (is_server_source ? 1 : 0), type || 'prometheus']
);
const [rows] = await db.query('SELECT * FROM prometheus_sources WHERE id = ?', [result.insertId]);
@@ -494,8 +502,8 @@ app.put('/api/sources/:id', requireAuth, async (req, res) => {
if (url && !/^https?:\/\//i.test(url)) url = 'http://' + url;
try {
await db.query(
'UPDATE prometheus_sources SET name = ?, url = ?, description = ?, is_server_source = ? WHERE id = ?',
[name, url, description || '', is_server_source ? 1 : 0, req.params.id]
'UPDATE prometheus_sources SET name = ?, url = ?, description = ?, is_server_source = ?, type = ? WHERE id = ?',
[name, url, description || '', is_server_source ? 1 : 0, type || 'prometheus', req.params.id]
);
// Clear network history cache
await cache.del('network_history_all');
@@ -523,11 +531,18 @@ app.delete('/api/sources/:id', requireAuth, async (req, res) => {
// Test connection to a Prometheus source
app.post('/api/sources/test', async (req, res) => {
let { url } = req.body;
let { url, type } = req.body;
if (url && !/^https?:\/\//i.test(url)) url = 'http://' + url;
try {
const version = await prometheusService.testConnection(url);
res.json({ status: 'ok', version });
let result;
if (type === 'blackbox') {
const resVal = await fetch(`${url.replace(/\/+$/, '')}/metrics`, { timeout: 5000 }).catch(() => null);
result = (resVal && resVal.ok) ? 'Blackbox Exporter Ready' : 'Connection Failed';
if (!resVal || !resVal.ok) throw new Error(result);
} else {
result = await prometheusService.testConnection(url);
}
res.json({ status: 'ok', version: result });
} catch (err) {
res.status(400).json({ status: 'error', message: err.message });
}
@@ -893,7 +908,14 @@ app.get('/api/metrics/latency', async (req, res) => {
}
const results = await Promise.all(routes.map(async (route) => {
const latency = await prometheusService.getLatency(route.url, route.latency_target);
// Try to get from Valkey first (filled by background latencyService)
let latency = await cache.get(`latency:route:${route.id}`);
// Fallback if not in cache (maybe service just started or failed)
if (latency === null) {
latency = await prometheusService.getLatency(route.url, route.latency_target);
}
return {
id: route.id,
source: route.latency_source,
@@ -933,8 +955,9 @@ async function broadcastMetrics() {
}
}
// Check and fix database integrity on startup
// Start services
checkAndFixDatabase();
latencyService.start();
const REFRESH_INT = parseInt(process.env.REFRESH_INTERVAL) || 5000;
setInterval(broadcastMetrics, REFRESH_INT);