Additional monitoring stats in server driver
This patch also performs some refactoring to make the
JSON parameters exchanged between the driver and the device
homogeneous (i.e., following the [a-z][A-Z]* pattern).
Code reviewed and minor refactoring.
Avoid exception when timing statistics are not present.
Handle device re-connections.
Server also reports a hardware queue index per core.
Addressed code reviewer's comments.
Change-Id: I6c9d0bbd5884267ee2fdb69bf50809694994c56d
Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java b/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
index 4fffe6e..d1cb020 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/BasicServerDriver.java
@@ -194,6 +194,22 @@
}
/**
+ * Raise a connect event by setting the
+ * activity flag of this device.
+ *
+ * @param device a device to connect
+ */
+ protected void raiseDeviceReconnect(RestSBDevice device) {
+ // Already done!
+ if (device.isActive()) {
+ return;
+ }
+
+ log.debug("Setting device {} active", device.deviceId());
+ device.setActive(true);
+ }
+
+ /**
* Upon a failure to contact a device, the driver
* raises a disconnect event by resetting the
* activity flag of this device.
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
index 10203a3..d52f115 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
@@ -110,8 +110,8 @@
private static final String PARAM_HW_VENDOR = "hwVersion";
private static final String PARAM_SW_VENDOR = "swVersion";
private static final String PARAM_SERIAL = "serial";
- private static final String PARAM_TIMING_STATS = "timing_stats";
- private static final String PARAM_TIMING_AUTOSCALE = "autoscale_timing_stats";
+ private static final String PARAM_TIMING_STATS = "timingStats";
+ private static final String PARAM_TIMING_AUTOSCALE = "autoScaleTimingStats";
private static final String NIC_PARAM_NAME = "name";
private static final String NIC_PARAM_PORT_INDEX = "index";
@@ -137,20 +137,29 @@
/**
* CPU statistics.
*/
- private static final String CPU_PARAM_ID = "id";
- private static final String CPU_PARAM_VENDOR = "vendor";
- private static final String CPU_PARAM_FREQUENCY = "frequency";
- private static final String CPU_PARAM_LOAD = "load";
- private static final String CPU_PARAM_STATUS = "busy";
- private static final String CPU_STATS_BUSY_CPUS = "busyCpus";
- private static final String CPU_STATS_FREE_CPUS = "freeCpus";
+ private static final String CPU_PARAM_ID = "id";
+ private static final String CPU_PARAM_VENDOR = "vendor";
+ private static final String CPU_PARAM_FREQUENCY = "frequency";
+ private static final String CPU_PARAM_LOAD = "load";
+ private static final String CPU_PARAM_QUEUE = "queue";
+ private static final String CPU_PARAM_STATUS = "busy";
+ private static final String CPU_PARAM_THROUGHPUT = "throughput";
+ private static final String CPU_PARAM_LATENCY = "latency";
+ private static final String MON_PARAM_UNIT = "unit";
+ private static final String MON_PARAM_BUSY_CPUS = "busyCpus";
+ private static final String MON_PARAM_FREE_CPUS = "freeCpus";
+ private static final String MON_PARAM_MIN = "min";
+ private static final String MON_PARAM_AVERAGE = "average";
+ private static final String MON_PARAM_MEDIAN = "median";
+ private static final String MON_PARAM_MAX = "max";
/**
* Timing statistics.
*/
- private static final String TIMING_PARAM_PARSE = "parse";
- private static final String TIMING_PARAM_LAUNCH = "launch";
- private static final String TIMING_PARAM_AUTOSCALE = "autoscale";
+ private static final String TIMING_PARAM_PARSE = "parseTime";
+ private static final String TIMING_PARAM_LAUNCH = "launchTime";
+ private static final String TIMING_PARAM_DEPLOY = "deployTime";
+ private static final String TIMING_PARAM_AUTOSCALE = "autoScaleTime";
/**
* Auxiliary constants.
@@ -350,6 +359,9 @@
);
checkNotNull(dev, DEVICE_NULL);
+ // Set alive
+ raiseDeviceReconnect(dev);
+
// Updates the controller with the complete device information
getController().removeDevice(deviceId);
getController().addDevice((RestSBDevice) dev);
@@ -512,7 +524,7 @@
* @param deviceId the device ID to be queried
* @return global monitoring statistics
*/
- private MonitoringStatistics getGlobalMonitoringStatistics(DeviceId deviceId) {
+ public MonitoringStatistics getGlobalMonitoringStatistics(DeviceId deviceId) {
// Monitoring statistics to return
MonitoringStatistics monStats = null;
@@ -562,8 +574,8 @@
}
// Get high-level CPU statistics
- int busyCpus = objNode.path(CPU_STATS_BUSY_CPUS).asInt();
- int freeCpus = objNode.path(CPU_STATS_FREE_CPUS).asInt();
+ int busyCpus = objNode.path(MON_PARAM_BUSY_CPUS).asInt();
+ int freeCpus = objNode.path(MON_PARAM_FREE_CPUS).asInt();
// Get a list of CPU statistics per core
Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);
@@ -581,11 +593,13 @@
statsBuilder.setDeviceId(deviceId)
.setTimingStatistics(timinsgStats)
.setCpuStatistics(cpuStats)
- .setNicStatistics(nicStats)
- .build();
+ .setNicStatistics(nicStats);
monStats = statsBuilder.build();
+ // When a device reports monitoring data, it means it is alive
+ raiseDeviceReconnect(device);
+
log.debug("Global monitoring statistics: {}", monStats.toString());
return monStats;
@@ -689,11 +703,13 @@
statsBuilder.setDeviceId(deviceId)
.setTimingStatistics(timinsgStats)
.setCpuStatistics(cpuStats)
- .setNicStatistics(nicStats)
- .build();
+ .setNicStatistics(nicStats);
monStats = statsBuilder.build();
+ // When a device reports monitoring data, it means it is alive
+ raiseDeviceReconnect(device);
+
log.debug("Monitoring statistics: {}", monStats.toString());
return monStats;
@@ -720,22 +736,62 @@
for (JsonNode cn : cpuNode) {
ObjectNode cpuObjNode = (ObjectNode) cn;
+ // CPU statistics builder
+ DefaultCpuStatistics.Builder cpuBuilder = DefaultCpuStatistics.builder();
+
+ // Throughput statistics are optional
+ JsonNode throughputNode = cpuObjNode.get(CPU_PARAM_THROUGHPUT);
+ if (throughputNode != null) {
+ String throughputUnit = get(throughputNode, MON_PARAM_UNIT);
+ if (!Strings.isNullOrEmpty(throughputUnit)) {
+ cpuBuilder.setThroughputUnit(throughputUnit);
+ }
+ float averageThroughput = (float) 0;
+ if (throughputNode.get(MON_PARAM_AVERAGE) != null) {
+ averageThroughput = throughputNode.path(MON_PARAM_AVERAGE).floatValue();
+ }
+ cpuBuilder.setAverageThroughput(averageThroughput);
+ }
+
+ // Latency statistics are optional
+ JsonNode latencyNode = cpuObjNode.get(CPU_PARAM_LATENCY);
+ if (latencyNode != null) {
+ String latencyUnit = get(latencyNode, MON_PARAM_UNIT);
+ if (!Strings.isNullOrEmpty(latencyUnit)) {
+ cpuBuilder.setLatencyUnit(latencyUnit);
+ }
+ float minLatency = (float) 0;
+ if (latencyNode.get(MON_PARAM_MIN) != null) {
+ minLatency = latencyNode.path(MON_PARAM_MIN).floatValue();
+ }
+ float medianLatency = (float) 0;
+ if (latencyNode.get(MON_PARAM_MEDIAN) != null) {
+ medianLatency = latencyNode.path(MON_PARAM_MEDIAN).floatValue();
+ }
+ float maxLatency = (float) 0;
+ if (latencyNode.get(MON_PARAM_MAX) != null) {
+ maxLatency = latencyNode.path(MON_PARAM_MAX).floatValue();
+ }
+
+ cpuBuilder.setMinLatency(minLatency)
+ .setMedianLatency(medianLatency)
+ .setMaxLatency(maxLatency);
+ }
+
// CPU ID with its load and status
- int cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
- float cpuLoad = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
+ int cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
+ float cpuLoad = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
+ int queueId = cpuObjNode.path(CPU_PARAM_QUEUE).asInt();
boolean isBusy = cpuObjNode.path(CPU_PARAM_STATUS).booleanValue();
- // Incorporate these statistics into an object
- DefaultCpuStatistics.Builder cpuBuilder =
- DefaultCpuStatistics.builder();
-
+ // This is mandatory information
cpuBuilder.setDeviceId(deviceId)
.setId(cpuId)
.setLoad(cpuLoad)
- .setIsBusy(isBusy)
- .build();
+ .setQueue(queueId)
+ .setIsBusy(isBusy);
- // We have statistics for this CPU core
+ // We have all the statistics for this CPU core
cpuStats.add(cpuBuilder.build());
}
@@ -790,8 +846,7 @@
long txErrors = nicObjNode.path(NIC_STATS_TX_ERRORS).asLong();
// Incorporate these statistics into an object
- DefaultPortStatistics.Builder nicBuilder =
- DefaultPortStatistics.builder();
+ DefaultPortStatistics.Builder nicBuilder = DefaultPortStatistics.builder();
nicBuilder.setDeviceId(deviceId)
.setPort((int) portNumber)
@@ -802,8 +857,7 @@
.setPacketsRxDropped(rxDropped)
.setPacketsRxErrors(rxErrors)
.setPacketsTxDropped(txDropped)
- .setPacketsTxErrors(txErrors)
- .build();
+ .setPacketsTxErrors(txErrors);
// We have statistics for this NIC
nicStats.add(nicBuilder.build());
@@ -813,9 +867,9 @@
}
/**
- * Parse the input JSON object, looking for timing-related
- * statistics. Upon success, construct and return a
- * timing statistics object.
+ * Parse the input JSON object, looking for timing-related statistics.
+ * Upon success, return a timing statistics object with the advertized values.
+ * Upon failure, return a timing statistics object with zero-initialized values.
*
* @param objNode input JSON node with timing statistics information
* @return TimingStatistics object or null
@@ -827,33 +881,56 @@
return timinsgStats;
}
+ // If no timing statistics are present, then send zeros
+ if (objNode.get(PARAM_TIMING_STATS) == null) {
+ return getZeroTimingStatistics();
+ }
+
+ DefaultTimingStatistics.Builder timingBuilder = DefaultTimingStatistics.builder();
+
// Get timing statistics
JsonNode timingNode = objNode.path(PARAM_TIMING_STATS);
ObjectNode timingObjNode = (ObjectNode) timingNode;
+ // The unit of timing statistics
+ String timingStatsUnit = get(timingNode, MON_PARAM_UNIT);
+ if (!Strings.isNullOrEmpty(timingStatsUnit)) {
+ timingBuilder.setUnit(timingStatsUnit);
+ }
+
// Time (ns) to parse the controller's deployment instruction
- long parsingTime = timingObjNode.path(TIMING_PARAM_PARSE).asLong();
+ long parsingTime = 0;
+ if (timingObjNode.get(TIMING_PARAM_PARSE) != null) {
+ parsingTime = timingObjNode.path(TIMING_PARAM_PARSE).asLong();
+ }
// Time (ns) to do the deployment
- long launchingTime = timingObjNode.path(TIMING_PARAM_LAUNCH).asLong();
- // Total time (ns)
- long totalTime = parsingTime + launchingTime;
+ long launchingTime = 0;
+ if (timingObjNode.get(TIMING_PARAM_LAUNCH) != null) {
+ launchingTime = timingObjNode.path(TIMING_PARAM_LAUNCH).asLong();
+ }
+ // Deployment time (ns) equals to time to parse + time to launch
+ long deployTime = 0;
+ if (timingObjNode.get(TIMING_PARAM_DEPLOY) != null) {
+ deployTime = timingObjNode.path(TIMING_PARAM_DEPLOY).asLong();
+ }
+ checkArgument(deployTime == parsingTime + launchingTime, "Inconsistent timing statistics");
+
+ timingBuilder.setParsingTime(parsingTime)
+ .setLaunchingTime(launchingTime);
// Get autoscale timing statistics
JsonNode autoscaleTimingNode = objNode.path(PARAM_TIMING_AUTOSCALE);
+ if (autoscaleTimingNode == null) {
+ return timingBuilder.build();
+ }
+
ObjectNode autoscaleTimingObjNode = (ObjectNode) autoscaleTimingNode;
-
// Time (ns) to autoscale a server's load
- long autoscaleTime = autoscaleTimingObjNode.path(
- TIMING_PARAM_AUTOSCALE
- ).asLong();
-
- DefaultTimingStatistics.Builder timingBuilder =
- DefaultTimingStatistics.builder();
-
- timingBuilder.setParsingTime(parsingTime)
- .setLaunchingTime(launchingTime)
- .setAutoscaleTime(autoscaleTime)
- .build();
+ long autoscaleTime = 0;
+ if (autoscaleTimingObjNode.get(TIMING_PARAM_AUTOSCALE) != null) {
+ autoscaleTimingObjNode.path(TIMING_PARAM_AUTOSCALE).asLong();
+ }
+ timingBuilder.setAutoscaleTime(autoscaleTime);
return timingBuilder.build();
}
@@ -866,13 +943,11 @@
* @return TimingStatistics object
*/
private TimingStatistics getZeroTimingStatistics() {
- DefaultTimingStatistics.Builder zeroTimingBuilder =
- DefaultTimingStatistics.builder();
+ DefaultTimingStatistics.Builder zeroTimingBuilder = DefaultTimingStatistics.builder();
zeroTimingBuilder.setParsingTime(0)
.setLaunchingTime(0)
- .setAutoscaleTime(0)
- .build();
+ .setAutoscaleTime(0);
return zeroTimingBuilder.build();
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
index f9c1989..2f5305d 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
@@ -17,10 +17,15 @@
package org.onosproject.drivers.server.impl.stats;
import org.onosproject.drivers.server.stats.CpuStatistics;
+import org.onosproject.drivers.server.stats.MonitoringUnit;
import org.onosproject.net.DeviceId;
import com.google.common.base.MoreObjects;
+import java.util.Optional;
+
+import static org.onosproject.drivers.server.stats.MonitoringUnit.LatencyUnit;
+import static org.onosproject.drivers.server.stats.MonitoringUnit.ThroughputUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
@@ -32,6 +37,9 @@
private static final float MIN_CPU_LOAD = (float) 0.0;
private static final float MAX_CPU_LOAD = (float) 1.0;
+ private static final LatencyUnit DEF_LATENCY_UNIT = LatencyUnit.NANO_SECOND;
+ private static final ThroughputUnit DEF_THROUGHPUT_UNIT = ThroughputUnit.MBPS;
+
// Upper limit of CPU cores in one machine
public static final int MAX_CPU_NB = 512;
@@ -39,27 +47,46 @@
private final int id;
private final float load;
+ private final int queue;
private final boolean isBusy;
+ private final Optional<MonitoringUnit> throughputUnit;
+ private final Optional<Float> averageThroughput;
+ private final Optional<MonitoringUnit> latencyUnit;
+ private final Optional<Float> minLatency;
+ private final Optional<Float> medianLatency;
+ private final Optional<Float> maxLatency;
- private DefaultCpuStatistics(
- DeviceId deviceId,
- int id,
- float load,
- boolean isBusy) {
+ private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, boolean isBusy) {
+ this(deviceId, id, load, queue, isBusy, null, -1, null, -1, -1, -1);
+ }
+
+ private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, boolean isBusy,
+ MonitoringUnit throughputUnit, float averageThroughput, MonitoringUnit latencyUnit,
+ float minLatency, float medianLatency, float maxLatency) {
checkNotNull(deviceId, "Device ID is NULL");
- checkArgument(
- (id >= 0) && (id < MAX_CPU_NB),
- "Invalid CPU core ID " + String.valueOf(id) + ", not in [0, " + String.valueOf(MAX_CPU_NB - 1) + "]"
- );
- checkArgument(
- (load >= MIN_CPU_LOAD) && (load <= MAX_CPU_LOAD),
- "Invalid CPU load " + Float.toString(load) + ", not in [" + MIN_CPU_LOAD + ", " + MAX_CPU_LOAD + "]"
- );
+ checkArgument((id >= 0) && (id < MAX_CPU_NB),
+ "Invalid CPU core ID " + String.valueOf(id) + ", not in [0, " + String.valueOf(MAX_CPU_NB - 1) + "]");
+ checkArgument((load >= MIN_CPU_LOAD) && (load <= MAX_CPU_LOAD),
+ "Invalid CPU load " + Float.toString(load) + ", not in [" + MIN_CPU_LOAD + ", " + MAX_CPU_LOAD + "]");
this.deviceId = deviceId;
this.id = id;
this.load = load;
+ this.queue = queue;
this.isBusy = isBusy;
+
+ this.throughputUnit = (throughputUnit == null) ?
+ Optional.empty() : Optional.ofNullable(throughputUnit);
+ this.averageThroughput = (averageThroughput < 0) ?
+ Optional.empty() : Optional.ofNullable(averageThroughput);
+ this.latencyUnit = (latencyUnit == null) ?
+ Optional.empty() : Optional.ofNullable(latencyUnit);
+ this.minLatency = (minLatency < 0) ?
+ Optional.empty() : Optional.ofNullable(minLatency);
+ this.medianLatency = (medianLatency < 0) ?
+ Optional.empty() : Optional.ofNullable(medianLatency);
+ this.maxLatency = (maxLatency < 0) ?
+ Optional.empty() : Optional.ofNullable(maxLatency);
}
// Constructor for serializer
@@ -67,7 +94,15 @@
this.deviceId = null;
this.id = 0;
this.load = 0;
+ this.queue = 0;
this.isBusy = false;
+
+ this.throughputUnit = null;
+ this.averageThroughput = null;
+ this.latencyUnit = null;
+ this.minLatency = null;
+ this.medianLatency = null;
+ this.maxLatency = null;
}
/**
@@ -90,18 +125,60 @@
}
@Override
+ public int queue() {
+ return this.queue;
+ }
+
+ @Override
public boolean busy() {
return this.isBusy;
}
@Override
+ public Optional<MonitoringUnit> throughputUnit() {
+ return this.throughputUnit;
+ }
+
+ @Override
+ public Optional<Float> averageThroughput() {
+ return this.averageThroughput;
+ }
+
+ @Override
+ public Optional<MonitoringUnit> latencyUnit() {
+ return this.latencyUnit;
+ }
+
+ @Override
+ public Optional<Float> minLatency() {
+ return this.minLatency;
+ }
+
+ @Override
+ public Optional<Float> medianLatency() {
+ return this.medianLatency;
+ }
+
+ @Override
+ public Optional<Float> maxLatency() {
+ return this.maxLatency;
+ }
+
+ @Override
public String toString() {
return MoreObjects.toStringHelper(this)
.omitNullValues()
.add("device", deviceId)
.add("id", id())
.add("load", load())
+ .add("queue", queue())
.add("isBusy", busy())
+ .add("throughputUnit", throughputUnit.orElse(null))
+ .add("averageThroughput", averageThroughput.orElse(null))
+ .add("latencyUnit", latencyUnit.orElse(null))
+ .add("minLatency", minLatency.orElse(null))
+ .add("medianLatency", medianLatency.orElse(null))
+ .add("maxLatency", maxLatency.orElse(null))
.toString();
}
@@ -109,8 +186,16 @@
DeviceId deviceId;
int id;
- float load;
- boolean isBusy;
+ float load = 0;
+ int queue = -1;
+ boolean isBusy = false;
+
+ MonitoringUnit throughputUnit = DEF_THROUGHPUT_UNIT;
+ float averageThroughput = -1;
+ MonitoringUnit latencyUnit = DEF_LATENCY_UNIT;
+ float minLatency = -1;
+ float medianLatency = -1;
+ float maxLatency = -1;
private Builder() {
@@ -131,7 +216,7 @@
/**
* Sets the CPU ID.
*
- * @param id the CPU ID
+ * @param id CPU ID
* @return builder object
*/
public Builder setId(int id) {
@@ -153,6 +238,18 @@
}
/**
+ * Sets the hardware queue ID associated with this core.
+ *
+ * @param queue hardware queue ID
+ * @return builder object
+ */
+ public Builder setQueue(int queue) {
+ this.queue = queue;
+
+ return this;
+ }
+
+ /**
* Sets the CPU status (free or busy).
*
* @param isBusy CPU status
@@ -165,17 +262,87 @@
}
/**
+ * Sets the throughput unit.
+ *
+ * @param throughputUnitStr throughput unit as a string
+ * @return builder object
+ */
+ public Builder setThroughputUnit(String throughputUnitStr) {
+ this.throughputUnit = ThroughputUnit.getByName(throughputUnitStr);
+
+ return this;
+ }
+
+ /**
+ * Sets the average throughput.
+ *
+ * @param averageThroughput average throughput
+ * @return builder object
+ */
+ public Builder setAverageThroughput(float averageThroughput) {
+ this.averageThroughput = averageThroughput;
+
+ return this;
+ }
+
+ /**
+ * Sets the latency unit.
+ *
+ * @param latencyUnitStr latency unit as a string
+ * @return builder object
+ */
+ public Builder setLatencyUnit(String latencyUnitStr) {
+ this.latencyUnit = LatencyUnit.getByName(latencyUnitStr);
+
+ return this;
+ }
+
+ /**
+ * Sets the minimum latency.
+ *
+ * @param minLatency minimum latency
+ * @return builder object
+ */
+ public Builder setMinLatency(float minLatency) {
+ this.minLatency = minLatency;
+
+ return this;
+ }
+
+ /**
+ * Sets the median latency.
+ *
+ * @param medianLatency median latency
+ * @return builder object
+ */
+ public Builder setMedianLatency(float medianLatency) {
+ this.medianLatency = medianLatency;
+
+ return this;
+ }
+
+ /**
+ * Sets the maximum latency.
+ *
+ * @param maxLatency maximum latency
+ * @return builder object
+ */
+ public Builder setMaxLatency(float maxLatency) {
+ this.maxLatency = maxLatency;
+
+ return this;
+ }
+
+ /**
* Creates a DefaultCpuStatistics object.
*
* @return DefaultCpuStatistics object
*/
public DefaultCpuStatistics build() {
return new DefaultCpuStatistics(
- deviceId,
- id,
- load,
- isBusy
- );
+ deviceId, id, load, queue, isBusy,
+ throughputUnit, averageThroughput,
+ latencyUnit, minLatency, medianLatency, maxLatency);
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
index 8256c5f..0fe253d 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
@@ -16,29 +16,39 @@
package org.onosproject.drivers.server.impl.stats;
+import org.onosproject.drivers.server.stats.MonitoringUnit;
import org.onosproject.drivers.server.stats.TimingStatistics;
+import com.google.common.base.Strings;
import com.google.common.base.MoreObjects;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.drivers.server.stats.MonitoringUnit.LatencyUnit;
/**
* Default implementation for timing statistics.
*/
public final class DefaultTimingStatistics implements TimingStatistics {
+ private static final LatencyUnit DEF_UNIT = LatencyUnit.NANO_SECOND;
+
+ private final MonitoringUnit unit;
private final long deployCommandParsingTime;
private final long deployCommandLaunchingTime;
private long autoscaleTime;
private DefaultTimingStatistics(
+ MonitoringUnit unit,
long parsingTime,
long launchingTime,
long autoscaleTime) {
+ checkNotNull(unit, "Time statistics unit is null");
checkArgument(parsingTime >= 0, "Parsing time is negative");
checkArgument(launchingTime >= 0, "Launching time is negative");
checkArgument(autoscaleTime >= 0, "Autoscale time is negative");
+ this.unit = unit;
this.deployCommandParsingTime = parsingTime;
this.deployCommandLaunchingTime = launchingTime;
this.autoscaleTime = autoscaleTime;
@@ -46,6 +56,7 @@
// Constructor for serializer
private DefaultTimingStatistics() {
+ this.unit = null;
this.deployCommandParsingTime = 0;
this.deployCommandLaunchingTime = 0;
this.autoscaleTime = 0;
@@ -61,6 +72,11 @@
}
@Override
+ public MonitoringUnit unit() {
+ return this.unit;
+ }
+
+ @Override
public long deployCommandParsingTime() {
return this.deployCommandParsingTime;
}
@@ -84,15 +100,17 @@
public String toString() {
return MoreObjects.toStringHelper(this)
.omitNullValues()
- .add("parsing", this.deployCommandParsingTime())
- .add("launching", this.deployCommandLaunchingTime())
- .add("total", this.totalDeploymentTime())
- .add("autoscale", this.autoscaleTime())
+ .add("unit", this.unit().toString())
+ .add("parsingTime", this.deployCommandParsingTime())
+ .add("launchingTime", this.deployCommandLaunchingTime())
+ .add("deploymentTime", this.totalDeploymentTime())
+ .add("autoScaleTime", this.autoscaleTime())
.toString();
}
public static final class Builder {
+ MonitoringUnit unit = DEF_UNIT;
long deployCommandParsingTime;
long deployCommandLaunchingTime;
long autoscaleTime;
@@ -102,6 +120,20 @@
}
/**
+ * Sets time statistics unit.
+ *
+ * @param unitStr time statistics unit as a string
+ * @return builder object
+ */
+ public Builder setUnit(String unitStr) {
+ if (!Strings.isNullOrEmpty(unitStr)) {
+ this.unit = LatencyUnit.getByName(unitStr);
+ }
+
+ return this;
+ }
+
+ /**
* Sets parsing time.
*
* @param parsingTime parsing time
@@ -144,6 +176,7 @@
*/
public DefaultTimingStatistics build() {
return new DefaultTimingStatistics(
+ unit,
deployCommandParsingTime,
deployCommandLaunchingTime,
autoscaleTime
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
index 9ea22b3..f30134d 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
@@ -16,6 +16,8 @@
package org.onosproject.drivers.server.stats;
+import java.util.Optional;
+
/**
* CPU statistics API.
*/
@@ -38,10 +40,63 @@
float load();
/**
+ * Returns the hardware queue identifier associated with this CPU core.
+ *
+ * @return hardware queue identifier
+ */
+ int queue();
+
+ /**
* Returns the status (true=busy, false=free) of a CPU core.
*
* @return boolean CPU core status
*/
boolean busy();
+ /**
+ * Returns the unit of throughput values.
+ *
+ * @return throughput monitoring unit
+ */
+ Optional<MonitoringUnit> throughputUnit();
+
+ /**
+ * Returns the average throughput of this CPU core,
+ * expressed in throughputUnit() monitoring units.
+ *
+ * @return average throughput of a CPU core
+ */
+ Optional<Float> averageThroughput();
+
+ /**
+ * Returns the unit of latency values.
+ *
+ * @return latency monitoring unit
+ */
+ Optional<MonitoringUnit> latencyUnit();
+
+ /**
+ * Returns the minimum latency incurred by a CPU core,
+ * expressed in latencyUnit() monitoring units.
+ *
+ * @return minimum latency incurred by a CPU core
+ */
+ Optional<Float> minLatency();
+
+ /**
+ * Returns the median latency incurred by a CPU core,
+ * expressed in latencyUnit() monitoring units.
+ *
+ * @return median latency incurred by a CPU core
+ */
+ Optional<Float> medianLatency();
+
+ /**
+ * Returns the maximum latency incurred by a CPU core,
+ * expressed in latencyUnit() monitoring units.
+ *
+ * @return maximum latency incurred by a CPU core
+ */
+ Optional<Float> maxLatency();
+
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java
new file mode 100644
index 0000000..0528a69
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/MonitoringUnit.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.server.stats;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Representation of a monitoring unit.
+ */
+public interface MonitoringUnit {
+
+ /**
+ * Throughput-related monitoring units.
+ */
+ public enum ThroughputUnit implements MonitoringUnit {
+
+ BPS("bps"),
+ KBPS("kbps"),
+ MBPS("mbps"),
+ GBPS("gbps");
+
+ private String throughputUnit;
+
+ // Statically maps throughput monitoring units to enum types
+ private static final Map<String, MonitoringUnit> MAP =
+ new HashMap<String, MonitoringUnit>();
+ static {
+ for (ThroughputUnit tu : ThroughputUnit.values()) {
+ MAP.put(tu.toString().toLowerCase(), (MonitoringUnit) tu);
+ }
+ }
+
+ private ThroughputUnit(String throughputUnit) {
+ this.throughputUnit = throughputUnit;
+ }
+
+ public static MonitoringUnit getByName(String tu) {
+ tu = tu.toLowerCase();
+ return MAP.get(tu);
+ }
+
+ @Override
+ public String toString() {
+ return this.throughputUnit;
+ }
+
+ };
+
+ /**
+ * Latency-related monitoring units.
+ */
+ public enum LatencyUnit implements MonitoringUnit {
+
+ NANO_SECOND("ns"),
+ MICRO_SECOND("us"),
+ MILLI_SECOND("ms"),
+ SECOND("s");
+
+ private String latencyUnit;
+
+ // Statically maps latency monitoring units to enum types
+ private static final Map<String, MonitoringUnit> MAP =
+ new HashMap<String, MonitoringUnit>();
+ static {
+ for (LatencyUnit lu : LatencyUnit.values()) {
+ MAP.put(lu.toString().toLowerCase(), (MonitoringUnit) lu);
+ }
+ }
+
+ private LatencyUnit(String latencyUnit) {
+ this.latencyUnit = latencyUnit;
+ }
+
+ public static MonitoringUnit getByName(String lu) {
+ lu = lu.toLowerCase();
+ return MAP.get(lu);
+ }
+
+ @Override
+ public String toString() {
+ return this.latencyUnit;
+ }
+
+ };
+
+ String toString();
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
index 102b186..9cf46dd 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/TimingStatistics.java
@@ -22,6 +22,13 @@
public interface TimingStatistics {
/**
+ * Returns the unit of timing statistics.
+ *
+ * @return timing statistics' unit
+ */
+ MonitoringUnit unit();
+
+ /**
* Time (ns) to parse the controller's deployment instruction.
*
* @return time in nanoseconds to parse a 'deploy' command