修复延迟显示错误的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) {
for (const line of lines) { let bestLine = null;
if (!line.startsWith(metricName)) continue;
// Precise matching for the specific target if multiple targets exist in data // First pass: look for phase="rtt" which is the most accurate "ping"
// Handles: metric{instance="target"} value OR metric value for (const line of lines) {
if (line.startsWith(metricName) && line.includes('phase="rtt"')) {
bestLine = line;
break;
}
}
// Second pass: if no rtt phase, look for a line without phases (legacy format) or just the first line
if (!bestLine) {
for (const line of lines) {
if (line.startsWith(metricName)) {
// Prefer lines without {} if possible, otherwise take the first one
if (!line.includes('{')) {
bestLine = line;
break;
}
if (!bestLine) bestLine = line;
}
}
}
if (bestLine) {
// Regex to capture the number, including scientific notation
const regex = new RegExp(`^${metricName}(?:\\{[^}]*\\})?\\s+([\\d.eE+-]+)`); const regex = new RegExp(`^${metricName}(?:\\{[^}]*\\})?\\s+([\\d.eE+-]+)`);
const match = line.match(regex); const match = bestLine.match(regex);
if (match) { if (match) {
// If there are labels, verify they relate to our target (if target label exists)
if (line.includes('{')) {
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]); const val = parseFloat(match[1]);
if (!isNaN(val)) foundLatency = val * 1000; if (!isNaN(val)) {
} foundLatency = val * 1000; // convert to ms
} else { break;
const val = parseFloat(match[1]);
if (!isNaN(val)) foundLatency = val * 1000;
} }
} }
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 });