package com.slamd.resourcemonitor.netstat; import com.slamd.stat.LongValueTracker; import java.util.List; import java.util.ArrayList; /** * Abstract class that encapsulates most of the common data processing for * network interface statistics. */ public abstract class InterfaceStatistics { // Name used to refer to an "aggragete" interface that captures statistics // for multiple network interfaces. public static final String AGGREGATE_INTERFACE_NAME = "aggregate"; // Network interface name. private final String name; // Tracker for number of bytes received by the interface. protected final LongValueTracker receivedBytes; // Tracker for number of bytes sent by the interface. protected final LongValueTracker sentBytes; // Collected received bytes values. protected final List<Long> rawReceivedBytes = new ArrayList<Long>(); // Collected sent bytes values. protected final List<Long> rawSentBytes = new ArrayList<Long>(); // A flag that indicates whether we will try to report real-time statistics. protected boolean enableRealTimeStats = false; /** * Constructs statistics for an interface. * * @param name interface name * @param receivedBytes received bytes tracker * @param sentBytes sent bytes tracker */ public InterfaceStatistics( String name, LongValueTracker receivedBytes, LongValueTracker sentBytes) { this.name = name; this.receivedBytes = receivedBytes; this.sentBytes = sentBytes; } /** * Returns the name of the interface. * * @return the name of the interface. */ final String getName() { return name; } /** * Returns the received bytes tracker. * * @return the received bytes tracker. */ final public LongValueTracker getReceivedBytes() { return receivedBytes; } /** * Returns the sent bytes tracker. * * @return the sent bytes tracker. */ final public LongValueTracker getSentBytes() { return sentBytes; } /** * Enables real time statistics collection. */ final public void enableRealTimeStats() { this.enableRealTimeStats = true; } /** * Completes the processing of network interface statistics. Called at the * end of the monitoring cycle. */ final void completeCollection() { final long[] rxArray = new long[this.rawReceivedBytes.size()]; final long[] txArray = new long[this.rawSentBytes.size()]; final int[] countArray = new int[this.rawReceivedBytes.size()]; for (int i=0; i < rxArray.length; i++) { long bytesReceived = this.rawReceivedBytes.get(i); if (bytesReceived < 0) { // We got a negative value, which could be the result of an internal // counter rolling over. Just take the previous value if possible, or // zero if there is no previous value. if (i > 0) { bytesReceived = rxArray[i-1]; } else { bytesReceived = 0; } } rxArray[i] = bytesReceived; long bytesTransmitted = this.rawSentBytes.get(i); if (bytesTransmitted < 0) { // We got a negative value, which could be the result of an internal // counter rolling over. Just take the previous value if possible, or // zero if there is no previous value. if (i > 0) { bytesTransmitted = txArray[i-1]; } else { bytesTransmitted = 0; } } txArray[i] = bytesTransmitted; countArray[i] = 1; } this.receivedBytes.setIntervalData(rxArray, countArray); this.sentBytes.setIntervalData(txArray, countArray); } /** * Records the number of sent bytes to the interface statistics. The * statistics may not be applied until {@link #completeIteration()} is * called. * * @param value number of bytes sent */ abstract void recordSentValue(long value); /** * Records the number of received bytes to the interface statistics. The * statistics may not be applied until {@link #completeIteration()} is * called. * * @param value number of bytes received */ abstract void recordReceivedValue(long value); /** * Completes any processing necessary to complete an iteration. An iteration * ends after both {@link #recordSentValue(long)} and * {@link #recordReceivedValue(long)} have been invoked. */ abstract void completeIteration(); }