Skip to content
Snippets Groups Projects
Commit 2cb1aee6 authored by Subrata Banerjee's avatar Subrata Banerjee
Browse files

Cleanup of performance monitoring, custom json serializers, and CLI display support.

parent 80f17738
No related branches found
No related tags found
No related merge requests found
Showing with 502 additions and 311 deletions
...@@ -24,6 +24,8 @@ import net.floodlightcontroller.core.web.serializers.EventHistoryBaseInfoJSONSer ...@@ -24,6 +24,8 @@ import net.floodlightcontroller.core.web.serializers.EventHistoryBaseInfoJSONSer
import net.floodlightcontroller.core.web.serializers.OFFeaturesReplyJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFFeaturesReplyJSONSerializer;
import net.floodlightcontroller.core.web.serializers.OFMatchJSONSerializer; import net.floodlightcontroller.core.web.serializers.OFMatchJSONSerializer;
import net.floodlightcontroller.core.web.serializers.OFPhysicalPortJSONSerializer; 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.JsonFactory;
import org.codehaus.jackson.Version; import org.codehaus.jackson.Version;
...@@ -62,6 +64,9 @@ public class JacksonCustomConverter extends JacksonConverter { ...@@ -62,6 +64,9 @@ public class JacksonCustomConverter extends JacksonConverter {
jsonModule.addSerializer(new EventHistoryBaseInfoJSONSerializer()); jsonModule.addSerializer(new EventHistoryBaseInfoJSONSerializer());
jsonModule.addSerializer( jsonModule.addSerializer(
new EventHistoryAttachmentPointJSONSerializer()); new EventHistoryAttachmentPointJSONSerializer());
jsonModule.addSerializer(new PerfMonOneComponentTimeJSONSerializer());
jsonModule.addSerializer(
new PerfMonCumulativeTimeBucketJSONSerializer());
jsonObjectMapper.registerModule(jsonModule); jsonObjectMapper.registerModule(jsonModule);
} }
......
...@@ -39,32 +39,46 @@ public class OFMatchJSONSerializer extends JsonSerializer<OFMatch> { ...@@ -39,32 +39,46 @@ public class OFMatchJSONSerializer extends JsonSerializer<OFMatch> {
((i >> 8 ) & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." +
( i & 0xFF); ( i & 0xFF);
} }
/** /**
* Performs the serialization of a OFMatch object * Performs the serialization of a OFMatch object
*/ */
@Override @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.writeStartObject();
jGen.writeStringField("dataLayerDestination", HexString.toHexString(match.getDataLayerDestination())); jGen.writeStringField("dataLayerDestination",
jGen.writeStringField("dataLayerSource", HexString.toHexString(match.getDataLayerSource())); HexString.toHexString(match.getDataLayerDestination()));
jGen.writeStringField("dataLayerSource",
HexString.toHexString(match.getDataLayerSource()));
String dataType = Integer.toHexString(match.getDataLayerType()); String dataType = Integer.toHexString(match.getDataLayerType());
while (dataType.length() < 4) { while (dataType.length() < 4) {
dataType = "0".concat(dataType); dataType = "0".concat(dataType);
} }
jGen.writeStringField("dataLayerType", "0x" + dataType); jGen.writeStringField("dataLayerType", "0x" + dataType);
jGen.writeNumberField("dataLayerVirtualLan", match.getDataLayerVirtualLan()); jGen.writeNumberField("dataLayerVirtualLan",
jGen.writeNumberField("dataLayerVirtualLanPriorityCodePoint", match.getDataLayerVirtualLanPriorityCodePoint()); match.getDataLayerVirtualLan());
jGen.writeStringField("inputSwitch", HexString.toHexString(match.getSwitchDataPathId())); jGen.writeNumberField("dataLayerVirtualLanPriorityCodePoint",
match.getDataLayerVirtualLanPriorityCodePoint());
jGen.writeStringField("inputSwitch",
HexString.toHexString(match.getSwitchDataPathId()));
jGen.writeNumberField("inputPort", match.getInputPort()); jGen.writeNumberField("inputPort", match.getInputPort());
jGen.writeStringField("networkDestination", intToIp(match.getNetworkDestination())); jGen.writeStringField("networkDestination",
jGen.writeNumberField("networkDestinationMaskLen", match.getNetworkDestinationMaskLen()); intToIp(match.getNetworkDestination()));
jGen.writeNumberField("networkDestinationMaskLen",
match.getNetworkDestinationMaskLen());
jGen.writeNumberField("networkProtocol", match.getNetworkProtocol()); jGen.writeNumberField("networkProtocol", match.getNetworkProtocol());
jGen.writeStringField("networkSource", intToIp(match.getNetworkSource())); jGen.writeStringField("networkSource",
jGen.writeNumberField("networkSourceMaskLen", match.getNetworkSourceMaskLen()); intToIp(match.getNetworkSource()));
jGen.writeNumberField("networkTypeOfService", match.getNetworkTypeOfService()); jGen.writeNumberField("networkSourceMaskLen",
jGen.writeNumberField("transportDestination", match.getTransportDestination()); match.getNetworkSourceMaskLen());
jGen.writeNumberField("transportSource", match.getTransportSource()); jGen.writeNumberField("networkTypeOfService",
match.getNetworkTypeOfService());
jGen.writeNumberField("transportDestination",
match.getTransportDestination());
jGen.writeNumberField("transportSource",
match.getTransportSource());
jGen.writeNumberField("wildcards", match.getWildcards()); jGen.writeNumberField("wildcards", match.getWildcards());
jGen.writeEndObject(); jGen.writeEndObject();
} }
......
...@@ -45,7 +45,7 @@ public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> ...@@ -45,7 +45,7 @@ public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort>
jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures()); jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures());
jGen.writeEndObject(); jGen.writeEndObject();
} }
/** /**
* Tells SimpleModule that we are the serializer for OFPhysicalPort * Tells SimpleModule that we are the serializer for OFPhysicalPort
*/ */
......
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;
}
}
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;
}
}
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
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
...@@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory; ...@@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
* *
*/ */
public class PktinProcessingTime { public class PktinProcessingTime {
/*** /***
* This class contains a set of buckets (called time buckets as the * This class contains a set of buckets (called time buckets as the
* primarily contain 'times' that are used in a circular way to * primarily contain 'times' that are used in a circular way to
...@@ -38,24 +38,24 @@ public class PktinProcessingTime { ...@@ -38,24 +38,24 @@ public class PktinProcessingTime {
* syslog is generated instead * syslog is generated instead
* *
*/ */
protected static Logger logger = protected static Logger logger =
LoggerFactory.getLogger(PktinProcessingTime.class); LoggerFactory.getLogger(PktinProcessingTime.class);
/*** /***
* procTimeMonitoringState: true if monitoring is on, default is false * procTimeMonitoringState: true if monitoring is on, default is false
* this variable is controller using a cli under the controller node * this variable is controller using a cli under the controller node
* (config-controller)> [no] performance-monitor processing-time * (config-controller)> [no] performance-monitor processing-time
*/ */
public class PerfMonConfigs { public class PerfMonConfigs {
// overall performance monitoring knob; turned off by default // overall performance monitoring knob; turned off by default
protected boolean procTimeMonitoringState; protected boolean procTimeMonitoringState;
// overall per-component performance monitoring knob; off by default // overall per-component performance monitoring knob; off by default
protected boolean procTimePerCompMonitoringState; protected boolean procTimePerCompMonitoringState;
// knob for database performance monitoring // knob for database performance monitoring
protected boolean dbTimePerfMonState; protected boolean dbTimePerfMonState;
public boolean isProcTimeMonitoringState() { public boolean isProcTimeMonitoringState() {
return procTimeMonitoringState; return procTimeMonitoringState;
} }
...@@ -77,14 +77,14 @@ public class PktinProcessingTime { ...@@ -77,14 +77,14 @@ public class PktinProcessingTime {
public void setDbTimePerfMonState(boolean dbTimePerfMonState) { public void setDbTimePerfMonState(boolean dbTimePerfMonState) {
this.dbTimePerfMonState = dbTimePerfMonState; this.dbTimePerfMonState = dbTimePerfMonState;
} }
public PerfMonConfigs() { public PerfMonConfigs() {
procTimeMonitoringState = false; procTimeMonitoringState = false;
procTimePerCompMonitoringState = false; procTimePerCompMonitoringState = false;
dbTimePerfMonState = false; dbTimePerfMonState = false;
} }
} }
protected PerfMonConfigs perfMonCfgs; protected PerfMonConfigs perfMonCfgs;
// Maintains the time when the last packet was processed // Maintains the time when the last packet was processed
protected long lastPktTime_ns; protected long lastPktTime_ns;
...@@ -92,141 +92,75 @@ public class PktinProcessingTime { ...@@ -92,141 +92,75 @@ public class PktinProcessingTime {
// Time bucket created once and reused as needed // Time bucket created once and reused as needed
public CumulativeTimeBucket ctb; // Current time bucket being filled public CumulativeTimeBucket ctb; // Current time bucket being filled
public CircularTimeBucketSet ctbs; // Set of all time buckets public CircularTimeBucketSet ctbs; // Set of all time buckets
private int numComponents;
public Long getLastPktTime_ns() { public Long getLastPktTime_ns() {
return lastPktTime_ns; return lastPktTime_ns;
} }
public void setLastPktTime_ns(Long lastPktTime_ns) { public void setLastPktTime_ns(Long lastPktTime_ns) {
this.lastPktTime_ns = lastPktTime_ns; this.lastPktTime_ns = lastPktTime_ns;
} }
public long getCurBucketStartTime() { public long getCurBucketStartTime() {
return curBucketStartTime; return curBucketStartTime;
} }
public void setCurBucketStartTime(long curBucketStartTime) { public void setCurBucketStartTime(long curBucketStartTime) {
this.curBucketStartTime = curBucketStartTime; this.curBucketStartTime = curBucketStartTime;
} }
public CumulativeTimeBucket getCtb() { public CumulativeTimeBucket getCtb() {
return ctb; return ctb;
} }
public void setCtb(CumulativeTimeBucket ctb) { public void setCtb(CumulativeTimeBucket ctb) {
this.ctb = ctb; this.ctb = ctb;
} }
public CircularTimeBucketSet getCtbs() { public CircularTimeBucketSet getCtbs() {
return ctbs; return ctbs;
} }
public void setCtbs(CircularTimeBucketSet ctbs) { public void setCtbs(CircularTimeBucketSet ctbs) {
this.ctbs = ctbs; this.ctbs = ctbs;
} }
public PerfMonConfigs getPerfMonCfgs() { public PerfMonConfigs getPerfMonCfgs() {
return perfMonCfgs; return perfMonCfgs;
} }
public void setPerfMonCfgs(PerfMonConfigs perfMonCfgs) { public void setPerfMonCfgs(PerfMonConfigs perfMonCfgs) {
this.perfMonCfgs = perfMonCfgs; this.perfMonCfgs = perfMonCfgs;
} }
public int getNumComponents() {
return numComponents;
}
public void setNumComponents(int numComponents) {
this.numComponents = numComponents;
}
public PktinProcessingTime() { public PktinProcessingTime() {
FlListenerID.populateCompNames(); FlListenerID.populateCompNames();
setNumComponents(BB_LAST_LISTENER_ID + 1);
perfMonCfgs = new PerfMonConfigs(); perfMonCfgs = new PerfMonConfigs();
ctbs = new CircularTimeBucketSet(); ctbs = new CircularTimeBucketSet(getNumComponents());
ctb = ctbs.timeBucketSet[ctbs.curBucketIdx]; ctb = ctbs.timeBucketSet[ctbs.curBucketIdx];
ctb.startTime_ms = System.currentTimeMillis(); 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 * 30 buckets each holding 10s of processing time data, a total
* of 30*10s = 5mins of processing time data is maintained * of 30*10s = 5mins of processing time data is maintained
*/ */
protected static final long ONE_BUCKET_DURATION_SECONDS_LONG = 10;// seconds 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 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; ONE_BUCKET_DURATION_SECONDS_LONG * 1000000000;
protected static final int BUCKET_SET_SIZE = 30; 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_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_ALERT_THRESHOLD_US = 10000;
// ms, TBD, alert not in logger
// TBD: Somehow need to get BB last listener id from BB // TBD: Somehow need to get BB last listener id from BB
protected static final int BB_LAST_LISTENER_ID = 12; 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;
}
}
public class ProcTime { public class ProcTime {
OneComponentTime [] oneComp; OneComponentTime [] oneComp;
public OneComponentTime[] getOneComp() { public OneComponentTime[] getOneComp() {
return oneComp; return oneComp;
} }
...@@ -236,8 +170,8 @@ public class PktinProcessingTime { ...@@ -236,8 +170,8 @@ public class PktinProcessingTime {
} }
public ProcTime() { public ProcTime() {
oneComp = new OneComponentTime[BB_LAST_LISTENER_ID + 1]; oneComp = new OneComponentTime[BB_LAST_LISTENER_ID + 1];
for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; for (int idx = FlListenerID.FL_FIRST_LISTENER_ID;
idx <= BB_LAST_LISTENER_ID; idx++) { idx <= BB_LAST_LISTENER_ID; idx++) {
oneComp[idx] = new OneComponentTime(); oneComp[idx] = new OneComponentTime();
// Initialise the min and max values; // Initialise the min and max values;
...@@ -250,27 +184,30 @@ public class PktinProcessingTime { ...@@ -250,27 +184,30 @@ public class PktinProcessingTime {
} }
} }
} }
/*** /***
* This function is called when a packet in processing starts * This function is called when a packet in processing starts
* Check if it is time to go to the next bucket * Check if it is time to go to the next bucket
* @param curTime_ns * @param curTime_ns
*/ */
private void checkAndStartNextBucket(Long curTime_ns) { private void checkAndStartNextBucket(Long curTime_ns) {
// We are not running any timer, packet arrivals themselves drive the rotation of the buckets // We are not running any timer, packet arrivals themselves drive the
// rotation of the buckets
this.lastPktTime_ns = curTime_ns; this.lastPktTime_ns = curTime_ns;
if ((curTime_ns - this.ctb.startTime_ns) > ONE_BUCKET_DURATION_NANOSECONDS) { if ((curTime_ns - this.ctb.startTime_ns) >
// Go to next bucket ONE_BUCKET_DURATION_NANOSECONDS) {
this.ctbs.fillTimeBucket(); // Go to next bucket
this.ctbs.fillTimeBucket();
/*** /***
* We might not have received packets for long time, in which case there would be * We might not have received packets for long time, in which case
* a gap in the start-time of the timer buckets indicating that there was no data * there would be a gap in the start-time of the timer buckets
* This should be a better utilization of resources instead of creating several empty * indicating that there was no data. This should be a better
* utilization of resources instead of creating several empty
* buckets. * buckets.
*/ */
} }
} }
public long getStartTimeOnePkt() { public long getStartTimeOnePkt() {
if (this.perfMonCfgs.procTimeMonitoringState) { if (this.perfMonCfgs.procTimeMonitoringState) {
long startTime_ns = System.nanoTime(); long startTime_ns = System.nanoTime();
...@@ -279,168 +216,15 @@ public class PktinProcessingTime { ...@@ -279,168 +216,15 @@ public class PktinProcessingTime {
} }
return 0L; return 0L;
} }
// Component refers to software component like forwarding // Component refers to software component like forwarding
public long getStartTimeOneComponent() { public long getStartTimeOneComponent() {
if (this.perfMonCfgs.procTimeMonitoringState) { if (this.perfMonCfgs.procTimeMonitoringState) {
return System.nanoTime(); return System.nanoTime();
} }
return 0L; 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( public void updateCumulativeTimeOneComp(
long onePktOneCompProcTime_ns, int id) { long onePktOneCompProcTime_ns, int id) {
if (this.perfMonCfgs.procTimeMonitoringState) { if (this.perfMonCfgs.procTimeMonitoringState) {
...@@ -449,48 +233,53 @@ public class PktinProcessingTime { ...@@ -449,48 +233,53 @@ public class PktinProcessingTime {
OneComponentTime t_temp = this.ctb.tComps.oneComp[id]; OneComponentTime t_temp = this.ctb.tComps.oneComp[id];
t_temp.pktCnt++; t_temp.pktCnt++;
t_temp.sumProcTime_us += onePktOneCompProcTime_us; t_temp.sumProcTime_us += onePktOneCompProcTime_us;
t_temp.sumSquaredProcTime_us2 += t_temp.sumSquaredProcTime_us2 +=
onePktOneCompProcTime_us * onePktOneCompProcTime_us; onePktOneCompProcTime_us * onePktOneCompProcTime_us;
if (onePktOneCompProcTime_us > t_temp.maxProcTime_us) { if (onePktOneCompProcTime_us > t_temp.maxProcTime_us) {
t_temp.maxProcTime_us = onePktOneCompProcTime_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; t_temp.minProcTime_us = onePktOneCompProcTime_us;
} }
} }
} }
public void updateCumulativeTimeTotal(long onePktStartTime_ns) { public void updateCumulativeTimeTotal(long onePktStartTime_ns) {
if (this.perfMonCfgs.procTimeMonitoringState) { if (this.perfMonCfgs.procTimeMonitoringState) {
// There is no api to get time in microseconds, milliseconds is too coarse // There is no api to get time in microseconds, milliseconds is
// Hence we have to use nanoseconds and then divide by 1000 to get mucroseconds // too coarse hence we have to use nanoseconds and then divide by
int onePktProcTime_us = (int)((System.nanoTime() - onePktStartTime_ns) / 1000); // 1000 to get microseconds
int onePktProcTime_us =
(int)((System.nanoTime() - onePktStartTime_ns) / 1000);
if (onePktProcTime_us > TOT_PROC_TIME_WARN_THRESHOLD_US) { 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.totalPktCnt++;
this.ctb.totalSumProcTime_us += onePktProcTime_us; 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) { if (onePktProcTime_us > this.ctb.maxTotalProcTime_us) {
this.ctb.maxTotalProcTime_us = onePktProcTime_us; this.ctb.maxTotalProcTime_us = onePktProcTime_us;
} else if (onePktProcTime_us < this.ctb.minTotalProcTime_us) { } else if (onePktProcTime_us < this.ctb.minTotalProcTime_us) {
this.ctb.minTotalProcTime_us = onePktProcTime_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 * How many timer buckets have valid data, initially it is false then it
* stays at true after the circle is completed * stays at true after the circle is completed
*/ */
boolean allBucketsValid; boolean allBucketsValid;
int curBucketIdx; // most recent bucket *being* filled int curBucketIdx; // most recent bucket *being* filled
int numComps;
CumulativeTimeBucket [] timeBucketSet; CumulativeTimeBucket [] timeBucketSet;
public boolean isAllBucketsValid() { public boolean isAllBucketsValid() {
return allBucketsValid; return allBucketsValid;
} }
...@@ -507,6 +296,10 @@ public class PktinProcessingTime { ...@@ -507,6 +296,10 @@ public class PktinProcessingTime {
this.curBucketIdx = curBucketIdx; this.curBucketIdx = curBucketIdx;
} }
public int getNumComps() {
return numComps;
}
public CumulativeTimeBucket[] getTimeBucketSet() { public CumulativeTimeBucket[] getTimeBucketSet() {
return timeBucketSet; return timeBucketSet;
} }
...@@ -521,44 +314,45 @@ public class PktinProcessingTime { ...@@ -521,44 +314,45 @@ public class PktinProcessingTime {
Long temp = (long) sum; Long temp = (long) sum;
temp = temp * temp / count; temp = temp * temp / count;
temp = (sumSquared - 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]; timeBucketSet = new CumulativeTimeBucket[BUCKET_SET_SIZE];
for (int idx= 0; idx < BUCKET_SET_SIZE; idx++) { for (int idx= 0; idx < BUCKET_SET_SIZE; idx++) {
timeBucketSet[idx] = new CumulativeTimeBucket(); timeBucketSet[idx] = new CumulativeTimeBucket(numComps);
timeBucketSet[idx].setBucketNo(idx); timeBucketSet[idx].setBucketNo(idx);
} }
allBucketsValid = false; allBucketsValid = false;
curBucketIdx = 0; curBucketIdx = 0;
this.numComps = numComps;
} }
// Called when the bucket time ends // Called when the bucket time ends
public void fillTimeBucket() { public void fillTimeBucket() {
// Wrap up computations on the current bucket data // 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 // here if it turns out to be a performance issue
if (ctb.totalPktCnt > 0) { if (ctb.totalPktCnt > 0) {
ctb.avgTotalProcTime_us = ctb.avgTotalProcTime_us =
ctb.totalSumProcTime_us / ctb.totalPktCnt; ctb.totalSumProcTime_us / ctb.totalPktCnt;
ctb.sigmaTotalProcTime_us = ctb.sigmaTotalProcTime_us =
computeSigma(ctb.totalSumProcTime_us, computeSigma(ctb.totalSumProcTime_us,
ctb.totalSumSquaredProcTime_us, ctb.totalPktCnt); ctb.totalSumSquaredProcTime_us, ctb.totalPktCnt);
// Find the avg and std. dev. of each component's proc. time // Find the avg and std. dev. of each component's proc. time
for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; for (int idx = FlListenerID.FL_FIRST_LISTENER_ID;
idx <= BB_LAST_LISTENER_ID; idx++) { idx <= BB_LAST_LISTENER_ID; idx++) {
OneComponentTime oct = ctb.tComps.oneComp[idx]; OneComponentTime oct = ctb.tComps.oneComp[idx];
if (oct.pktCnt > 0) { if (oct.pktCnt > 0) {
oct.avgProcTime_us = oct.sumProcTime_us / oct.pktCnt; oct.avgProcTime_us = oct.sumProcTime_us / oct.pktCnt;
oct.sigmaProcTime_us = computeSigma(oct.sumProcTime_us, oct.sigmaProcTime_us = computeSigma(oct.sumProcTime_us,
oct.sumSquaredProcTime_us2, oct.pktCnt); oct.sumSquaredProcTime_us2, oct.pktCnt);
} }
} }
} }
ctb.duration_s = ONE_BUCKET_DURATION_SECONDS_INT; ctb.duration_s = ONE_BUCKET_DURATION_SECONDS_INT;
// Move to the new bucket // Move to the new bucket
if (curBucketIdx >= BUCKET_SET_SIZE-1) { if (curBucketIdx >= BUCKET_SET_SIZE-1) {
curBucketIdx = 0; curBucketIdx = 0;
...@@ -570,5 +364,5 @@ public class PktinProcessingTime { ...@@ -570,5 +364,5 @@ public class PktinProcessingTime {
ctb = timeBucketSet[curBucketIdx]; ctb = timeBucketSet[curBucketIdx];
ctb.initializeCumulativeTimeBucket(ctb); ctb.initializeCumulativeTimeBucket(ctb);
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment