Rust CI / cargo fmt (push) Successful in 17s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Successful in 34s
Rust CI / cargo clippy (push) Successful in 35s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 8s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 10s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Successful in 1m14s
Rust CI / cargo doc (push) Successful in 23s
Fuzz Smoke / cargo fuzz smoke (push) Failing after 29s
Supply chain / cargo-deny advisories (push) Successful in 9s
Supply chain / cargo-deny bans licenses sources (push) Successful in 5s
Supply chain / actionlint (push) Successful in 3s
Netem Interop / netem interop (push) Successful in 1m11s
124 lines
3.7 KiB
Rust
124 lines
3.7 KiB
Rust
use std::fmt::Write as _;
|
|
|
|
use irtt_stats::{Snapshot, TimeStats};
|
|
|
|
use crate::cmd::format::{
|
|
format_ns_f64, format_optional_ns_f64 as format_ns_f64_opt,
|
|
format_optional_ns_i128 as format_ns_i128, format_percent,
|
|
};
|
|
|
|
pub fn format_summary(summary: &Snapshot) -> String {
|
|
format_summary_with_options(summary, SummaryFormatOptions::default())
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
pub struct SummaryFormatOptions {
|
|
pub verbose: bool,
|
|
pub show_running_only_note: bool,
|
|
}
|
|
|
|
pub fn format_summary_with_options(summary: &Snapshot, options: SummaryFormatOptions) -> String {
|
|
let mut out = String::new();
|
|
let packets = summary.packets;
|
|
let loss = summary.loss;
|
|
|
|
writeln!(out).unwrap();
|
|
writeln!(out, "irtt-rs summary").unwrap();
|
|
if options.show_running_only_note {
|
|
writeln!(
|
|
out,
|
|
"note: medians unavailable in continuous mode; running statistics are bounded-memory"
|
|
)
|
|
.unwrap();
|
|
}
|
|
writeln!(out).unwrap();
|
|
writeln!(
|
|
out,
|
|
" {:<18} {:>7} {:>10} {:>10} {:>10} {:>10} {:>10}",
|
|
"Metric", "Count", "Min", "Mean", "Median", "Max", "Stddev"
|
|
)
|
|
.unwrap();
|
|
writeln!(out, " {}", "-".repeat(82)).unwrap();
|
|
|
|
write_time_row(&mut out, "RTT", &summary.rtt.primary);
|
|
if options.verbose {
|
|
write_time_row(&mut out, "raw RTT", &summary.rtt.raw);
|
|
write_time_row(&mut out, "adjusted RTT", &summary.rtt.adjusted);
|
|
}
|
|
write_time_row(&mut out, "IPDV/jitter", &summary.ipdv.round_trip);
|
|
write_time_row(&mut out, "send IPDV", &summary.ipdv.send);
|
|
write_time_row(&mut out, "receive IPDV", &summary.ipdv.receive);
|
|
write_time_row(&mut out, "send delay", &summary.one_way_delay.send_delay);
|
|
write_time_row(
|
|
&mut out,
|
|
"receive delay",
|
|
&summary.one_way_delay.receive_delay,
|
|
);
|
|
write_time_row(
|
|
&mut out,
|
|
"server processing",
|
|
&summary.server_processing.processing,
|
|
);
|
|
write_time_row(&mut out, "send call", &summary.send_call);
|
|
write_time_row(&mut out, "timer error", &summary.timer_error);
|
|
|
|
writeln!(out).unwrap();
|
|
writeln!(
|
|
out,
|
|
"packets: sent={} received={} unique={} lost={} loss={}",
|
|
packets.packets_sent,
|
|
packets.packets_received,
|
|
packets.unique_replies,
|
|
loss.lost_packets,
|
|
format_percent(loss.packet_loss_percent)
|
|
)
|
|
.unwrap();
|
|
if packets.duplicates != 0 || packets.late_packets != 0 {
|
|
writeln!(
|
|
out,
|
|
"replies: duplicates={} ({}) late={} ({})",
|
|
packets.duplicates,
|
|
format_percent(loss.duplicate_percent),
|
|
packets.late_packets,
|
|
format_percent(loss.late_packets_percent)
|
|
)
|
|
.unwrap();
|
|
}
|
|
writeln!(
|
|
out,
|
|
"bytes: sent={} received={}",
|
|
packets.bytes_sent, packets.bytes_received
|
|
)
|
|
.unwrap();
|
|
|
|
if packets.server_packets_received.is_some() || packets.server_received_window.is_some() {
|
|
write!(out, "server:").unwrap();
|
|
if let Some(count) = packets.server_packets_received {
|
|
write!(out, " received={count}").unwrap();
|
|
}
|
|
if let Some(window) = packets.server_received_window {
|
|
write!(out, " window={window:#x}").unwrap();
|
|
}
|
|
writeln!(out).unwrap();
|
|
}
|
|
|
|
out
|
|
}
|
|
|
|
fn write_time_row(out: &mut String, label: &str, value: &TimeStats) {
|
|
if value.count == 0 {
|
|
return;
|
|
}
|
|
writeln!(
|
|
out,
|
|
" {label:<18} {:>7} {:>10} {:>10} {:>10} {:>10} {:>10}",
|
|
value.count,
|
|
format_ns_i128(value.min_ns),
|
|
format_ns_f64(value.mean_ns),
|
|
format_ns_f64_opt(value.median_ns),
|
|
format_ns_i128(value.max_ns),
|
|
format_ns_f64(value.stddev_ns())
|
|
)
|
|
.unwrap();
|
|
}
|