From 7fdac71062a5d59a5f3555636312c50346b6311b Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Mon, 6 Apr 2026 01:03:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BB=B6=E8=BF=9F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/index.js | 7 +++---- server/latency-service.js | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/index.js b/server/index.js index 29ba3bd..7aec305 100644 --- a/server/index.js +++ b/server/index.js @@ -910,13 +910,12 @@ app.put('/api/latency-routes/:id', requireAuth, async (req, res) => { app.get('/api/metrics/latency', async (req, res) => { try { const [routes] = await db.query(` - SELECT r.*, s.url + SELECT r.*, s.url, s.type as source_type FROM latency_routes r JOIN prometheus_sources s ON r.source_id = s.id `); if (routes.length === 0) { - // Return empty routes array instead of null for consistency return res.json({ routes: [] }); } @@ -924,8 +923,8 @@ app.get('/api/metrics/latency', async (req, res) => { // 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) { + // Fallback if not in cache (only for prometheus sources, blackbox sources rely on the background service) + if (latency === null && route.source_type === 'prometheus') { latency = await prometheusService.getLatency(route.url, route.latency_target); } diff --git a/server/latency-service.js b/server/latency-service.js index af677d0..f918363 100644 --- a/server/latency-service.js +++ b/server/latency-service.js @@ -38,7 +38,8 @@ async function pollLatency() { const lines = response.data.split('\n'); for (const line of lines) { - if (line.match(/^probe_success\s+1/)) { + // Match probe_success with optional labels: probe_success{...} 1 + if (line.match(/^probe_success({.*})?\s+1/)) { success = true; break; } @@ -48,8 +49,9 @@ async function pollLatency() { // Try specialized metrics first for better accuracy const priorityMetrics = ['probe_icmp_duration_seconds', 'probe_http_duration_seconds', 'probe_duration_seconds']; for (const metricName of priorityMetrics) { - // Support scientific notation (e.g. 1.23e-04) - const regex = new RegExp(`^${metricName}(?:\\{.*\\})?\\s+([\\d.eE+-]+)`); + // More robust regex: handle optional labels and scientific notation + // Supports: metric_name{...} 1.23e-4 or metric_name 0.05 + const regex = new RegExp(`^${metricName}\\s*(?:\\{[^}]*\\})?\\s+([\\d.eE+-]+)`); for (const line of lines) { const match = line.match(regex); if (match) {