package org.radargun.sysmonitor; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.concurrent.TimeUnit; import org.radargun.logging.Log; import org.radargun.logging.LogFactory; import org.radargun.reporting.Timeline; /** * Parse the /proc/net/dev file for a value on the specified network interface * * @author Alan Field <afield@redhat.com> */ public class NetworkBytesMonitor implements Monitor { private static final int TRANSMIT_BYTES_INDEX = 8; private static final int RECEIVE_BYTES_INDEX = 0; /** The serialVersionUID */ private static final long serialVersionUID = -260611570251145013L; private static Log log = LogFactory.getLog(NetworkBytesMonitor.class); private final Timeline timeline; private String iface; private int valueIndex = -1; private long previousValue; private long previousTime; private NetworkBytesMonitor(String iface, int valueIndex, Timeline timeline) { this.timeline = timeline; this.iface = iface; this.valueIndex = valueIndex; } public static NetworkBytesMonitor createReceiveMonitor(String iface, Timeline timeline) { return new NetworkBytesMonitor(iface, RECEIVE_BYTES_INDEX, timeline); } public static NetworkBytesMonitor createTransmitMonitor(String iface, Timeline timeline) { return new NetworkBytesMonitor(iface, TRANSMIT_BYTES_INDEX, timeline); } public void run() { try (FileInputStream inputStream = new FileInputStream("/proc/net/dev"); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { try { String line = br.readLine(); while (line != null) { line = line.trim(); if (line.startsWith(iface)) { long now = System.currentTimeMillis(); String[] vals = line.split(":")[1].trim().split("\\s+"); if (previousValue == 0) { timeline.addValue(getCategory(), new Timeline.Value(0)); } else { long bytesSinceLastTime = Long.valueOf(vals[valueIndex]) - previousValue; long trafficPerSecond = bytesSinceLastTime * TimeUnit.SECONDS.toMillis(1) / (now - previousTime); timeline.addValue(getCategory(), new Timeline.Value(trafficPerSecond)); } previousValue = Long.valueOf(vals[valueIndex]); previousTime = now; break; } line = br.readLine(); } } catch (Exception e) { log.error("Exception occurred while reading /proc/net/dev.", e); } } catch (FileNotFoundException e) { log.error("File /proc/net/dev was not found!", e); } catch (IOException e) { log.error("Error while getting input stream", e); } } private Timeline.Category getCategory() { return Timeline.Category.sysCategory(String.format("Network %s on %s [bytes per second]", valueIndex == TRANSMIT_BYTES_INDEX ? "TX" : "RX", iface)); } @Override public void start() { // nothing to do } @Override public void stop() { // nothing to do } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NetworkBytesMonitor that = (NetworkBytesMonitor) o; if (valueIndex != that.valueIndex) return false; if (!iface.equals(that.iface)) return false; return true; } @Override public int hashCode() { int result = iface.hashCode(); result = 31 * result + valueIndex; return result; } }