Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

以前、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 より機能が豊富。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした