[modules/cpu] Add configurable warning and critical thresholds
The cpu module now has cpu.warning and cpu.critical thresholds. If the CPU utilization is higher than any of those values, the widget's state changes to warning or critical, respectively. see #23
This commit is contained in:
parent
87e76b9e40
commit
225d471c6a
5 changed files with 60 additions and 17 deletions
|
@ -18,19 +18,19 @@ def main():
|
||||||
inp=inp,
|
inp=inp,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
engine.run()
|
||||||
engine.run()
|
# try:
|
||||||
except KeyboardInterrupt as error:
|
# except KeyboardInterrupt as error:
|
||||||
inp.stop()
|
# inp.stop()
|
||||||
sys.exit(0)
|
# sys.exit(0)
|
||||||
except bumblebee.error.BaseError as error:
|
# except bumblebee.error.BaseError as error:
|
||||||
inp.stop()
|
# inp.stop()
|
||||||
sys.stderr.write("fatal: {}\n".format(error))
|
# sys.stderr.write("fatal: {}\n".format(error))
|
||||||
sys.exit(1)
|
# sys.exit(1)
|
||||||
except Exception as error:
|
# except Exception as error:
|
||||||
inp.stop()
|
# inp.stop()
|
||||||
sys.stderr.write("fatal: {}\n".format(error))
|
# sys.stderr.write("fatal: {}\n".format(error))
|
||||||
sys.exit(2)
|
# sys.exit(2)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
# pylint: disable=C0111,R0903
|
# pylint: disable=C0111,R0903
|
||||||
|
|
||||||
"""Displays CPU utilization across all CPUs."""
|
"""Displays CPU utilization across all CPUs.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* cpu.warning : Warning threshold in % of CPU usage (defaults to 70%)
|
||||||
|
* cpu.critical: Critical threshold in % of CPU usage (defaults to 80%)
|
||||||
|
"""
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
import bumblebee.input
|
import bumblebee.input
|
||||||
|
@ -22,4 +27,11 @@ class Module(bumblebee.engine.Module):
|
||||||
def update(self, widgets):
|
def update(self, widgets):
|
||||||
self._utilization = psutil.cpu_percent(percpu=False)
|
self._utilization = psutil.cpu_percent(percpu=False)
|
||||||
|
|
||||||
|
def state(self, widget):
|
||||||
|
if self._utilization > int(self.parameter("critical", 80)):
|
||||||
|
return "critical"
|
||||||
|
if self._utilization > int(self.parameter("warning", 70)):
|
||||||
|
return "warning"
|
||||||
|
return None
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
|
@ -11,6 +11,7 @@ class Widget(object):
|
||||||
def __init__(self, full_text="", name=""):
|
def __init__(self, full_text="", name=""):
|
||||||
self._full_text = full_text
|
self._full_text = full_text
|
||||||
self.module = None
|
self.module = None
|
||||||
|
self._module = None
|
||||||
self.name = name
|
self.name = name
|
||||||
self.id = str(uuid.uuid4())
|
self.id = str(uuid.uuid4())
|
||||||
|
|
||||||
|
@ -20,10 +21,13 @@ class Widget(object):
|
||||||
This is done outside the constructor to avoid having to
|
This is done outside the constructor to avoid having to
|
||||||
pass in the module name in every concrete module implementation"""
|
pass in the module name in every concrete module implementation"""
|
||||||
self.module = module.name
|
self.module = module.name
|
||||||
|
self._module = module
|
||||||
|
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Return the widget's state"""
|
"""Return the widget's state"""
|
||||||
return "state-default"
|
if self._module and hasattr(self._module, "state"):
|
||||||
|
return self._module.state(self)
|
||||||
|
return None
|
||||||
|
|
||||||
def full_text(self):
|
def full_text(self):
|
||||||
"""Retrieve the full text to display in the widget"""
|
"""Retrieve the full text to display in the widget"""
|
||||||
|
|
|
@ -7,14 +7,17 @@ import mock
|
||||||
import bumblebee.input
|
import bumblebee.input
|
||||||
from bumblebee.input import I3BarInput
|
from bumblebee.input import I3BarInput
|
||||||
from bumblebee.modules.cpu import Module
|
from bumblebee.modules.cpu import Module
|
||||||
from tests.util import MockEngine, assertPopen
|
from tests.util import MockEngine, MockConfig, assertPopen
|
||||||
|
|
||||||
class TestCPUModule(unittest.TestCase):
|
class TestCPUModule(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.engine = MockEngine()
|
self.engine = MockEngine()
|
||||||
self.engine.input = I3BarInput()
|
self.engine.input = I3BarInput()
|
||||||
self.engine.input.need_event = True
|
self.engine.input.need_event = True
|
||||||
self.module = Module(engine=self.engine, config={})
|
self.config = MockConfig()
|
||||||
|
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||||
|
for widget in self.module.widgets():
|
||||||
|
widget.link_module(self.module)
|
||||||
|
|
||||||
@mock.patch("sys.stdout")
|
@mock.patch("sys.stdout")
|
||||||
def test_format(self, mock_output):
|
def test_format(self, mock_output):
|
||||||
|
@ -34,4 +37,20 @@ class TestCPUModule(unittest.TestCase):
|
||||||
mock_input.readline.assert_any_call()
|
mock_input.readline.assert_any_call()
|
||||||
assertPopen(mock_output, "gnome-system-monitor")
|
assertPopen(mock_output, "gnome-system-monitor")
|
||||||
|
|
||||||
|
@mock.patch("psutil.cpu_percent")
|
||||||
|
def test_warning(self, mock_psutil):
|
||||||
|
self.config.set("cpu.critical", "20")
|
||||||
|
self.config.set("cpu.warning", "18")
|
||||||
|
mock_psutil.return_value = 19.0
|
||||||
|
self.module.update(self.module.widgets())
|
||||||
|
self.assertEquals(self.module.widgets()[0].state(), "warning")
|
||||||
|
|
||||||
|
@mock.patch("psutil.cpu_percent")
|
||||||
|
def test_critical(self, mock_psutil):
|
||||||
|
self.config.set("cpu.critical", "20")
|
||||||
|
self.config.set("cpu.warning", "19")
|
||||||
|
mock_psutil.return_value = 21.0
|
||||||
|
self.module.update(self.module.widgets())
|
||||||
|
self.assertEquals(self.module.widgets()[0].state(), "critical")
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
|
@ -31,9 +31,17 @@ class MockEngine(object):
|
||||||
self.input = MockInput()
|
self.input = MockInput()
|
||||||
|
|
||||||
class MockConfig(object):
|
class MockConfig(object):
|
||||||
|
def __init__(self):
|
||||||
|
self._data = {}
|
||||||
|
|
||||||
def get(self, name, default):
|
def get(self, name, default):
|
||||||
|
if name in self._data:
|
||||||
|
return self._data[name]
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
def set(self, name, value):
|
||||||
|
self._data[name] = value
|
||||||
|
|
||||||
class MockOutput(object):
|
class MockOutput(object):
|
||||||
def start(self):
|
def start(self):
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in a new issue