I’ve recently been playing around with wmii, a very minimal window manager for Linux. It uses a virtual filesystem to allow third party scripts to interact with it, in the style of procfs or Plan 9. ruby-wmii is just such a system for Ruby, and I’ve been spending an interesting time trying it out.
I’m not sure whether I like wmii yet, but I’m willing to give it a chance. It’s very minimal, but it’s nice to be able to have windows automatically tile, and I rather wish there were some way of doing it in GNOME or KDE. Maybe I’ll come to like the minimalism as well, but for now it seems there are a few things missing that could be rather useful.
One of these useful but missing things is a way to monitor network traffic, but it’s not too hard to add it. I’m just surprised that someone hasn’t created a plugin for it already. Briefly, then, here’s the class I use to poll for traffic information…
class NetworkMonitor def initialize @traffic = read_traffic @time = Time.now end def poll new_traffic = read_traffic new_time = Time.now # Calculate difference between traffic records traffic_diff = @traffic.merge(new_traffic) { |dev, before, after| { :recv => (after[:recv] - before[:recv]) / (new_time - @time), :sent => (after[:sent] - before[:sent]) / (new_time - @time) } } # Update records @time = new_time @traffic.update(new_traffic) return traffic_diff end protected def read_traffic traffic = {} File.open "/proc/net/dev" do |file| # Remove header file.gets; file.gets # Parse lines file.each do |line| dev, data = line.split /:/ data = data.strip.split /\s+/ traffic[dev.strip] = { :recv => data[0].to_i, :sent => data[8].to_i } end end return traffic end end
And here’s the code for the bar applet I use to display the information in wmii:
bar_applet("network-traffic", 100) do |wmii, bar| monitor = NetworkMonitor.new address = "weavejester@weavejester.com:network-traffic" devices = wmii.plugin_config[address]["devices"] || ["wlan0"] format = wmii.plugin_config[address]["format"] format ||= lambda do |dev, recv, sent| sprintf "R %.2fK, S %.2fK", recv / 1024.0, sent / 1024.0 end Thread.new do loop do text = "" for dev in devices data = monitor.poll[dev] text << format[dev, data[:recv], data[:sent]] end bar.data = text sleep 1 end end end