summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py95
-rw-r--r--src/flow_stat.cpp4
2 files changed, 72 insertions, 27 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index 78bd2358..418affb7 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -382,15 +382,13 @@ class CTRexInfoGenerator(object):
class CTRexStats(object):
""" This is an abstract class to represent a stats object """
- def __init__(self, flowing = True):
+ def __init__(self):
self.reference_stats = {}
self.latest_stats = {}
self.last_update_ts = time.time()
self.history = deque(maxlen = 10)
self.lock = threading.Lock()
- # does the object gets a constant flow of data ?
- self.flowing = flowing
######## abstract methods ##########
@@ -428,8 +426,8 @@ class CTRexStats(object):
# handle the reference (base)
self.__update_ref()
- # for flowing objects 3 seconds is too much
- if self.flowing and (diff_time > 3):
+ # 3 seconds its a timeout
+ if diff_time > 3:
self.clear_stats()
@@ -444,24 +442,24 @@ class CTRexStats(object):
self.latest_stats = {}
- def __get (self, src, field):
+ def _get (self, src, field, default = None):
if isinstance(field, list):
# deep
value = src
for level in field:
if not level in value:
- return None
+ return default
value = value[level]
else:
# flat
if not field in src:
- return None
+ return default
value = src[field]
return value
def get(self, field, format=False, suffix=""):
- value = self.__get(self.latest_stats, field)
+ value = self._get(self.latest_stats, field)
if value == None:
return "N/A"
@@ -469,12 +467,12 @@ class CTRexStats(object):
def get_rel(self, field, format=False, suffix=""):
- ref_value = self.__get(self.reference_stats, field)
+ ref_value = self._get(self.reference_stats, field)
if ref_value == None:
return "N/A"
# if the latest does not have the value - its like the ref
- latest_value = self.__get(self.latest_stats, field)
+ latest_value = self._get(self.latest_stats, field)
if latest_value == None:
latest_value = ref_value
@@ -753,20 +751,28 @@ class CPortStats(CTRexStats):
class CRxStats(CTRexStats):
def __init__(self):
- super(CRxStats, self).__init__(flowing = False)
+ super(CRxStats, self).__init__()
+
+ def bps_L1 (self, bps, pps):
+ if pps == 0:
+ return 0
+ factor = bps / (pps * 8.0)
+ return bps * ( 1 + (20 / factor) )
def preprocess_snapshot (self, snapshot):
# heavy pre-processing here...
new_snapshot = {}
- if not 'timestamp' in snapshot:
- raise ValueError("INTERNAL ERROR: RX stats snapshot MUST contain 'timestamp' field")
+ if not 'ts' in snapshot:
+ raise ValueError("INTERNAL ERROR: RX stats snapshot MUST contain 'ts' field")
+
+ new_snapshot['ts'] = snapshot['ts']
for key, value in snapshot.iteritems():
# skip non int values (simply copy)
- if key == 'timestamp':
+ if key == 'ts':
new_snapshot[key] = value
continue
@@ -785,11 +791,46 @@ class CRxStats(CTRexStats):
new_snapshot[pg_id][field][int(port)] = pv
new_snapshot[pg_id][field]['total'] += pv
-
+ # add B/W calcs for a PG id
+ self.calculate_bw(new_snapshot, pg_id)
snapshot.clear()
snapshot.update(new_snapshot)
+
+ def calculate_bw (self, snapshot, pg_id):
+ if not self.latest_stats:
+ snapshot[pg_id]['tx_pps'] = 0.0
+ snapshot[pg_id]['tx_bps'] = 0.0
+ snapshot[pg_id]['rx_pps'] = 0.0
+ snapshot[pg_id]['rx_bps'] = 0.0
+ return
+
+ # prev
+ prev_ts = self._get(self.latest_stats, 'ts')
+ prev_tx_pkts = self._get(self.latest_stats, [pg_id, 'tx_pkts', 'total'], default = 0.0)
+ prev_tx_bytes = self._get(self.latest_stats, [pg_id, 'tx_bytes', 'total'], default = 0.0)
+ prev_tx_pps = self._get(self.latest_stats, [pg_id, 'tx_pps'], default = 0.0)
+ prev_tx_bps = self._get(self.latest_stats, [pg_id, 'tx_bps'], default = 0.0)
+
+ # now
+ now_ts = snapshot['ts']
+ now_tx_pkts = snapshot[pg_id]['tx_pkts']['total']
+ now_tx_bytes = snapshot[pg_id]['tx_bytes']['total']
+
+ # diff seconds
+ diff_sec = (now_ts['value'] - prev_ts['value']) / float(now_ts['freq'])
+
+ # calculate fields
+ snapshot[pg_id]['tx_pps'] = (0.5 * prev_tx_pps) + (0.5 * ( (now_tx_pkts - prev_tx_pkts) / diff_sec) )
+ snapshot[pg_id]['tx_bps'] = (0.5 * prev_tx_bps) + (0.5 * ( (now_tx_bytes - prev_tx_bytes) * 8 / diff_sec) )
+
+ snapshot[pg_id]['rx_pps'] = 0.0
+ snapshot[pg_id]['rx_bps'] = 0.0
+
+ snapshot[pg_id]['tx_bps_L1'] = self.bps_L1(snapshot[pg_id]['tx_bps'], snapshot[pg_id]['tx_pps'])
+
+
def get_stats (self):
stats = {}
@@ -824,11 +865,12 @@ class CRxStats(CTRexStats):
cnt = len(pg_ids)
- formatted_stats = OrderedDict([ ('Tx bps L2', []),
- ('Tx bps L1', []),
- ('Tx pps', []),
+ formatted_stats = OrderedDict([ ('Tx pps', []),
+ ('Tx bps L2', []),
+ ('Tx bps L1', []),
('---', [''] * cnt),
('Rx pps', []),
+ ('Rx bps', []),
('----', [''] * cnt),
('opackets', []),
('ipackets', []),
@@ -846,13 +888,14 @@ class CRxStats(CTRexStats):
# maximum 4
for pg_id in pg_ids:
- #formatted_stats['TX packet count'].append(stats[key]['tx-pkts']['total'])
- #formatted_stats['TX byte count'].append(stats[key]['tx-bytes']['total'])
- #formatted_stats['RX packet count'].append(stats[key]['rx-pkts']['total'])
- formatted_stats['Tx bps L2'].append(0)
- formatted_stats['Tx bps L1'].append(0)
- formatted_stats['Tx pps'].append(0)
- formatted_stats['Rx pps'].append(0)
+ formatted_stats['Tx pps'].append(self.get([pg_id, 'tx_pps'], format = True, suffix = "pps"))
+ formatted_stats['Tx bps L2'].append(self.get([pg_id, 'tx_bps'], format = True, suffix = "bps"))
+
+ formatted_stats['Tx bps L1'].append(self.get([pg_id, 'tx_bps_L1'], format = True, suffix = "bps"))
+
+ formatted_stats['Rx pps'].append(self.get([pg_id, 'rx_pps'], format = True, suffix = "pps"))
+ formatted_stats['Rx bps'].append(self.get([pg_id, 'rx_bps'], format = True, suffix = "bps"))
+
formatted_stats['opackets'].append(self.get_rel([pg_id, 'tx_pkts', 'total']))
formatted_stats['ipackets'].append(self.get_rel([pg_id, 'rx_pkts', 'total']))
formatted_stats['obytes'].append(self.get_rel([pg_id, 'tx_bytes', 'total']))
diff --git a/src/flow_stat.cpp b/src/flow_stat.cpp
index 57aa29c5..4e05de8a 100644
--- a/src/flow_stat.cpp
+++ b/src/flow_stat.cpp
@@ -631,7 +631,9 @@ bool CFlowStatRuleMgr::dump_json(std::string & json, bool force_sync) {
root["name"] = "flow_stats";
root["type"] = 0;
Json::Value &data_section = root["data"];
- data_section["timestamp"] = Json::Value::UInt64(os_get_hr_tick_64());
+
+ data_section["ts"]["value"] = Json::Value::UInt64(os_get_hr_tick_64());
+ data_section["ts"]["freq"] = Json::Value::UInt64(os_get_hr_freq());
if (m_user_id_map.is_empty()) {
if (force_sync) {