1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Rust frontend APIs for driving upstream libiperf.
//!
//! `iperf3-rs` links upstream `esnet/iperf3` through FFI. The high-level
//! [`IperfCommand`] API accepts ordinary iperf arguments, lets libiperf parse
//! and run them, and can stream the same live interval metrics used by the CLI's
//! Pushgateway exporter.
//! Protocol-specific metrics are optional, so callers can distinguish a real
//! zero from values that libiperf did not report for a TCP, UDP, or SCTP run.
//! Metrics callbacks emit one aggregate stream direction per libiperf reporting
//! interval. In bidirectional mode the client-side aggregate is the sending
//! direction and the server-side aggregate is the receiving direction; this
//! crate does not currently emit both bidirectional halves from one process.
//!
//! This crate is useful when a Rust program needs to run iperf tests directly,
//! for example from a bot, controller, or test harness, without spawning an
//! external `iperf3-rs` process and parsing stdout.
//! High-level library runs suppress libiperf's ordinary stdout output by
//! default; use [`IperfCommand::inherit_output`] or [`IperfCommand::logfile`]
//! when an application intentionally wants upstream text output.
//!
//! # Examples
//!
//! Run a client and consume live interval metrics:
//!
//! ```no_run
//! use std::time::Duration;
//!
//! use iperf3_rs::{IperfCommand, MetricEvent, MetricsMode, Result};
//!
//! fn main() -> Result<()> {
//! let mut command = IperfCommand::client("127.0.0.1");
//! command
//! .duration(Duration::from_secs(10))
//! .report_interval(Duration::from_secs(1));
//!
//! let (running, mut metrics) = command.spawn_with_metrics(MetricsMode::Interval)?;
//!
//! while let Some(event) = metrics.recv() {
//! match event {
//! MetricEvent::Interval(sample) => {
//! println!("{} bit/s", sample.bandwidth_bits_per_second);
//! }
//! MetricEvent::Window(window) => {
//! println!("{} bytes", window.transferred_bytes);
//! }
//! _ => {}
//! }
//! }
//!
//! running.wait()?;
//! Ok(())
//! }
//! ```
//!
//! # Concurrency
//!
//! High-level [`IperfCommand`] runs are serialized inside the process. libiperf
//! has process-global state for errors, signal handling, and output hooks, so
//! this crate intentionally avoids promising in-process parallelism that
//! upstream does not clearly guarantee. Server runs must use iperf's one-off
//! mode (`-s -1`) by default; opt in with
//! [`IperfCommand::allow_unbounded_server`] only when the process is dedicated
//! to that long-lived server.
//!
//! [`RunningIperf`] observes worker completion; it is not a cancellation or kill
//! handle. Dropping it detaches the worker, and
//! [`RunningIperf::wait_timeout`] only stops waiting. It does not stop libiperf.
//! Use a separate process, container, VM, or another process-backed wrapper for
//! runs that must be externally terminated, isolated from hangs, or executed in
//! parallel.
//!
//! # Metrics stream ownership
//!
//! [`MetricsMode::Interval`] and [`MetricsMode::Window`] are every-sample
//! library streams. They preserve all events by using unbounded internal queues,
//! so long-running runs must continuously drain [`MetricsStream`] or disable
//! metrics. [`IperfCommand::run`] collects emitted events in memory before
//! returning; do not combine it with metrics for unbounded server runs or other
//! runs that can produce an unbounded number of samples.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use PrometheusEncoder;
pub use ;