oxedyne/fe2o3/fe2o3_sys/src/net.rs
3.8 KiB, 1 run
created by r1870400018:10588, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Per-interface network counters from `/proc/net/dev`. |
| 2 | |
| 3 | use crate::parse::{ |
| 4 | parse_num, |
| 5 | read_to_string, |
| 6 | tokens, |
| 7 | }; |
| 8 | |
| 9 | use oxedyne_fe2o3_core::prelude::*; |
| 10 | |
| 11 | /// Cumulative byte and packet counters for one interface. |
| 12 | #[derive(Clone, Debug, Default, PartialEq)] |
| 13 | pub struct NetLine { |
| 14 | /// Interface name, e.g. `lo`, `eth0`, `wlp4s0`. |
| 15 | pub name: String, |
| 16 | /// Cumulative bytes received. |
| 17 | pub rx_bytes: u64, |
| 18 | /// Cumulative packets received. |
| 19 | pub rx_packets:u64, |
| 20 | /// Cumulative receive errors. |
| 21 | pub rx_errors: u64, |
| 22 | /// Cumulative receive packets dropped. |
| 23 | pub rx_drops: u64, |
| 24 | /// Cumulative bytes transmitted. |
| 25 | pub tx_bytes: u64, |
| 26 | /// Cumulative packets transmitted. |
| 27 | pub tx_packets:u64, |
| 28 | /// Cumulative transmit errors. |
| 29 | pub tx_errors: u64, |
| 30 | /// Cumulative transmit packets dropped. |
| 31 | pub tx_drops: u64, |
| 32 | } |
| 33 | |
| 34 | /// Collection of per-interface counters. |
| 35 | #[derive(Clone, Debug, Default, PartialEq)] |
| 36 | pub struct NetStats { |
| 37 | pub interfaces: Vec<NetLine>, |
| 38 | } |
| 39 | |
| 40 | impl NetStats { |
| 41 | /// Read `/proc/net/dev`. |
| 42 | pub fn sample() -> Outcome<Self> { |
| 43 | let content = res!(read_to_string("/proc/net/dev")); |
| 44 | Self::from_net_dev(&content) |
| 45 | } |
| 46 | |
| 47 | /// Parse a `/proc/net/dev` body. The first two lines are |
| 48 | /// header rows describing the column groups; we skip them. |
| 49 | pub fn from_net_dev(content: &str) -> Outcome<Self> { |
| 50 | let mut out = Self::default(); |
| 51 | for line in content.lines().skip(2) { |
| 52 | let (name_part, rest) = match line.split_once(':') { |
| 53 | Some(t) => t, |
| 54 | None => continue, |
| 55 | }; |
| 56 | let toks = tokens(rest); |
| 57 | // 16 columns: rx (bytes packets errs drop fifo frame |
| 58 | // compressed multicast) then tx (same layout). |
| 59 | if toks.len() < 16 { |
| 60 | continue; |
| 61 | } |
| 62 | out.interfaces.push(NetLine { |
| 63 | name: name_part.trim().to_string(), |
| 64 | rx_bytes: res!(parse_num::<u64>(toks[0], "net.rx_bytes")), |
| 65 | rx_packets: res!(parse_num::<u64>(toks[1], "net.rx_packets")), |
| 66 | rx_errors: res!(parse_num::<u64>(toks[2], "net.rx_errors")), |
| 67 | rx_drops: res!(parse_num::<u64>(toks[3], "net.rx_drops")), |
| 68 | tx_bytes: res!(parse_num::<u64>(toks[8], "net.tx_bytes")), |
| 69 | tx_packets: res!(parse_num::<u64>(toks[9], "net.tx_packets")), |
| 70 | tx_errors: res!(parse_num::<u64>(toks[10], "net.tx_errors")), |
| 71 | tx_drops: res!(parse_num::<u64>(toks[11], "net.tx_drops")), |
| 72 | }); |
| 73 | } |
| 74 | Ok(out) |
| 75 | } |
| 76 | |
| 77 | /// Per-interface throughput between two samples. |
| 78 | pub fn deltas(&self, prev: &Self, elapsed_s: f64) -> Vec<NetDelta> { |
| 79 | let mut out = Vec::with_capacity(self.interfaces.len()); |
| 80 | for iface in &self.interfaces { |
| 81 | let p = prev.interfaces.iter().find(|i| i.name == iface.name); |
| 82 | let p = match p { |
| 83 | Some(p) => p, |
| 84 | None => continue, |
| 85 | }; |
| 86 | let rx = iface.rx_bytes.saturating_sub(p.rx_bytes); |
| 87 | let tx = iface.tx_bytes.saturating_sub(p.tx_bytes); |
| 88 | let (rxps, txps) = if elapsed_s > 0.0 { |
| 89 | (rx as f64 / elapsed_s, tx as f64 / elapsed_s) |
| 90 | } else { |
| 91 | (0.0, 0.0) |
| 92 | }; |
| 93 | out.push(NetDelta { |
| 94 | name: iface.name.clone(), |
| 95 | rx_bps: rxps, |
| 96 | tx_bps: txps, |
| 97 | }); |
| 98 | } |
| 99 | out |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | /// Per-interface throughput between two samples. |
| 104 | #[derive(Clone, Debug, Default, PartialEq)] |
| 105 | pub struct NetDelta { |
| 106 | pub name: String, |
| 107 | /// Bytes per second received over the interval. |
| 108 | pub rx_bps: f64, |
| 109 | /// Bytes per second transmitted over the interval. |
| 110 | pub tx_bps: f64, |
| 111 | } |