From 958d3c258293929e80b215d2b56b4032dae3910d Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 30 May 2016 17:36:03 +0300 Subject: async util. monitor i40 FDIR delay issue --- .../stl/trex_stl_lib/trex_stl_async_client.py | 90 +++++++++++++++++++++- .../stl/trex_stl_lib/trex_stl_client.py | 3 +- .../stl/trex_stl_lib/trex_stl_stats.py | 19 +++-- 3 files changed, 99 insertions(+), 13 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py index 745a7fc5..0f73792a 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py @@ -153,6 +153,8 @@ class CTRexAsyncClient(): self.last_data_recv_ts = 0 self.async_barrier = None + self.monitor = AsyncUtil() + self.connected = False # connects the async channel @@ -223,10 +225,17 @@ class CTRexAsyncClient(): got_data = False + self.monitor.reset() + + while self.active: try: - line = self.socket.recv_string() + with self.monitor: + line = self.socket.recv_string() + + self.monitor.on_recv_msg(line) + self.last_data_recv_ts = time.time() # signal once @@ -237,7 +246,6 @@ class CTRexAsyncClient(): # got a timeout - mark as not alive and retry except zmq.Again: - # signal once if got_data: self.event_handler.on_async_dead() @@ -341,4 +349,82 @@ class CTRexAsyncClient(): return RC_OK() +# a class to measure util. of async subscriber thread +class AsyncUtil(object): + + STATE_SLEEP = 1 + STATE_AWAKE = 2 + + def __init__ (self): + self.reset() + + + def reset (self): + self.state = self.STATE_AWAKE + self.clock = time.time() + + # reset the current interval + self.interval = {'ts': time.time(), 'total_sleep': 0, 'total_bits': 0} + + # global counters + self.cpu_util = 0 + self.bps = 0 + + + def on_recv_msg (self, message): + self.interval['total_bits'] += len(message) * 8.0 + + self._tick() + + + def __enter__ (self): + assert(self.state == self.STATE_AWAKE) + self.state = self.STATE_SLEEP + + self.sleep_start_ts = time.time() + + + def __exit__(self, exc_type, exc_val, exc_tb): + assert(self.state == self.STATE_SLEEP) + self.state = self.STATE_AWAKE + + # measure total sleep time for interval + self.interval['total_sleep'] += time.time() - self.sleep_start_ts + + self._tick() + + def _tick (self): + # how much time did the current interval lasted + ts = time.time() - self.interval['ts'] + if ts < 1: + return + + # if tick is in the middle of sleep - add the interval and reset + if self.state == self.STATE_SLEEP: + self.interval['total_sleep'] += time.time() - self.sleep_start_ts + self.sleep_start_ts = time.time() + + # add the interval + if self.interval['total_sleep'] > 0: + # calculate + self.cpu_util = self.cpu_util * 0.75 + (float(ts - self.interval['total_sleep']) / ts) * 0.25 + self.interval['total_sleep'] = 0 + + + if self.interval['total_bits'] > 0: + # calculate + self.bps = self.bps * 0.75 + ( self.interval['total_bits'] / ts ) * 0.25 + self.interval['total_bits'] = 0 + + # reset the interval's clock + self.interval['ts'] = time.time() + + + def get_cpu_util (self): + self._tick() + return (self.cpu_util * 100) + + def get_bps (self): + self._tick() + return (self.bps) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index fa24574f..22895a75 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -558,7 +558,8 @@ class STLClient(object): self.stats_generator = trex_stl_stats.CTRexInfoGenerator(self.global_stats, self.ports, self.flow_stats, - self.latency_stats) + self.latency_stats, + self.async_client.monitor) 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 0ebea607..94a45577 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 @@ -138,11 +138,12 @@ class CTRexInfoGenerator(object): STLClient and the ports. """ - def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref): + def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref, async_monitor): self._global_stats = global_stats_ref self._ports_dict = ports_dict_ref self._rx_stats_ref = rx_stats_ref self._latency_stats_ref = latency_stats_ref + self._async_monitor = async_monitor def generate_single_statistic(self, port_id_list, statistic_type): if statistic_type == GLOBAL_STATS: @@ -187,24 +188,22 @@ class CTRexInfoGenerator(object): def _generate_global_stats(self): global_stats = self._global_stats - #if is_integer(global_stats.max_global_latency): - # max_global_latency_str = ', Max latency: %s' % format_num(global_stats.max_global_latency, - # suffix = 'usec', - # compact = False, - # opts = 'green' if global_stats.max_global_latency < 1000 else 'red') - #else: - # max_global_latency_str = '' + stats_data = OrderedDict([("connection", "{host}, Port {port}".format(host=global_stats.connection_info.get("server"), port=global_stats.connection_info.get("sync_port"))), ("version", "{ver}, UUID: {uuid}".format(ver=global_stats.server_version.get("version", "N/A"), uuid="N/A")), - ("cpu_util", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_cpu_util")), [85, 100], [0, 85]), + ("cpu_util.", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_cpu_util")), [85, 100], [0, 85]), global_stats.get_trend_gui("m_cpu_util", use_raw = True))), - ("rx_cpu_util", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_rx_cpu_util")), [85, 100], [0, 85]), + ("rx_cpu_util.", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_rx_cpu_util")), [85, 100], [0, 85]), global_stats.get_trend_gui("m_rx_cpu_util", use_raw = True))), + ("async_util.", "{0}% / {1}".format( format_threshold(round_float(self._async_monitor.get_cpu_util()), [85, 100], [0, 85]), + format_num(self._async_monitor.get_bps() / 8.0, suffix = "B/sec"))), + + (" ", ""), ("total_tx_L2", "{0} {1}".format( global_stats.get("m_tx_bps", format=True, suffix="b/sec"), -- cgit 1.2.3-korg