From f3ce370566dedcbf5ba4da11591ddcd5777d0924 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 7 Apr 2013 18:52:49 +0400 Subject: [PATCH 1/3] Make cpu_load_percent segment threaded interval=0.5 means that it will block for 0.5 seconds which is bad. With threading it blocks only the separate thread, and it does not hold GIL (uses regular time.sleep to wait) in this case which is fine. interval=0.05 means that it will report almost random value. interval=None means that (assuming psutil.cpu_percent is called only by this segment) it will report CPU load percent measured between two subsequent .cpu_load_percent calls or cpu_load_percent call and module import. It is used for update method to get immediate result in case update_first is True. --- powerline/segments/common.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/powerline/segments/common.py b/powerline/segments/common.py index e50615cc..4f8db199 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -558,16 +558,30 @@ try: def _get_user(segment_info): return psutil.Process(os.getpid()).username - def cpu_load_percent(pl, measure_interval=.5): - '''Return the average CPU load as a percentage. + class CPULoadPercentSegment(ThreadedSegment): + interval = 1 - Requires the ``psutil`` module. + def update(self, old_cpu): + return psutil.cpu_percent(interval=None) - :param float measure_interval: - interval used to measure CPU load (in seconds) - ''' - cpu_percent = int(psutil.cpu_percent(interval=measure_interval)) - return '{0}%'.format(cpu_percent) + def run(self): + while not self.shutdown_event.is_set(): + try: + self.update_value = psutil.cpu_percent(interval=self.interval) + except Exception as e: + self.exception('Exception while calculating cpu_percent: {0}', str(e)) + + def render(self, cpu_percent, format='{0:.0f}%', **kwargs): + return format.format(cpu_percent) + + cpu_load_percent = with_docstring(CPULoadPercentSegment(), + '''Return the average CPU load as a percentage. + + Requires the ``psutil`` module. + + :param str format: + Output format. Accepts measured CPU load as the first argument. + ''') except ImportError: def _get_bytes(interface): # NOQA with open('/sys/class/net/{interface}/statistics/rx_bytes'.format(interface=interface), 'rb') as file_obj: From 14b31eca357eec3e4f66191901a9d612937d6c18 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 7 Apr 2013 19:01:54 +0400 Subject: [PATCH 2/3] Make dummy cpu_load_percent also ThreadedSegment It is the easiest way to make documentation identical when created on a system with and without psutil module and deduplicate docstrings --- powerline/segments/common.py | 44 ++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/powerline/segments/common.py b/powerline/segments/common.py index 4f8db199..bbc6fb11 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -573,15 +573,6 @@ try: def render(self, cpu_percent, format='{0:.0f}%', **kwargs): return format.format(cpu_percent) - - cpu_load_percent = with_docstring(CPULoadPercentSegment(), - '''Return the average CPU load as a percentage. - - Requires the ``psutil`` module. - - :param str format: - Output format. Accepts measured CPU load as the first argument. - ''') except ImportError: def _get_bytes(interface): # NOQA with open('/sys/class/net/{interface}/statistics/rx_bytes'.format(interface=interface), 'rb') as file_obj: @@ -599,16 +590,35 @@ except ImportError: def _get_user(segment_info): # NOQA return segment_info['environ'].get('USER', None) - def cpu_load_percent(pl, measure_interval=.5): # NOQA - '''Return the average CPU load as a percentage. + class CPULoadPercentSegment(ThreadedSegment): # NOQA + interval = 1 - Requires the ``psutil`` module. + @staticmethod + def startup(**kwargs): + pass - :param float measure_interval: - interval used to measure CPU load (in seconds) - ''' - pl.warn('psutil package is not installed, thus CPU load is not available') - return None + @staticmethod + def start(): + pass + + @staticmethod + def shutdown(): + pass + + @staticmethod + def render(cpu_percent, pl, format='{0:.0f}%', **kwargs): + pl.warn('psutil package is not installed, thus CPU load is not available') + return None + + +cpu_load_percent = with_docstring(CPULoadPercentSegment(), +'''Return the average CPU load as a percentage. + +Requires the ``psutil`` module. + +:param str format: + Output format. Accepts measured CPU load as the first argument. +''') username = False From 71329cdb5d45cd42b62629385a53dddac3f8520c Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 8 Apr 2013 08:04:22 +0400 Subject: [PATCH 3/3] Add gradient for cpu_load_percent Note: no changes to colorschemes: no cpu_load_percent in colorscheme --- powerline/segments/common.py | 10 +++++++++- tests/test_segments.py | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/powerline/segments/common.py b/powerline/segments/common.py index bbc6fb11..a40ec75c 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -572,7 +572,13 @@ try: self.exception('Exception while calculating cpu_percent: {0}', str(e)) def render(self, cpu_percent, format='{0:.0f}%', **kwargs): - return format.format(cpu_percent) + if not cpu_percent: + return None + return [{ + 'contents': format.format(cpu_percent), + 'gradient_level': cpu_percent, + 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + }] except ImportError: def _get_bytes(interface): # NOQA with open('/sys/class/net/{interface}/statistics/rx_bytes'.format(interface=interface), 'rb') as file_obj: @@ -618,6 +624,8 @@ Requires the ``psutil`` module. :param str format: Output format. Accepts measured CPU load as the first argument. + +Highlight groups used: ``cpu_load_percent_gradient`` (gradient) or ``cpu_load_percent``. ''') diff --git a/tests/test_segments.py b/tests/test_segments.py index ca16eb93..18cdc65e 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -244,7 +244,16 @@ class TestCommon(TestCase): def test_cpu_load_percent(self): pl = Pl() with replace_module_module(common, 'psutil', cpu_percent=lambda **kwargs: 52.3): - self.assertEqual(common.cpu_load_percent(pl=pl), '52%') + self.assertEqual(common.cpu_load_percent(pl=pl), [{ + 'contents': '52%', + 'gradient_level': 52.3, + 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + }]) + self.assertEqual(common.cpu_load_percent(pl=pl, format='{0:.1f}%'), [{ + 'contents': '52.3%', + 'gradient_level': 52.3, + 'highlight_group': ['cpu_load_percent_gradient', 'cpu_load_percent'], + }]) def test_network_load(self): from time import sleep