From 2cb1aee696251b6a61205023aa94143e3b42af57 Mon Sep 17 00:00:00 2001 From: Subrata Banerjee <subrata.banerjee@bigswitch.com> Date: Thu, 12 Jan 2012 01:30:01 -0800 Subject: [PATCH] Cleanup of performance monitoring, custom json serializers, and CLI display support. --- .../core/web/JacksonCustomConverter.java | 5 + .../serializers/OFMatchJSONSerializer.java | 42 +- .../OFPhysicalPortJSONSerializer.java | 2 +- ...MonCumulativeTimeBucketJSONSerializer.java | 60 +++ ...PerfMonOneComponentTimeJSONSerializer.java | 45 ++ .../perfmon/CumulativeTimeBucket.java | 205 ++++++++++ .../perfmon/OneComponentTime.java | 68 +++ .../perfmon/PktinProcessingTime.java | 386 ++++-------------- 8 files changed, 502 insertions(+), 311 deletions(-) create mode 100644 src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonCumulativeTimeBucketJSONSerializer.java create mode 100644 src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonOneComponentTimeJSONSerializer.java create mode 100644 src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java create mode 100644 src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java diff --git a/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java b/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java index 452d6f1de..a9de95bf3 100644 --- a/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java +++ b/src/main/java/net/floodlightcontroller/core/web/JacksonCustomConverter.java @@ -24,6 +24,8 @@ import net.floodlightcontroller.core.web.serializers.EventHistoryBaseInfoJSONSer import net.floodlightcontroller.core.web.serializers.OFFeaturesReplyJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFMatchJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFPhysicalPortJSONSerializer; +import net.floodlightcontroller.core.web.serializers.PerfMonCumulativeTimeBucketJSONSerializer; +import net.floodlightcontroller.core.web.serializers.PerfMonOneComponentTimeJSONSerializer; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.Version; @@ -62,6 +64,9 @@ public class JacksonCustomConverter extends JacksonConverter { jsonModule.addSerializer(new EventHistoryBaseInfoJSONSerializer()); jsonModule.addSerializer( new EventHistoryAttachmentPointJSONSerializer()); + jsonModule.addSerializer(new PerfMonOneComponentTimeJSONSerializer()); + jsonModule.addSerializer( + new PerfMonCumulativeTimeBucketJSONSerializer()); jsonObjectMapper.registerModule(jsonModule); } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java index 42693c8a0..303750c4d 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFMatchJSONSerializer.java @@ -39,32 +39,46 @@ public class OFMatchJSONSerializer extends JsonSerializer<OFMatch> { ((i >> 8 ) & 0xFF) + "." + ( i & 0xFF); } - + /** * Performs the serialization of a OFMatch object */ @Override - public void serialize(OFMatch match, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException { + public void serialize(OFMatch match, JsonGenerator jGen, + SerializerProvider serializer) + throws IOException, JsonProcessingException { jGen.writeStartObject(); - jGen.writeStringField("dataLayerDestination", HexString.toHexString(match.getDataLayerDestination())); - jGen.writeStringField("dataLayerSource", HexString.toHexString(match.getDataLayerSource())); + jGen.writeStringField("dataLayerDestination", + HexString.toHexString(match.getDataLayerDestination())); + jGen.writeStringField("dataLayerSource", + HexString.toHexString(match.getDataLayerSource())); String dataType = Integer.toHexString(match.getDataLayerType()); while (dataType.length() < 4) { dataType = "0".concat(dataType); } jGen.writeStringField("dataLayerType", "0x" + dataType); - jGen.writeNumberField("dataLayerVirtualLan", match.getDataLayerVirtualLan()); - jGen.writeNumberField("dataLayerVirtualLanPriorityCodePoint", match.getDataLayerVirtualLanPriorityCodePoint()); - jGen.writeStringField("inputSwitch", HexString.toHexString(match.getSwitchDataPathId())); + jGen.writeNumberField("dataLayerVirtualLan", + match.getDataLayerVirtualLan()); + jGen.writeNumberField("dataLayerVirtualLanPriorityCodePoint", + match.getDataLayerVirtualLanPriorityCodePoint()); + jGen.writeStringField("inputSwitch", + HexString.toHexString(match.getSwitchDataPathId())); jGen.writeNumberField("inputPort", match.getInputPort()); - jGen.writeStringField("networkDestination", intToIp(match.getNetworkDestination())); - jGen.writeNumberField("networkDestinationMaskLen", match.getNetworkDestinationMaskLen()); + jGen.writeStringField("networkDestination", + intToIp(match.getNetworkDestination())); + jGen.writeNumberField("networkDestinationMaskLen", + match.getNetworkDestinationMaskLen()); jGen.writeNumberField("networkProtocol", match.getNetworkProtocol()); - jGen.writeStringField("networkSource", intToIp(match.getNetworkSource())); - jGen.writeNumberField("networkSourceMaskLen", match.getNetworkSourceMaskLen()); - jGen.writeNumberField("networkTypeOfService", match.getNetworkTypeOfService()); - jGen.writeNumberField("transportDestination", match.getTransportDestination()); - jGen.writeNumberField("transportSource", match.getTransportSource()); + jGen.writeStringField("networkSource", + intToIp(match.getNetworkSource())); + jGen.writeNumberField("networkSourceMaskLen", + match.getNetworkSourceMaskLen()); + jGen.writeNumberField("networkTypeOfService", + match.getNetworkTypeOfService()); + jGen.writeNumberField("transportDestination", + match.getTransportDestination()); + jGen.writeNumberField("transportSource", + match.getTransportSource()); jGen.writeNumberField("wildcards", match.getWildcards()); jGen.writeEndObject(); } diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFPhysicalPortJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFPhysicalPortJSONSerializer.java index 66f24c063..5500f49d8 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFPhysicalPortJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFPhysicalPortJSONSerializer.java @@ -45,7 +45,7 @@ public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures()); jGen.writeEndObject(); } - + /** * Tells SimpleModule that we are the serializer for OFPhysicalPort */ diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonCumulativeTimeBucketJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonCumulativeTimeBucketJSONSerializer.java new file mode 100644 index 000000000..5c07f8737 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonCumulativeTimeBucketJSONSerializer.java @@ -0,0 +1,60 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; +import java.sql.Timestamp; + +import net.floodlightcontroller.perfmon.CumulativeTimeBucket; +import net.floodlightcontroller.perfmon.OneComponentTime; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; + +public class PerfMonCumulativeTimeBucketJSONSerializer + extends JsonSerializer<CumulativeTimeBucket> { + /** + * Performs the serialization of a OneComponentTime object + */ + @Override + public void serialize(CumulativeTimeBucket cTB, + JsonGenerator jGen, + SerializerProvider serializer) + throws IOException, JsonProcessingException { + // Skip if the number of packets processed is zero + if (cTB.getTotalPktCnt() != 0) { + jGen.writeStartObject(); + jGen.writeNumberField("BktNo", cTB.getBucketNo()); + Timestamp ts = new Timestamp(cTB.getStartTime_ms()); + String tsStr = ts.toString(); + while (tsStr.length() < 23) { + tsStr = tsStr.concat("0"); + } + jGen.writeStringField("StartTime", tsStr); + jGen.writeNumberField("Duration", cTB.getDuration_s()); + jGen.writeNumberField("TotPkts", cTB.getTotalPktCnt()); + jGen.writeNumberField("Avg", cTB.getAvgTotalProcTime_us()); + jGen.writeNumberField("Min", cTB.getMinTotalProcTime_us()); + jGen.writeNumberField("Max", cTB.getMaxTotalProcTime_us()); + jGen.writeNumberField("StdDev", cTB.getSigmaTotalProcTime_us()); + int numComps = cTB.getNumComps(); + for (int idx=0; idx < numComps; idx++) { + OneComponentTime oCT = cTB.getTComps().getOneComp()[idx]; + if (oCT.getPktCnt() != 0) { + serializer.defaultSerializeField( + Integer.toString(idx), oCT, jGen); + } + } + + jGen.writeEndObject(); + } + } + + /** + * Tells SimpleModule that we are the serializer for OFMatch + */ + @Override + public Class<CumulativeTimeBucket> handledType() { + return CumulativeTimeBucket.class; + } +} diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonOneComponentTimeJSONSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonOneComponentTimeJSONSerializer.java new file mode 100644 index 000000000..5afe36c6d --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/PerfMonOneComponentTimeJSONSerializer.java @@ -0,0 +1,45 @@ +package net.floodlightcontroller.core.web.serializers; + +import java.io.IOException; + +import net.floodlightcontroller.perfmon.OneComponentTime; + +import org.codehaus.jackson.JsonGenerator; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonSerializer; +import org.codehaus.jackson.map.SerializerProvider; + +public class PerfMonOneComponentTimeJSONSerializer + extends JsonSerializer<OneComponentTime> { + /** + * Performs the serialization of a OneComponentTime object + */ + @Override + public void serialize(OneComponentTime oCT, + JsonGenerator jGen, + SerializerProvider serializer) + throws IOException, JsonProcessingException { + // Skip if the number of packets processed is zero + if (oCT.getPktCnt() != 0) { + jGen.writeStartObject(); // Called from higher layer + jGen.writeStringField("CompName", oCT.getCompName()); + jGen.writeNumberField("Pkts", oCT.getPktCnt()); + jGen.writeNumberField("Avg", oCT.getAvgProcTime_us()); + jGen.writeNumberField("Max", oCT.getMaxProcTime_us()); + jGen.writeNumberField("Min", oCT.getMinProcTime_us()); + jGen.writeNumberField("StdDev", oCT.getSigmaProcTime_us()); + //jGen.writeNumberField("Sum", oCT.getSumProcTime_us()); + //jGen.writeNumberField("SumSq", oCT.getSumSquaredProcTime_us2()); + jGen.writeEndObject(); + } + } + + /** + * Tells SimpleModule that we are the serializer for OFMatch + */ + @Override + public Class<OneComponentTime> handledType() { + return OneComponentTime.class; + } +} + diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java new file mode 100644 index 000000000..9af4ba196 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java @@ -0,0 +1,205 @@ +package net.floodlightcontroller.perfmon; + +import net.floodlightcontroller.core.IOFMessageListener.FlListenerID; + +public class CumulativeTimeBucket { + int bucketNo; + long startTime_ms; + long startTime_ns; // First pkt time-stamp in this bucket + // duration for which pkts are put into this bucket in seconds + int duration_s; + ProcTime tComps; // processing times of each component + int totalPktCnt; + int totalSumProcTime_us; // total processing time for one pkt in + long totalSumSquaredProcTime_us; + int maxTotalProcTime_us; + int minTotalProcTime_us; + int avgTotalProcTime_us; + int sigmaTotalProcTime_us; // std. deviation + int numComps; + + public int getBucketNo() { + return bucketNo; + } + + public void setBucketNo(int bucketNo) { + this.bucketNo = bucketNo; + } + + public long getStartTime_ms() { + return startTime_ms; + } + + public void setStartTime_ms(long startTime_ms) { + this.startTime_ms = startTime_ms; + } + + public long getStartTime_ns() { + return startTime_ns; + } + + public void setStartTime_ns(long startTime_ns) { + this.startTime_ns = startTime_ns; + } + + public int getDuration_s() { + return duration_s; + } + + public void setDuration_s(int duration_s) { + this.duration_s = duration_s; + } + + public ProcTime getTComps() { + return tComps; + } + + public void setTComps(ProcTime tComps) { + this.tComps = tComps; + } + + public int getTotalPktCnt() { + return totalPktCnt; + } + + public void setTotalPktCnt(int totalPktCnt) { + this.totalPktCnt = totalPktCnt; + } + + public int getTotalSumProcTime_us() { + return totalSumProcTime_us; + } + + public void setTotalSumProcTime_us(int totalSumProcTime_us) { + this.totalSumProcTime_us = totalSumProcTime_us; + } + + public Long getTotalSumSquaredProcTime_us() { + return totalSumSquaredProcTime_us; + } + + public void setTotalSumSquaredProcTime_us( + Long totalSumSquaredProcTime_us) { + this.totalSumSquaredProcTime_us = totalSumSquaredProcTime_us; + } + + public int getMaxTotalProcTime_us() { + return maxTotalProcTime_us; + } + + public void setMaxTotalProcTime_us(int maxTotalProcTime_us) { + this.maxTotalProcTime_us = maxTotalProcTime_us; + } + + public int getMinTotalProcTime_us() { + return minTotalProcTime_us; + } + + public void setMinTotalProcTime_us(int minTotalProcTime_us) { + this.minTotalProcTime_us = minTotalProcTime_us; + } + + public int getAvgTotalProcTime_us() { + return avgTotalProcTime_us; + } + + public void setAvgTotalProcTime_us(int avgTotalProcTime_us) { + this.avgTotalProcTime_us = avgTotalProcTime_us; + } + + public int getSigmaTotalProcTime_us() { + return sigmaTotalProcTime_us; + } + + public void setSigmaTotalProcTime_us(int sigmaTotalProcTime_us) { + this.sigmaTotalProcTime_us = sigmaTotalProcTime_us; + } + + public ProcTime gettComps() { + return tComps; + } + + public void settComps(ProcTime tComps) { + this.tComps = tComps; + } + + public int getNumComps() { + return numComps; + } + + public void setNumComps(int numComps) { + this.numComps = numComps; + } + + public void setTotalSumSquaredProcTime_us(long totalSumSquaredProcTime_us) { + this.totalSumSquaredProcTime_us = totalSumSquaredProcTime_us; + } + + public class ProcTime { + OneComponentTime [] oneComp; + + public OneComponentTime[] getOneComp() { + return oneComp; + } + + public void setOneComp(OneComponentTime[] oneComp) { + this.oneComp = oneComp; + } + + public ProcTime(int numComponents) { + oneComp = new OneComponentTime[numComponents]; + for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; + idx < numComponents; idx++) { + oneComp[idx] = new OneComponentTime(); + // Initialize the min and max values; + oneComp[idx].maxProcTime_us = Integer.MIN_VALUE; + oneComp[idx].minProcTime_us = Integer.MAX_VALUE; + // Set the component id and name + oneComp[idx].setCompId(idx); + oneComp[idx].setCompName( + FlListenerID.getListenerNameFromId(idx)); + } + } + } + + public CumulativeTimeBucket(int numComponents) { + duration_s = 0; + maxTotalProcTime_us = Integer.MIN_VALUE; + minTotalProcTime_us = Integer.MAX_VALUE; + tComps = new ProcTime(numComponents); + numComps = numComponents; + } + + // Initialize the time bucket so that it can be reused for the next + // interval, thus not + // creating lots of garbage + public void initializeCumulativeTimeBucket( + CumulativeTimeBucket cumulativeTimeBkt) { + assert(cumulativeTimeBkt != null); + if (cumulativeTimeBkt == null) { + return; + } + + cumulativeTimeBkt.startTime_ms = System.currentTimeMillis(); + cumulativeTimeBkt.startTime_ns = System.nanoTime(); + cumulativeTimeBkt.duration_s = 0; + cumulativeTimeBkt.totalPktCnt = 0; + cumulativeTimeBkt.totalSumProcTime_us = 0; + cumulativeTimeBkt.totalSumSquaredProcTime_us = 0L; + cumulativeTimeBkt.maxTotalProcTime_us = Integer.MIN_VALUE; + cumulativeTimeBkt.minTotalProcTime_us = Integer.MAX_VALUE; + cumulativeTimeBkt.avgTotalProcTime_us = 0; + cumulativeTimeBkt.sigmaTotalProcTime_us = 0; + for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; + idx <= PktinProcessingTime.BB_LAST_LISTENER_ID; idx++) { + OneComponentTime oct = cumulativeTimeBkt.tComps.oneComp[idx]; + oct.pktCnt = 0; + oct.sumProcTime_us = 0; + oct.sumSquaredProcTime_us2 = 0; + oct.maxProcTime_us = Integer.MIN_VALUE; + oct.minProcTime_us = Integer.MAX_VALUE; + oct.avgProcTime_us = 0; + oct.sigmaProcTime_us = 0; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java b/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java new file mode 100644 index 000000000..db29813e8 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java @@ -0,0 +1,68 @@ +package net.floodlightcontroller.perfmon; + +public class OneComponentTime { + int compId; + String compName; + int pktCnt; + int sumProcTime_us; + long sumSquaredProcTime_us2; + int maxProcTime_us; + int minProcTime_us; + int avgProcTime_us; + int sigmaProcTime_us; // std. deviation + + public int getCompId() { + return compId; + } + public void setCompId(int compId) { + this.compId = compId; + } + public String getCompName() { + return compName; + } + public void setCompName(String compName) { + this.compName = compName; + } + public int getPktCnt() { + return pktCnt; + } + public void setPktCnt(int pktCnt) { + this.pktCnt = pktCnt; + } + public int getSumProcTime_us() { + return sumProcTime_us; + } + public void setSumProcTime_us(int sumProcTime_us) { + this.sumProcTime_us = sumProcTime_us; + } + public long getSumSquaredProcTime_us2() { + return sumSquaredProcTime_us2; + } + public void setSumSquaredProcTime_us2(long sumSquaredProcTime_us2) { + this.sumSquaredProcTime_us2 = sumSquaredProcTime_us2; + } + public int getMaxProcTime_us() { + return maxProcTime_us; + } + public void setMaxProcTime_us(int maxProcTime_us) { + this.maxProcTime_us = maxProcTime_us; + } + public int getMinProcTime_us() { + return minProcTime_us; + } + public void setMinProcTime_us(int minProcTime_us) { + this.minProcTime_us = minProcTime_us; + } + public int getAvgProcTime_us() { + return avgProcTime_us; + } + public void setAvgProcTime_us(int avgProcTime_us) { + this.avgProcTime_us = avgProcTime_us; + } + public int getSigmaProcTime_us() { + return sigmaProcTime_us; + } + public void setSigmaProcTime_us(int sigmaProcTime_us) { + this.sigmaProcTime_us = sigmaProcTime_us; + } +} \ No newline at end of file diff --git a/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java b/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java index e68ed34c9..40074a3b9 100644 --- a/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java +++ b/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java @@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory; * */ public class PktinProcessingTime { - + /*** * This class contains a set of buckets (called time buckets as the * primarily contain 'times' that are used in a circular way to @@ -38,24 +38,24 @@ public class PktinProcessingTime { * syslog is generated instead * */ - + protected static Logger logger = LoggerFactory.getLogger(PktinProcessingTime.class); - + /*** * procTimeMonitoringState: true if monitoring is on, default is false * this variable is controller using a cli under the controller node * (config-controller)> [no] performance-monitor processing-time */ - + public class PerfMonConfigs { // overall performance monitoring knob; turned off by default protected boolean procTimeMonitoringState; // overall per-component performance monitoring knob; off by default - protected boolean procTimePerCompMonitoringState; + protected boolean procTimePerCompMonitoringState; // knob for database performance monitoring protected boolean dbTimePerfMonState; - + public boolean isProcTimeMonitoringState() { return procTimeMonitoringState; } @@ -77,14 +77,14 @@ public class PktinProcessingTime { public void setDbTimePerfMonState(boolean dbTimePerfMonState) { this.dbTimePerfMonState = dbTimePerfMonState; } - + public PerfMonConfigs() { procTimeMonitoringState = false; procTimePerCompMonitoringState = false; dbTimePerfMonState = false; } } - + protected PerfMonConfigs perfMonCfgs; // Maintains the time when the last packet was processed protected long lastPktTime_ns; @@ -92,141 +92,75 @@ public class PktinProcessingTime { // Time bucket created once and reused as needed public CumulativeTimeBucket ctb; // Current time bucket being filled public CircularTimeBucketSet ctbs; // Set of all time buckets + private int numComponents; + public Long getLastPktTime_ns() { return lastPktTime_ns; } - public void setLastPktTime_ns(Long lastPktTime_ns) { this.lastPktTime_ns = lastPktTime_ns; } - public long getCurBucketStartTime() { return curBucketStartTime; } - public void setCurBucketStartTime(long curBucketStartTime) { this.curBucketStartTime = curBucketStartTime; } - public CumulativeTimeBucket getCtb() { return ctb; } - public void setCtb(CumulativeTimeBucket ctb) { this.ctb = ctb; } - public CircularTimeBucketSet getCtbs() { return ctbs; } - public void setCtbs(CircularTimeBucketSet ctbs) { this.ctbs = ctbs; } - public PerfMonConfigs getPerfMonCfgs() { return perfMonCfgs; } - public void setPerfMonCfgs(PerfMonConfigs perfMonCfgs) { this.perfMonCfgs = perfMonCfgs; } + public int getNumComponents() { + return numComponents; + } + public void setNumComponents(int numComponents) { + this.numComponents = numComponents; + } - public PktinProcessingTime() { + public PktinProcessingTime() { FlListenerID.populateCompNames(); + setNumComponents(BB_LAST_LISTENER_ID + 1); perfMonCfgs = new PerfMonConfigs(); - ctbs = new CircularTimeBucketSet(); + ctbs = new CircularTimeBucketSet(getNumComponents()); ctb = ctbs.timeBucketSet[ctbs.curBucketIdx]; ctb.startTime_ms = System.currentTimeMillis(); - ctb.startTime_ns = System.nanoTime(); + ctb.startTime_ns = System.nanoTime(); } - + /*** * 30 buckets each holding 10s of processing time data, a total * of 30*10s = 5mins of processing time data is maintained */ protected static final long ONE_BUCKET_DURATION_SECONDS_LONG = 10;// seconds protected static final int ONE_BUCKET_DURATION_SECONDS_INT = 10;// seconds - protected static final long ONE_BUCKET_DURATION_NANOSECONDS = + protected static final long ONE_BUCKET_DURATION_NANOSECONDS = ONE_BUCKET_DURATION_SECONDS_LONG * 1000000000; protected static final int BUCKET_SET_SIZE = 30; - protected static final int TOT_PROC_TIME_WARN_THRESHOLD_US = 5000; // ms - protected static final int TOT_PROC_TIME_ALERT_THRESHOLD_US = 10000; // ms, TBD, alert not in logger - + protected static final int TOT_PROC_TIME_WARN_THRESHOLD_US = 5000; // ms + protected static final int TOT_PROC_TIME_ALERT_THRESHOLD_US = 10000; + // ms, TBD, alert not in logger + // TBD: Somehow need to get BB last listener id from BB - protected static final int BB_LAST_LISTENER_ID = 12; - - public class OneComponentTime { - int compId; - String compName; - int pktCnt; - int sumProcTime_us; - long sumSquaredProcTime_us2; - int maxProcTime_us; - int minProcTime_us; - int avgProcTime_us; - int sigmaProcTime_us; // std. deviation - - public int getCompId() { - return compId; - } - public void setCompId(int compId) { - this.compId = compId; - } - public String getCompName() { - return compName; - } - public void setCompName(String compName) { - this.compName = compName; - } - public int getPktCnt() { - return pktCnt; - } - public void setPktCnt(int pktCnt) { - this.pktCnt = pktCnt; - } - public int getSumProcTime_us() { - return sumProcTime_us; - } - public void setSumProcTime_us(int sumProcTime_us) { - this.sumProcTime_us = sumProcTime_us; - } - public long getSumSquaredProcTime_us2() { - return sumSquaredProcTime_us2; - } - public void setSumSquaredProcTime_us2(long sumSquaredProcTime_us2) { - this.sumSquaredProcTime_us2 = sumSquaredProcTime_us2; - } - public int getMaxProcTime_us() { - return maxProcTime_us; - } - public void setMaxProcTime_us(int maxProcTime_us) { - this.maxProcTime_us = maxProcTime_us; - } - public int getMinProcTime_us() { - return minProcTime_us; - } - public void setMinProcTime_us(int minProcTime_us) { - this.minProcTime_us = minProcTime_us; - } - public int getAvgProcTime_us() { - return avgProcTime_us; - } - public void setAvgProcTime_us(int avgProcTime_us) { - this.avgProcTime_us = avgProcTime_us; - } - public int getSigmaProcTime_us() { - return sigmaProcTime_us; - } - public void setSigmaProcTime_us(int sigmaProcTime_us) { - this.sigmaProcTime_us = sigmaProcTime_us; - } - } - + protected static final int BB_LAST_LISTENER_ID = 12; + public class ProcTime { OneComponentTime [] oneComp; - + public OneComponentTime[] getOneComp() { return oneComp; } @@ -236,8 +170,8 @@ public class PktinProcessingTime { } public ProcTime() { - oneComp = new OneComponentTime[BB_LAST_LISTENER_ID + 1]; - for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; + oneComp = new OneComponentTime[BB_LAST_LISTENER_ID + 1]; + for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; idx <= BB_LAST_LISTENER_ID; idx++) { oneComp[idx] = new OneComponentTime(); // Initialise the min and max values; @@ -250,27 +184,30 @@ public class PktinProcessingTime { } } } - + /*** * This function is called when a packet in processing starts * Check if it is time to go to the next bucket * @param curTime_ns */ - private void checkAndStartNextBucket(Long curTime_ns) { - // We are not running any timer, packet arrivals themselves drive the rotation of the buckets + private void checkAndStartNextBucket(Long curTime_ns) { + // We are not running any timer, packet arrivals themselves drive the + // rotation of the buckets this.lastPktTime_ns = curTime_ns; - if ((curTime_ns - this.ctb.startTime_ns) > ONE_BUCKET_DURATION_NANOSECONDS) { - // Go to next bucket - this.ctbs.fillTimeBucket(); + if ((curTime_ns - this.ctb.startTime_ns) > + ONE_BUCKET_DURATION_NANOSECONDS) { + // Go to next bucket + this.ctbs.fillTimeBucket(); /*** - * We might not have received packets for long time, in which case there would be - * a gap in the start-time of the timer buckets indicating that there was no data - * This should be a better utilization of resources instead of creating several empty + * We might not have received packets for long time, in which case + * there would be a gap in the start-time of the timer buckets + * indicating that there was no data. This should be a better + * utilization of resources instead of creating several empty * buckets. - */ + */ } } - + public long getStartTimeOnePkt() { if (this.perfMonCfgs.procTimeMonitoringState) { long startTime_ns = System.nanoTime(); @@ -279,168 +216,15 @@ public class PktinProcessingTime { } return 0L; } - + // Component refers to software component like forwarding - public long getStartTimeOneComponent() { - if (this.perfMonCfgs.procTimeMonitoringState) { + public long getStartTimeOneComponent() { + if (this.perfMonCfgs.procTimeMonitoringState) { return System.nanoTime(); } return 0L; } - - public class CumulativeTimeBucket { - int bucketNo; - long startTime_ms; - long startTime_ns; // First pkt time-stamp in this bucket - // duration for which pkts are put into this bucket in seconds - int duration_s; - ProcTime tComps; // processing times of each component - int totalPktCnt; - int totalSumProcTime_us; // total processing time for one pkt in - long totalSumSquaredProcTime_us; - int maxTotalProcTime_us; - int minTotalProcTime_us; - int avgTotalProcTime_us; - int sigmaTotalProcTime_us; // std. deviation - - public int getBucketNo() { - return bucketNo; - } - - public void setBucketNo(int bucketNo) { - this.bucketNo = bucketNo; - } - - public long getStartTime_ms() { - return startTime_ms; - } - - public void setStartTime_ms(long startTime_ms) { - this.startTime_ms = startTime_ms; - } - - public long getStartTime_ns() { - return startTime_ns; - } - - public void setStartTime_ns(long startTime_ns) { - this.startTime_ns = startTime_ns; - } - public int getDuration_s() { - return duration_s; - } - - public void setDuration_s(int duration_s) { - this.duration_s = duration_s; - } - - public ProcTime getTComps() { - return tComps; - } - - public void setTComps(ProcTime tComps) { - this.tComps = tComps; - } - - public int getTotalPktCnt() { - return totalPktCnt; - } - - public void setTotalPktCnt(int totalPktCnt) { - this.totalPktCnt = totalPktCnt; - } - - public int getTotalSumProcTime_us() { - return totalSumProcTime_us; - } - - public void setTotalSumProcTime_us(int totalSumProcTime_us) { - this.totalSumProcTime_us = totalSumProcTime_us; - } - - public Long getTotalSumSquaredProcTime_us() { - return totalSumSquaredProcTime_us; - } - - public void setTotalSumSquaredProcTime_us( - Long totalSumSquaredProcTime_us) { - this.totalSumSquaredProcTime_us = totalSumSquaredProcTime_us; - } - - public int getMaxTotalProcTime_us() { - return maxTotalProcTime_us; - } - - public void setMaxTotalProcTime_us(int maxTotalProcTime_us) { - this.maxTotalProcTime_us = maxTotalProcTime_us; - } - - public int getMinTotalProcTime_us() { - return minTotalProcTime_us; - } - - public void setMinTotalProcTime_us(int minTotalProcTime_us) { - this.minTotalProcTime_us = minTotalProcTime_us; - } - - public int getAvgTotalProcTime_us() { - return avgTotalProcTime_us; - } - - public void setAvgTotalProcTime_us(int avgTotalProcTime_us) { - this.avgTotalProcTime_us = avgTotalProcTime_us; - } - - public int getSigmaTotalProcTime_us() { - return sigmaTotalProcTime_us; - } - - public void setSigmaTotalProcTime_us(int sigmaTotalProcTime_us) { - this.sigmaTotalProcTime_us = sigmaTotalProcTime_us; - } - - public CumulativeTimeBucket() { - duration_s = 0; - maxTotalProcTime_us = Integer.MIN_VALUE; - minTotalProcTime_us = Integer.MAX_VALUE; - tComps = new ProcTime(); - } - - // Initialize the time bucket so that it can be reused for the next - // interval, thus not - // creating lots of garbage - public void initializeCumulativeTimeBucket( - CumulativeTimeBucket cumulativeTimeBkt) { - assert(cumulativeTimeBkt != null); - if (cumulativeTimeBkt == null) { - return; - } - - cumulativeTimeBkt.startTime_ms = System.currentTimeMillis(); - cumulativeTimeBkt.startTime_ns = System.nanoTime(); - cumulativeTimeBkt.duration_s = 0; - cumulativeTimeBkt.totalPktCnt = 0; - cumulativeTimeBkt.totalSumProcTime_us = 0; - cumulativeTimeBkt.totalSumSquaredProcTime_us = 0L; - cumulativeTimeBkt.maxTotalProcTime_us = Integer.MIN_VALUE; - cumulativeTimeBkt.minTotalProcTime_us = Integer.MAX_VALUE; - cumulativeTimeBkt.avgTotalProcTime_us = 0; - cumulativeTimeBkt.sigmaTotalProcTime_us = 0; - for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; - idx <= BB_LAST_LISTENER_ID; idx++) { - OneComponentTime oct = cumulativeTimeBkt.tComps.oneComp[idx]; - oct.pktCnt = 0; - oct.sumProcTime_us = 0; - oct.sumSquaredProcTime_us2 = 0; - oct.maxProcTime_us = Integer.MIN_VALUE; - oct.minProcTime_us = Integer.MAX_VALUE; - oct.avgProcTime_us = 0; - oct.sigmaProcTime_us = 0; - } - } - } - public void updateCumulativeTimeOneComp( long onePktOneCompProcTime_ns, int id) { if (this.perfMonCfgs.procTimeMonitoringState) { @@ -449,48 +233,53 @@ public class PktinProcessingTime { OneComponentTime t_temp = this.ctb.tComps.oneComp[id]; t_temp.pktCnt++; t_temp.sumProcTime_us += onePktOneCompProcTime_us; - t_temp.sumSquaredProcTime_us2 += - onePktOneCompProcTime_us * onePktOneCompProcTime_us; - + t_temp.sumSquaredProcTime_us2 += + onePktOneCompProcTime_us * onePktOneCompProcTime_us; if (onePktOneCompProcTime_us > t_temp.maxProcTime_us) { t_temp.maxProcTime_us = onePktOneCompProcTime_us; - } else if (onePktOneCompProcTime_us < t_temp.minProcTime_us) { + } + if (onePktOneCompProcTime_us < t_temp.minProcTime_us) { t_temp.minProcTime_us = onePktOneCompProcTime_us; - } + } } } - + public void updateCumulativeTimeTotal(long onePktStartTime_ns) { if (this.perfMonCfgs.procTimeMonitoringState) { - // There is no api to get time in microseconds, milliseconds is too coarse - // Hence we have to use nanoseconds and then divide by 1000 to get mucroseconds - int onePktProcTime_us = (int)((System.nanoTime() - onePktStartTime_ns) / 1000); + // There is no api to get time in microseconds, milliseconds is + // too coarse hence we have to use nanoseconds and then divide by + // 1000 to get microseconds + int onePktProcTime_us = + (int)((System.nanoTime() - onePktStartTime_ns) / 1000); if (onePktProcTime_us > TOT_PROC_TIME_WARN_THRESHOLD_US) { - logger.warn("Total processing time for one packet exceeded threshold: proc time: {}ms", onePktProcTime_us/1000); + logger.warn("Total processing time for one packet exceeded" + + "threshold: proc time: {}ms", onePktProcTime_us/1000); } this.ctb.totalPktCnt++; this.ctb.totalSumProcTime_us += onePktProcTime_us; - this.ctb.totalSumSquaredProcTime_us += onePktProcTime_us * onePktProcTime_us; - + this.ctb.totalSumSquaredProcTime_us += + onePktProcTime_us * onePktProcTime_us; + if (onePktProcTime_us > this.ctb.maxTotalProcTime_us) { this.ctb.maxTotalProcTime_us = onePktProcTime_us; } else if (onePktProcTime_us < this.ctb.minTotalProcTime_us) { this.ctb.minTotalProcTime_us = onePktProcTime_us; } } - + } - - public class CircularTimeBucketSet { - + + public class CircularTimeBucketSet { + /** * How many timer buckets have valid data, initially it is false then it * stays at true after the circle is completed */ boolean allBucketsValid; int curBucketIdx; // most recent bucket *being* filled + int numComps; CumulativeTimeBucket [] timeBucketSet; - + public boolean isAllBucketsValid() { return allBucketsValid; } @@ -507,6 +296,10 @@ public class PktinProcessingTime { this.curBucketIdx = curBucketIdx; } + public int getNumComps() { + return numComps; + } + public CumulativeTimeBucket[] getTimeBucketSet() { return timeBucketSet; } @@ -521,44 +314,45 @@ public class PktinProcessingTime { Long temp = (long) sum; temp = temp * temp / count; temp = (sumSquared - temp) / count; - return (int) Math.sqrt((double)temp); + return (int) Math.sqrt((double)temp); } - - public CircularTimeBucketSet() { + + public CircularTimeBucketSet(int numComps) { timeBucketSet = new CumulativeTimeBucket[BUCKET_SET_SIZE]; for (int idx= 0; idx < BUCKET_SET_SIZE; idx++) { - timeBucketSet[idx] = new CumulativeTimeBucket(); + timeBucketSet[idx] = new CumulativeTimeBucket(numComps); timeBucketSet[idx].setBucketNo(idx); } - allBucketsValid = false; + allBucketsValid = false; curBucketIdx = 0; + this.numComps = numComps; } - + // Called when the bucket time ends - public void fillTimeBucket() { + public void fillTimeBucket() { // Wrap up computations on the current bucket data - // The following operation can be done in the front end instead of + // The following operation can be done in the front end instead of // here if it turns out to be a performance issue if (ctb.totalPktCnt > 0) { ctb.avgTotalProcTime_us = - ctb.totalSumProcTime_us / ctb.totalPktCnt; + ctb.totalSumProcTime_us / ctb.totalPktCnt; ctb.sigmaTotalProcTime_us = computeSigma(ctb.totalSumProcTime_us, ctb.totalSumSquaredProcTime_us, ctb.totalPktCnt); - + // Find the avg and std. dev. of each component's proc. time for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; idx <= BB_LAST_LISTENER_ID; idx++) { OneComponentTime oct = ctb.tComps.oneComp[idx]; if (oct.pktCnt > 0) { - oct.avgProcTime_us = oct.sumProcTime_us / oct.pktCnt; - oct.sigmaProcTime_us = computeSigma(oct.sumProcTime_us, + oct.avgProcTime_us = oct.sumProcTime_us / oct.pktCnt; + oct.sigmaProcTime_us = computeSigma(oct.sumProcTime_us, oct.sumSquaredProcTime_us2, oct.pktCnt); } } - } + } ctb.duration_s = ONE_BUCKET_DURATION_SECONDS_INT; - + // Move to the new bucket if (curBucketIdx >= BUCKET_SET_SIZE-1) { curBucketIdx = 0; @@ -570,5 +364,5 @@ public class PktinProcessingTime { ctb = timeBucketSet[curBucketIdx]; ctb.initializeCumulativeTimeBucket(ctb); } - } + } } -- GitLab