修复延迟显示错误的BUG

This commit is contained in:
CN-JS-HuiBai
2026-04-06 01:13:34 +08:00
parent 5baffb7e05
commit c42d512dbd
2 changed files with 38 additions and 27 deletions

View File

@@ -55,44 +55,53 @@ async function pollLatency() {
const targetMetrics = [ const targetMetrics = [
'probe_icmp_duration_seconds', 'probe_icmp_duration_seconds',
'probe_http_duration_seconds', 'probe_http_duration_seconds',
'probe_dns_lookup_time_seconds',
'probe_duration_seconds' 'probe_duration_seconds'
]; ];
let foundLatency = null; let foundLatency = null;
const encodedTarget = target.toLowerCase();
for (const metricName of targetMetrics) { for (const metricName of targetMetrics) {
let bestLine = null;
// First pass: look for phase="rtt" which is the most accurate "ping"
for (const line of lines) { for (const line of lines) {
if (!line.startsWith(metricName)) continue; if (line.startsWith(metricName) && line.includes('phase="rtt"')) {
bestLine = line;
break;
}
}
// Precise matching for the specific target if multiple targets exist in data // Second pass: if no rtt phase, look for a line without phases (legacy format) or just the first line
// Handles: metric{instance="target"} value OR metric value if (!bestLine) {
const regex = new RegExp(`^${metricName}(?:\\{[^}]*\\})?\\s+([\\d.eE+-]+)`); for (const line of lines) {
const match = line.match(regex); if (line.startsWith(metricName)) {
// Prefer lines without {} if possible, otherwise take the first one
if (match) { if (!line.includes('{')) {
// If there are labels, verify they relate to our target (if target label exists) bestLine = line;
if (line.includes('{')) { break;
const labelsPart = line.substring(line.indexOf('{') + 1, line.lastIndexOf('}')).toLowerCase();
// Only check if the labels contain our target to be safe,
// though /probe usually only returns one target anyway.
if (labelsPart.includes(encodedTarget) || labelsPart.includes('instance') || labelsPart.includes('target')) {
const val = parseFloat(match[1]);
if (!isNaN(val)) foundLatency = val * 1000;
} }
} else { if (!bestLine) bestLine = line;
const val = parseFloat(match[1]); }
if (!isNaN(val)) foundLatency = val * 1000; }
}
if (bestLine) {
// Regex to capture the number, including scientific notation
const regex = new RegExp(`^${metricName}(?:\\{[^}]*\\})?\\s+([\\d.eE+-]+)`);
const match = bestLine.match(regex);
if (match) {
const val = parseFloat(match[1]);
if (!isNaN(val)) {
foundLatency = val * 1000; // convert to ms
break;
} }
} }
if (foundLatency !== null) break;
} }
if (foundLatency !== null) break;
} }
// 3. Final decision // 3. Final decision
// If it's a success, use found latency. If success=0 or missing, handle carefully. // If it's a success, use found latency. If success=0 or missing, handle carefully.
let latency;
if (isProbeSuccess && foundLatency !== null) { if (isProbeSuccess && foundLatency !== null) {
latency = foundLatency; latency = foundLatency;
} else { } else {

View File

@@ -809,12 +809,14 @@ module.exports = {
// Construct a single optimized query searching for priority metrics and common labels // Construct a single optimized query searching for priority metrics and common labels
// Prioritize probe_icmp_duration_seconds OVER probe_duration_seconds // Prioritize probe_icmp_duration_seconds OVER probe_duration_seconds
const queryExpr = `( const queryExpr = `(
probe_icmp_duration_seconds{phase="rtt", instance="${target}"} or
probe_icmp_duration_seconds{phase="rtt", target="${target}"} or
probe_http_duration_seconds{phase="rtt", instance="${target}"} or
probe_http_duration_seconds{phase="rtt", target="${target}"} or
probe_icmp_duration_seconds{instance="${target}"} or probe_icmp_duration_seconds{instance="${target}"} or
probe_icmp_duration_seconds{target="${target}"} or probe_icmp_duration_seconds{target="${target}"} or
probe_icmp_duration_seconds{instance_name="${target}"} or
probe_duration_seconds{instance="${target}"} or probe_duration_seconds{instance="${target}"} or
probe_duration_seconds{target="${target}"} or probe_duration_seconds{target="${target}"}
probe_duration_seconds{instance_name="${target}"}
)`; )`;
const params = new URLSearchParams({ query: queryExpr }); const params = new URLSearchParams({ query: queryExpr });