Netstats

The next part excites me, I’ve been working on this code on different occasions for some years now. This post is a cross-posting, it lay ground for the Grafana infrastructure that I’m using and taught me a lot about data, rust and how to get the data to render. While it is not directly related to the PV topic itself, it is worth taking the time to consider the lesson to be learned here.

When I realized, that the hack with bash was very ineffective, I was thinking, what could I do instead? Normally, I would have done something tougher with Python. However, running python on an embedded device is terrible. The Router of mine has 16Mbyte of storage on a NAND flash. The default python installation requires around 50 MB.

Behold! There is an embedded version of python! Yeah… but this take also at least 15 MB. The base image requires more than one MB to get started. So python wasn’t an option. The same is true for ruby, Perl and other languages with an interpreter. They just don’t do it.

At the time, I was helping to teach computer security in the university and many students there were talking about rust. After a lecture, I got curious and started to learn about it. Back then I didn’t had any problem that could be solved with it.

For an Android project I need to have an API for my HTTP service running. Hence, I’ve tried to use rust with rocket.rs[] for this. However, I failed because I didn’t had the necessary skills in rust to get it running.

Fast forwarding some months to my problem with the Router and the interface data. Once, I’ve realized the terrible hack I did, rust seem just as a naturally choice to me here.

Step by step

The first prototype was just if I’m able to read a file. I’ve started to read the hostname and boy, that was different. In someway, you’re reminded to C, yet it is not C. The underlying logic is, the handling logic is not.

However, at the time, I had to write Java Code for an Android project and Rust seemed so much of a better language to me. The thing about this statement is, I can not even argument why this is. It just feels so much better to me than any language I’ve used so far. WTF?

Once I’ve read the hostname of proc, I moved on to the network interface file in proc. This turned our to be more different, because you need to write a parse to handle the different interfaces.

The PoC looked like this:

pub fn read_traffic_file() -> Vec<String> {
  let mut f = File::open("/proc/net/dev").unwrap();

  let mut data_to_return: Vec<String> =  Vec::new();
  let mut buffer = String::new();
  let mut new_data: String = String::new();
  f.read_to_string(&mut buffer).unwrap();
  // This can be done by the line() function
  // https://doc.rust-lang.org/std/string/struct.String.html#method.lines
  let mut data: Vec<&str> = buffer.split("\n").collect();

  // Cleanup the Vector, remove unnecessary lines
  data.reverse();
  data.pop();
  data.pop();
  data.reverse();
  data.pop();


  // At this point out Vec only contains interface parameters.
  for line in 0..data.len()  {
    new_data = clean_up(data[line]).clone();
    data_to_return.push(new_data);
  }
  //println!("{}", new_data);
  data_to_return
}




fn main() {
    
    let mut interface_data: Vec<String> = read_traffic_file(); 

    for interface in 0..interface_data.len(){
      extract_interface_data(interface_data[interface].as_str());
    }
    let now_in_s = get_unix_time();
    println!("{:?}", now_in_s);
    let hostname = get_hostname();
    println!("{:?}", hostname);

The code wasn’t good, nor something to be proud of. However, it did work and that was mattered to me.

One of the bigger problem that then occurred to me was the formatting of the data. Here is the lesson: make sure that you format the in the correct order. Somehow I mixed up the date and the bytes and was wondering why nothing was showing in the graph…

So far,

akendo

[] https://rocket.rs/