Adding support for GUI TopologyView to visualize port packet stats as an alternative to port byte stats.

Change-Id: I323840c4fe98009759646eed0c4c66fa2bad0e61
This commit is contained in:
Thomas Vachuska 2017-03-30 13:28:49 -07:00 committed by Simon Hunt
parent d821b18cab
commit 0932ac5e56
4 changed files with 58 additions and 15 deletions

View File

@ -25,12 +25,32 @@ import org.onosproject.net.statistic.Load;
@Beta @Beta
public interface PortStatisticsService { public interface PortStatisticsService {
/** Specifies the type of metric. */
enum MetricType {
/** Load is to be given in bytes/second. */
BYTES,
/** Load is to be given in packets/second. */
PACKETS
}
/** /**
* Obtain the egress load for the given port. * Obtain the egress load for the given port in terms of bytes per second.
* *
* @param connectPoint the port to query * @param connectPoint the port to query
* @return egress traffic load * @return egress traffic load
*/ */
Load load(ConnectPoint connectPoint); Load load(ConnectPoint connectPoint);
/**
* Obtain the egress load for the given port in terms of the specified metric.
*
* @param connectPoint the port to query
* @param metricType metric type
* @return egress traffic load
*/
default Load load(ConnectPoint connectPoint, MetricType metricType) {
return load(connectPoint);
}
} }

View File

@ -75,21 +75,28 @@ public class PortStatisticsManager implements PortStatisticsService {
@Override @Override
public Load load(ConnectPoint connectPoint) { public Load load(ConnectPoint connectPoint) {
return load(connectPoint, MetricType.BYTES);
}
@Override
public Load load(ConnectPoint connectPoint, MetricType metricType) {
DataPoint c = current.get(connectPoint); DataPoint c = current.get(connectPoint);
DataPoint p = previous.get(connectPoint); DataPoint p = previous.get(connectPoint);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (c != null && p != null && (now - c.time < STALE_LIMIT)) { if (c != null && p != null && (now - c.time < STALE_LIMIT)) {
if (c.time > p.time + SECOND) { if (c.time > p.time + SECOND) {
long cve = getEgressValue(c.stats, metricType);
long cvi = getIngressValue(c.stats, metricType);
long pve = getEgressValue(p.stats, metricType);
long pvi = getIngressValue(p.stats, metricType);
//Use max of either Tx or Rx load as the total load of a port //Use max of either Tx or Rx load as the total load of a port
Load load = null; Load load = null;
if (c.stats.bytesSent() >= p.stats.bytesSent()) { if (cve >= pve) {
load = new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), load = new DefaultLoad(cve, pve, (int) (c.time - p.time) / SECOND);
(int) (c.time - p.time) / SECOND);
} }
if (c.stats.bytesReceived() >= p.stats.bytesReceived()) { if (cvi >= pvi) {
Load rcvLoad = new DefaultLoad(c.stats.bytesReceived(), p.stats.bytesReceived(), Load rcvLoad = new DefaultLoad(cvi, pvi, (int) (c.time - p.time) / SECOND);
(int) (c.time - p.time) / SECOND);
load = ((load == null) || (rcvLoad.rate() > load.rate())) ? rcvLoad : load; load = ((load == null) || (rcvLoad.rate() > load.rate())) ? rcvLoad : load;
} }
return load; return load;
@ -98,6 +105,14 @@ public class PortStatisticsManager implements PortStatisticsService {
return null; return null;
} }
private long getEgressValue(PortStatistics stats, MetricType metricType) {
return metricType == MetricType.BYTES ? stats.bytesSent() : stats.packetsSent();
}
private long getIngressValue(PortStatistics stats, MetricType metricType) {
return metricType == MetricType.BYTES ? stats.bytesReceived() : stats.packetsReceived();
}
// Monitors port stats update messages. // Monitors port stats update messages.
private class InternalDeviceListener implements DeviceListener { private class InternalDeviceListener implements DeviceListener {
@Override @Override

View File

@ -18,6 +18,7 @@
package org.onosproject.ui.impl; package org.onosproject.ui.impl;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.onosproject.incubator.net.PortStatisticsService.MetricType;
import org.onosproject.net.Device; import org.onosproject.net.Device;
import org.onosproject.net.DeviceId; import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId; import org.onosproject.net.ElementId;
@ -67,10 +68,10 @@ import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import static org.onosproject.incubator.net.PortStatisticsService.MetricType.BYTES;
import static org.onosproject.incubator.net.PortStatisticsService.MetricType.PACKETS;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink; import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.ui.impl.TrafficMonitor.Mode.IDLE; import static org.onosproject.ui.impl.TrafficMonitor.Mode.*;
import static org.onosproject.ui.impl.TrafficMonitor.Mode.RELATED_INTENTS;
import static org.onosproject.ui.impl.TrafficMonitor.Mode.SELECTED_INTENT;
/** /**
* Encapsulates the behavior of monitoring specific traffic patterns. * Encapsulates the behavior of monitoring specific traffic patterns.
@ -372,7 +373,9 @@ public class TrafficMonitor extends AbstractTopoMonitor {
if (type == StatsType.FLOW_STATS) { if (type == StatsType.FLOW_STATS) {
attachFlowLoad(tlink); attachFlowLoad(tlink);
} else if (type == StatsType.PORT_STATS) { } else if (type == StatsType.PORT_STATS) {
attachPortLoad(tlink); attachPortLoad(tlink, BYTES);
} else if (type == StatsType.PORT_PACKET_STATS) {
attachPortLoad(tlink, PACKETS);
} }
// we only want to report on links deemed to have traffic // we only want to report on links deemed to have traffic
@ -483,14 +486,14 @@ public class TrafficMonitor extends AbstractTopoMonitor {
link.addLoad(getLinkFlowLoad(link.two())); link.addLoad(getLinkFlowLoad(link.two()));
} }
private void attachPortLoad(TrafficLink link) { private void attachPortLoad(TrafficLink link, MetricType metricType) {
// For bi-directional traffic links, use // For bi-directional traffic links, use
// the max link rate of either direction // the max link rate of either direction
// (we choose 'one' since we know that is never null) // (we choose 'one' since we know that is never null)
Link one = link.one(); Link one = link.one();
Load egressSrc = servicesBundle.portStatsService().load(one.src()); Load egressSrc = servicesBundle.portStatsService().load(one.src(), metricType);
Load egressDst = servicesBundle.portStatsService().load(one.dst()); Load egressDst = servicesBundle.portStatsService().load(one.dst(), metricType);
link.addLoad(maxLoad(egressSrc, egressDst), BPS_THRESHOLD); link.addLoad(maxLoad(egressSrc, egressDst), metricType == BYTES ? BPS_THRESHOLD : 0);
// link.addLoad(maxLoad(egressSrc, egressDst), 10); // DEBUG ONLY!! // link.addLoad(maxLoad(egressSrc, egressDst), 10); // DEBUG ONLY!!
} }

View File

@ -242,6 +242,11 @@ public class TrafficLink extends BiLink {
*/ */
PORT_STATS, PORT_STATS,
/**
* Number of packets per second.
*/
PORT_PACKET_STATS,
/** /**
* Custom tagged information. * Custom tagged information.
*/ */