From 280447f79d573cc4d94941bada7a221285be0953 Mon Sep 17 00:00:00 2001 From: Herbert Wolverson Date: Tue, 19 Mar 2024 15:39:58 -0500 Subject: [PATCH] Display worst TCP retransmits as a button in the UI. --- src/rust/lqos_bus/src/bus/request.rs | 8 +++ src/rust/lqos_bus/src/bus/response.rs | 3 + src/rust/lqos_node_manager/src/main.rs | 1 + src/rust/lqos_node_manager/src/tracker/mod.rs | 15 +++++ src/rust/lqos_node_manager/static/main.html | 42 +++++++++++++- src/rust/lqosd/src/main.rs | 3 + src/rust/lqosd/src/throughput_tracker/mod.rs | 56 +++++++++++++++++++ 7 files changed, 126 insertions(+), 2 deletions(-) diff --git a/src/rust/lqos_bus/src/bus/request.rs b/src/rust/lqos_bus/src/bus/request.rs index 064cd0e1..29b44ffd 100644 --- a/src/rust/lqos_bus/src/bus/request.rs +++ b/src/rust/lqos_bus/src/bus/request.rs @@ -30,6 +30,14 @@ pub enum BusRequest { end: u32, }, + /// Retrieves the TopN hosts with the worst Retransmits, sorted by Retransmits descending. + GetWorstRetransmits { + /// First row to retrieve (usually 0 unless you are paging) + start: u32, + /// Last row to retrieve (10 for top-10 starting at 0) + end: u32, + }, + /// Retrieves the TopN hosts with the best RTT, sorted by RTT descending. GetBestRtt { /// First row to retrieve (usually 0 unless you are paging) diff --git a/src/rust/lqos_bus/src/bus/response.rs b/src/rust/lqos_bus/src/bus/response.rs index 5d08347f..47987dcd 100644 --- a/src/rust/lqos_bus/src/bus/response.rs +++ b/src/rust/lqos_bus/src/bus/response.rs @@ -43,6 +43,9 @@ pub enum BusResponse { /// Provides the worst N RTT scores, sorted in descending order. WorstRtt(Vec), + /// Provides the worst N Retransmit scores, sorted in descending order. + WorstRetransmits(Vec), + /// Provides the best N RTT scores, sorted in descending order. BestRtt(Vec), diff --git a/src/rust/lqos_node_manager/src/main.rs b/src/rust/lqos_node_manager/src/main.rs index a2f64428..93ea75ee 100644 --- a/src/rust/lqos_node_manager/src/main.rs +++ b/src/rust/lqos_node_manager/src/main.rs @@ -59,6 +59,7 @@ fn rocket() -> _ { tracker::ram_usage, tracker::top_10_downloaders, tracker::worst_10_rtt, + tracker::worst_10_tcp, tracker::rtt_histogram, tracker::host_counts, shaped_devices::all_shaped_devices, diff --git a/src/rust/lqos_node_manager/src/tracker/mod.rs b/src/rust/lqos_node_manager/src/tracker/mod.rs index 1c70da15..ec5c2b8f 100644 --- a/src/rust/lqos_node_manager/src/tracker/mod.rs +++ b/src/rust/lqos_node_manager/src/tracker/mod.rs @@ -133,6 +133,21 @@ pub async fn worst_10_rtt(_auth: AuthGuard) -> NoCache NoCache>> { + if let Ok(messages) = bus_request(vec![BusRequest::GetWorstRetransmits { start: 0, end: 10 }]).await + { + for msg in messages { + if let BusResponse::WorstRetransmits(stats) = msg { + let result = stats.iter().map(|tt| tt.into()).collect(); + return NoCache::new(MsgPack(result)); + } + } + } + + NoCache::new(MsgPack(Vec::new())) +} + #[get("/api/rtt_histogram")] pub async fn rtt_histogram(_auth: AuthGuard) -> NoCache>> { if let Ok(messages) = bus_request(vec![BusRequest::RttHistogram]).await diff --git a/src/rust/lqos_node_manager/static/main.html b/src/rust/lqos_node_manager/static/main.html index 3902f56c..ef72af31 100644 --- a/src/rust/lqos_node_manager/static/main.html +++ b/src/rust/lqos_node_manager/static/main.html @@ -164,8 +164,12 @@
-
Worst 10 RTT
+
Worst 10 + + +
+
@@ -319,6 +323,13 @@ }); } + function updateWorstTcp() { + msgPackGet("/api/worst_10_tcp", (tt) => { + //console.log(tt); + updateNTable('#worstTcp', tt); + }); + } + function updateTop10Flows() { $.get("/api/flows/top/10/rate", data => { let html = ""; @@ -436,6 +447,29 @@ } let top10view = "circuits"; + let worst10view = "rtt"; + + function changeBottom10(visible) { + const bottom10 = ["worstRtt", "worstTcp"]; + for (let i=0; i { throughput_tracker::worst_n(*start, *end) } + BusRequest::GetWorstRetransmits { start, end } => { + throughput_tracker::worst_n_retransmits(*start, *end) + } BusRequest::GetBestRtt { start, end } => { throughput_tracker::best_n(*start, *end) } diff --git a/src/rust/lqosd/src/throughput_tracker/mod.rs b/src/rust/lqosd/src/throughput_tracker/mod.rs index 64e83cb4..0e5f81e9 100644 --- a/src/rust/lqosd/src/throughput_tracker/mod.rs +++ b/src/rust/lqosd/src/throughput_tracker/mod.rs @@ -307,6 +307,62 @@ pub fn worst_n(start: u32, end: u32) -> BusResponse { BusResponse::WorstRtt(result) } +pub fn worst_n_retransmits(start: u32, end: u32) -> BusResponse { + let mut full_list: Vec = { + let tp_cycle = THROUGHPUT_TRACKER + .cycle + .load(std::sync::atomic::Ordering::Relaxed); + THROUGHPUT_TRACKER + .raw_data + .iter() + .filter(|v| !v.key().as_ip().is_loopback()) + .filter(|d| retire_check(tp_cycle, d.most_recent_cycle)) + .filter(|te| te.median_latency().is_some()) + .map(|te| { + ( + *te.key(), + te.bytes_per_second, + te.packets_per_second, + te.median_latency().unwrap_or(0.0), + te.tc_handle, + te.circuit_id.as_ref().unwrap_or(&String::new()).clone(), + te.tcp_retransmits, + ) + }) + .collect() + }; + full_list.sort_by(|a, b| { + let total_a = a.6 .0 + a.6 .1; + let total_b = b.6 .0 + b.6 .1; + total_b.cmp(&total_a) + }); + let result = full_list + .iter() + .skip(start as usize) + .take((end as usize) - (start as usize)) + .map( + |( + ip, + (bytes_dn, bytes_up), + (packets_dn, packets_up), + median_rtt, + tc_handle, + circuit_id, + tcp_retransmits, + )| IpStats { + ip_address: ip.as_ip().to_string(), + circuit_id: circuit_id.clone(), + bits_per_second: (bytes_dn * 8, bytes_up * 8), + packets_per_second: (*packets_dn, *packets_up), + median_tcp_rtt: *median_rtt, + tc_handle: *tc_handle, + tcp_retransmits: *tcp_retransmits, + }, + ) + .collect(); + BusResponse::WorstRetransmits(result) +} + pub fn best_n(start: u32, end: u32) -> BusResponse { let mut full_list: Vec = { let tp_cycle = THROUGHPUT_TRACKER