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/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