mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Display worst TCP retransmits as a button in the UI.
This commit is contained in:
parent
a4c8093401
commit
280447f79d
@ -30,6 +30,14 @@ pub enum BusRequest {
|
|||||||
end: u32,
|
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.
|
/// Retrieves the TopN hosts with the best RTT, sorted by RTT descending.
|
||||||
GetBestRtt {
|
GetBestRtt {
|
||||||
/// First row to retrieve (usually 0 unless you are paging)
|
/// First row to retrieve (usually 0 unless you are paging)
|
||||||
|
@ -43,6 +43,9 @@ pub enum BusResponse {
|
|||||||
/// Provides the worst N RTT scores, sorted in descending order.
|
/// Provides the worst N RTT scores, sorted in descending order.
|
||||||
WorstRtt(Vec<IpStats>),
|
WorstRtt(Vec<IpStats>),
|
||||||
|
|
||||||
|
/// Provides the worst N Retransmit scores, sorted in descending order.
|
||||||
|
WorstRetransmits(Vec<IpStats>),
|
||||||
|
|
||||||
/// Provides the best N RTT scores, sorted in descending order.
|
/// Provides the best N RTT scores, sorted in descending order.
|
||||||
BestRtt(Vec<IpStats>),
|
BestRtt(Vec<IpStats>),
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ fn rocket() -> _ {
|
|||||||
tracker::ram_usage,
|
tracker::ram_usage,
|
||||||
tracker::top_10_downloaders,
|
tracker::top_10_downloaders,
|
||||||
tracker::worst_10_rtt,
|
tracker::worst_10_rtt,
|
||||||
|
tracker::worst_10_tcp,
|
||||||
tracker::rtt_histogram,
|
tracker::rtt_histogram,
|
||||||
tracker::host_counts,
|
tracker::host_counts,
|
||||||
shaped_devices::all_shaped_devices,
|
shaped_devices::all_shaped_devices,
|
||||||
|
@ -133,6 +133,21 @@ pub async fn worst_10_rtt(_auth: AuthGuard) -> NoCache<MsgPack<Vec<IpStatsWithPl
|
|||||||
NoCache::new(MsgPack(Vec::new()))
|
NoCache::new(MsgPack(Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/api/worst_10_tcp")]
|
||||||
|
pub async fn worst_10_tcp(_auth: AuthGuard) -> NoCache<MsgPack<Vec<IpStatsWithPlan>>> {
|
||||||
|
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")]
|
#[get("/api/rtt_histogram")]
|
||||||
pub async fn rtt_histogram(_auth: AuthGuard) -> NoCache<MsgPack<Vec<u32>>> {
|
pub async fn rtt_histogram(_auth: AuthGuard) -> NoCache<MsgPack<Vec<u32>>> {
|
||||||
if let Ok(messages) = bus_request(vec![BusRequest::RttHistogram]).await
|
if let Ok(messages) = bus_request(vec![BusRequest::RttHistogram]).await
|
||||||
|
@ -164,8 +164,12 @@
|
|||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="card bg-light">
|
<div class="card bg-light">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title"><i class='fa fa-exclamation'></i> Worst 10 RTT</h5>
|
<h5 class="card-title"><i class='fa fa-exclamation'></i> Worst 10
|
||||||
|
<button id="btnworstRtt" class="btn btn-small btn-success" href="/top10" onclick="showWorstRtt()">RTT</button>
|
||||||
|
<button id="btnworstTcp" class="btn btn-small btn-primary" href="/top10" onclick="showWorstTcp()">TCP Retransmits</button>
|
||||||
|
</h5>
|
||||||
<div id="worstRtt"></div>
|
<div id="worstRtt"></div>
|
||||||
|
<div id="worstTcp" style="display: none;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -319,6 +323,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateWorstTcp() {
|
||||||
|
msgPackGet("/api/worst_10_tcp", (tt) => {
|
||||||
|
//console.log(tt);
|
||||||
|
updateNTable('#worstTcp', tt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateTop10Flows() {
|
function updateTop10Flows() {
|
||||||
$.get("/api/flows/top/10/rate", data => {
|
$.get("/api/flows/top/10/rate", data => {
|
||||||
let html = "<table class='table table-striped' style='font-size: 8pt'>";
|
let html = "<table class='table table-striped' style='font-size: 8pt'>";
|
||||||
@ -436,6 +447,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let top10view = "circuits";
|
let top10view = "circuits";
|
||||||
|
let worst10view = "rtt";
|
||||||
|
|
||||||
|
function changeBottom10(visible) {
|
||||||
|
const bottom10 = ["worstRtt", "worstTcp"];
|
||||||
|
for (let i=0; i<bottom10.length; i++) {
|
||||||
|
$("#" + bottom10[i]).hide();
|
||||||
|
$("#btn" + bottom10[i]).removeClass("btn-success");
|
||||||
|
$("#btn" + bottom10[i]).addClass("btn-primary");
|
||||||
|
}
|
||||||
|
$("#" + visible).show();
|
||||||
|
$("#btn" + visible).removeClass("btn-primary");
|
||||||
|
$("#btn" + visible).addClass("btn-success");
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWorstRtt() {
|
||||||
|
changeBottom10("worstRtt");
|
||||||
|
worst10view = "rtt";
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWorstTcp() {
|
||||||
|
changeBottom10("worstTcp");
|
||||||
|
worst10view = "tcp";
|
||||||
|
}
|
||||||
|
|
||||||
function changeTop10(visible) {
|
function changeTop10(visible) {
|
||||||
const top10 = ["top10dl", "top10flows", "top10ep", "top10eth", "top10pro"];
|
const top10 = ["top10dl", "top10flows", "top10ep", "top10eth", "top10pro"];
|
||||||
@ -495,7 +529,11 @@
|
|||||||
|
|
||||||
if (tickCount % 5 == 0) {
|
if (tickCount % 5 == 0) {
|
||||||
updateHistogram();
|
updateHistogram();
|
||||||
updateWorst10();
|
if (worst10view == "rtt") {
|
||||||
|
updateWorst10();
|
||||||
|
} else if (worst10view == "tcp") {
|
||||||
|
updateWorstTcp();
|
||||||
|
}
|
||||||
if (top10view == "circuits") {
|
if (top10view == "circuits") {
|
||||||
updateTop10();
|
updateTop10();
|
||||||
} else if (top10view == "flows") {
|
} else if (top10view == "flows") {
|
||||||
|
@ -151,6 +151,9 @@ fn handle_bus_requests(
|
|||||||
BusRequest::GetWorstRtt { start, end } => {
|
BusRequest::GetWorstRtt { start, end } => {
|
||||||
throughput_tracker::worst_n(*start, *end)
|
throughput_tracker::worst_n(*start, *end)
|
||||||
}
|
}
|
||||||
|
BusRequest::GetWorstRetransmits { start, end } => {
|
||||||
|
throughput_tracker::worst_n_retransmits(*start, *end)
|
||||||
|
}
|
||||||
BusRequest::GetBestRtt { start, end } => {
|
BusRequest::GetBestRtt { start, end } => {
|
||||||
throughput_tracker::best_n(*start, *end)
|
throughput_tracker::best_n(*start, *end)
|
||||||
}
|
}
|
||||||
|
@ -307,6 +307,62 @@ pub fn worst_n(start: u32, end: u32) -> BusResponse {
|
|||||||
BusResponse::WorstRtt(result)
|
BusResponse::WorstRtt(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn worst_n_retransmits(start: u32, end: u32) -> BusResponse {
|
||||||
|
let mut full_list: Vec<TopList> = {
|
||||||
|
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 {
|
pub fn best_n(start: u32, end: u32) -> BusResponse {
|
||||||
let mut full_list: Vec<TopList> = {
|
let mut full_list: Vec<TopList> = {
|
||||||
let tp_cycle = THROUGHPUT_TRACKER
|
let tp_cycle = THROUGHPUT_TRACKER
|
||||||
|
Loading…
Reference in New Issue
Block a user