修改为直接与blackbox通信
This commit is contained in:
77
server/latency-service.js
Normal file
77
server/latency-service.js
Normal file
@@ -0,0 +1,77 @@
|
||||
const axios = require('axios');
|
||||
const cache = require('./cache');
|
||||
const db = require('./db');
|
||||
|
||||
const POLL_INTERVAL = 10000; // 10 seconds
|
||||
|
||||
async function pollLatency() {
|
||||
try {
|
||||
const [routes] = await db.query(`
|
||||
SELECT r.*, s.url
|
||||
FROM latency_routes r
|
||||
JOIN prometheus_sources s ON r.source_id = s.id
|
||||
WHERE s.type = 'blackbox'
|
||||
`);
|
||||
|
||||
if (routes.length === 0) return;
|
||||
|
||||
// Poll each route
|
||||
await Promise.allSettled(routes.map(async (route) => {
|
||||
try {
|
||||
// Blackbox exporter probe URL
|
||||
// We assume ICMP module for now. If target is a URL, maybe use http_2xx
|
||||
let module = 'icmp';
|
||||
let target = route.latency_target;
|
||||
|
||||
if (target.startsWith('http://') || target.startsWith('https://')) {
|
||||
module = 'http_2xx';
|
||||
}
|
||||
|
||||
const probeUrl = `${route.url.replace(/\/+$/, '')}/probe?module=${module}&target=${encodeURIComponent(target)}`;
|
||||
|
||||
const startTime = Date.now();
|
||||
const response = await axios.get(probeUrl, { timeout: 5000 });
|
||||
const duration = (Date.now() - startTime) / 1000; // Fallback to local timing if parsing fails
|
||||
|
||||
// Parse prometheus text format for probe_duration_seconds
|
||||
let latency = null;
|
||||
const lines = response.data.split('\n');
|
||||
for (const line of lines) {
|
||||
// Match "probe_duration_seconds 0.123" or "probe_duration_seconds{...} 0.123"
|
||||
const match = line.match(/^probe_duration_seconds(?:\{.*\})?\s+([\d.]+)/);
|
||||
if (match) {
|
||||
latency = parseFloat(match[1]) * 1000; // to ms
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (latency === null) {
|
||||
// Fallback to local response time if metric not found in output
|
||||
latency = duration * 1000;
|
||||
}
|
||||
|
||||
// Save to Valkey
|
||||
await cache.set(`latency:route:${route.id}`, latency, 60);
|
||||
// console.log(`[Latency] Route ${route.id} (${target}): ${latency.toFixed(2)}ms`);
|
||||
} catch (err) {
|
||||
// console.error(`[Latency] Error polling route ${route.id}:`, err.message);
|
||||
await cache.set(`latency:route:${route.id}`, null, 60);
|
||||
}
|
||||
}));
|
||||
} catch (err) {
|
||||
console.error('[Latency] Service error:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
let intervalId = null;
|
||||
|
||||
function start() {
|
||||
if (intervalId) clearInterval(intervalId);
|
||||
pollLatency(); // initial run
|
||||
intervalId = setInterval(pollLatency, POLL_INTERVAL);
|
||||
console.log('[Latency] Background service started (polling Blackbox Exporter directly)');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start
|
||||
};
|
||||
Reference in New Issue
Block a user