LoginSignup
10
9

More than 5 years have passed since last update.

Linuxでネットワークインタフェースの活動状況を調べる by Rust

Last updated at Posted at 2018-09-25

以前、Linuxでネットワークインタフェースの活動状況を調べる by Golang という記事を書いたのですが、最近Rustを勉強し始めたので、同様のものをRustで書いてみました。

やっていること

/sys/class/net/<network_if>/statistics/ から受信、送信の累計のバイト数がわかるので、周期的にそれを表示しています。

ソースをここに貼ります。

main.rs
use std::env;
use std::fs;
extern crate chrono;
extern crate schedule_recv;
use schedule_recv::periodic_ms;

fn read_transfer_bytes(f: &str) -> u64 {
    match fs::read_to_string(f) {
        Ok(s) => s.trim().parse().unwrap_or(0),
        Err(err) => {
            panic!("Failed to read:{} Err={:?}", f, err);
        }
    }
}

fn net_activity(ifname: &str) {
    let interval = 2000;
    let txf = &format!("/sys/class/net/{}/statistics/tx_bytes", ifname);
    let rxf = &format!("/sys/class/net/{}/statistics/rx_bytes", ifname);
    let tick = periodic_ms(interval);
    let mut tx_prev = read_transfer_bytes(txf);
    let mut rx_prev = read_transfer_bytes(rxf);
    let td = interval as f64 * 1e-3;
    loop {
        tick.recv().unwrap();
        let tx = read_transfer_bytes(txf);
        let rx = read_transfer_bytes(rxf);
        println!(
            "t={}, tx={}, rx={}, tx/s={:.1} KB/s, rx/s={:.1} KB/s",
            chrono::Utc::now().timestamp(),
            tx,
            rx,
            ((tx - tx_prev) as f64) / td / 1024f64,
            ((rx - rx_prev) as f64) / td / 1024f64
        );
        tx_prev = tx;
        rx_prev = rx;
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: {} ifname", args[0]);
        eprintln!("  For example, {} eth0", args[0]);
        eprintln!("  You can find ifname by `ls /sys/class/net`");
        return;
    }
    net_activity(&args[1]);
}

Cargo.toml に追加したのは以下の通り。

[dependencies]
schedule_recv = "0.1"
chrono = "0.4"

実行例

$ ls /sys/class/net/
enp0s31f6  enx00051bd1473c  lo  wlp4s0

$ cargo run enp0s31f6
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s                   
     Running `target/debug/net_activity enp0s31f6`
t=1537868984, tx=405623729, rx=98837205807, tx/s=0.0 KB/s, rx/s=0.1 KB/s
t=1537868986, tx=405623729, rx=98837206182, tx/s=0.0 KB/s, rx/s=0.2 KB/s
t=1537868988, tx=405623930, rx=98837208653, tx/s=0.1 KB/s, rx/s=1.2 KB/s
t=1537868990, tx=405624302, rx=98837209502, tx/s=0.2 KB/s, rx/s=0.4 KB/s
^C

メモ

ファイルを一括で読んでStringにするのに、std::fs::read_to_string() というちょうどいいものがあったので、それを使った。

周期的に実行するには、schedule_recvというクレートを使用した。Sleepで待つと少しずつ遅れてしまうので。

タイムスタンプには、chronoというクレートを使用した。std::time::SystemTime より機能が豊富。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9