diff options
author | nicolargo <nicolas@nicolargo.com> | 2019-11-24 17:40:02 +0100 |
---|---|---|
committer | nicolargo <nicolas@nicolargo.com> | 2019-11-24 17:40:02 +0100 |
commit | 3b11856926d9d512ba749033e67c326fb619fa3a (patch) | |
tree | 4c26540e15981be0ae5286d3548c67eb31050510 | |
parent | 7bd6351bf27c316eaa9c25f76bf48d1b8a121d36 (diff) |
Feature request: HDD S.M.A.R.T. reports #1288 (only terminal UI)
-rw-r--r-- | conf/glances.conf | 17 | ||||
-rw-r--r-- | docs/aoa/amps.rst | 2 | ||||
-rw-r--r-- | docs/aoa/diskio.rst (renamed from docs/aoa/disk.rst) | 0 | ||||
-rw-r--r-- | docs/aoa/index.rst | 8 | ||||
-rw-r--r-- | docs/aoa/irq.rst | 2 | ||||
-rw-r--r-- | docs/aoa/quicklook.rst | 2 | ||||
-rw-r--r-- | docs/aoa/wifi.rst | 2 | ||||
-rw-r--r-- | glances/compat.py | 25 | ||||
-rw-r--r-- | glances/outputs/glances_curses.py | 20 | ||||
-rw-r--r-- | glances/plugins/glances_raid.py | 2 | ||||
-rw-r--r-- | glances/plugins/glances_smart.py | 67 | ||||
-rwxr-xr-x | unitest.py | 2 |
12 files changed, 99 insertions, 50 deletions
diff --git a/conf/glances.conf b/conf/glances.conf index a69a1192..5a177068 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -186,7 +186,13 @@ critical=90 # Allow additional file system types (comma-separated FS type) #allow=zfs +[irq] +# Documentation: https://glances.readthedocs.io/en/stable/aoa/irq.html +# This plugin is disabled by default +disable=True + [folders] +# Documentation: https://glances.readthedocs.io/en/stable/aoa/folders.html disable=False # Define a folder list to monitor # The list is composed of items (list_#nb <= 10) @@ -207,10 +213,15 @@ disable=False #folder_3_path=/nonexisting #folder_4_path=/root -[irq] +[raid] +# Documentation: https://glances.readthedocs.io/en/stable/aoa/raid.html # This plugin is disabled by default -# Documentation: https://glances.readthedocs.io/en/stable/aoa/irq.html -disable=False +disable=True + +[smart] +# Documentation: https://glances.readthedocs.io/en/stable/aoa/smart.html +# This plugin is disabled by default +disable=True [hddtemp] disable=False diff --git a/docs/aoa/amps.rst b/docs/aoa/amps.rst index 85518f86..e32d6192 100644 --- a/docs/aoa/amps.rst +++ b/docs/aoa/amps.rst @@ -6,7 +6,7 @@ Applications Monitoring Process Thanks to Glances and its AMP module, you can add specific monitoring to running processes. AMPs are defined in the Glances [configuration file](http://glances.readthedocs.io/en/stable/config.html). -You can disable AMP using the ``--disable-amps`` option or pressing the +You can disable AMP using the ``--disable-plugin amps`` option or pressing the ``A`` key. Simple AMP diff --git a/docs/aoa/disk.rst b/docs/aoa/diskio.rst index f6d03ffe..f6d03ffe 100644 --- a/docs/aoa/disk.rst +++ b/docs/aoa/diskio.rst diff --git a/docs/aoa/index.rst b/docs/aoa/index.rst index 93d7db44..571e9410 100644 --- a/docs/aoa/index.rst +++ b/docs/aoa/index.rst @@ -24,16 +24,18 @@ Legend: quicklook cpu gpu - load memory + load network connections wifi ports - disk + diskio fs - folders irq + folders + raid + smart sensors ps monitor diff --git a/docs/aoa/irq.rst b/docs/aoa/irq.rst index 9a9a55a7..6fbc868f 100644 --- a/docs/aoa/irq.rst +++ b/docs/aoa/irq.rst @@ -5,7 +5,7 @@ IRQ *Availability: Linux* -This plugin is disable by default, please use the --enable-irq option +This plugin is disable by default, please use the --enable irq option to enable it. .. image:: ../_static/irq.png diff --git a/docs/aoa/quicklook.rst b/docs/aoa/quicklook.rst index 69e47427..a7cad3ee 100644 --- a/docs/aoa/quicklook.rst +++ b/docs/aoa/quicklook.rst @@ -6,6 +6,8 @@ Quick Look The ``quicklook`` plugin is only displayed on wide screen and proposes a bar view for CPU and memory (virtual and swap). +In the terminal interface, click on ``3`` to enable/disable it. + .. image:: ../_static/quicklook.png If the per CPU mode is on (by clicking the ``1`` key): diff --git a/docs/aoa/wifi.rst b/docs/aoa/wifi.rst index 9e44d062..deb71fbc 100644 --- a/docs/aoa/wifi.rst +++ b/docs/aoa/wifi.rst @@ -32,5 +32,5 @@ hide the loopback interface (lo) and all the virtual docker interfaces: warning=-75 critical=-85 -You can disable this plugin using the ``--disable-wifi`` option or by +You can disable this plugin using the ``--disable-plugin wifi`` option or by hitting the ``W`` key from the user interface. diff --git a/glances/compat.py b/glances/compat.py index cac531f1..e16e8286 100644 --- a/glances/compat.py +++ b/glances/compat.py @@ -28,6 +28,7 @@ import sys import unicodedata import types import subprocess +import os from glances.logger import logger @@ -239,3 +240,27 @@ def time_serie_subsample(data, sampling): def to_fahrenheit(celsius): """Convert Celsius to Fahrenheit.""" return celsius * 1.8 + 32 + + +def is_admin(): + """ + https://stackoverflow.com/a/19719292 + @return: True if the current user is an 'Admin' whatever that + means (root on Unix), otherwise False. + Warning: The inner function fails unless you have Windows XP SP2 or + higher. The failure causes a traceback to be printed and this + function to return False. + """ + + if os.name == 'nt': + import ctypes + import traceback + # WARNING: requires Windows XP SP2 or higher! + try: + return ctypes.windll.shell32.IsUserAnAdmin() + except Exception as e: + traceback.print_exc() + return False + else: + # Check for root on Posix + return os.getuid() == 0 diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index ec1afdf4..a1e00d2d 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -55,38 +55,38 @@ class _GlancesCurses(object): '3': {'switch': 'disable_quicklook'}, '6': {'switch': 'meangpu'}, '/': {'switch': 'process_short_name'}, + 'a': {'sort_key': 'auto'}, 'A': {'switch': 'disable_amps'}, 'b': {'switch': 'byte'}, 'B': {'switch': 'diskio_iops'}, + 'c': {'sort_key': 'cpu_percent'}, 'C': {'switch': 'disable_cloud'}, - 'D': {'switch': 'disable_docker'}, 'd': {'switch': 'disable_diskio'}, + 'D': {'switch': 'disable_docker'}, 'F': {'switch': 'fs_free_space'}, 'g': {'switch': 'generate_graph'}, 'G': {'switch': 'disable_gpu'}, 'h': {'switch': 'help_tag'}, + 'i': {'sort_key': 'io_counters'}, 'I': {'switch': 'disable_ip'}, 'k': {'switch': 'disable_connections'}, 'l': {'switch': 'disable_alert'}, + 'm': {'sort_key': 'memory_percent'}, 'M': {'switch': 'reset_minmax_tag'}, 'n': {'switch': 'disable_network'}, 'N': {'switch': 'disable_now'}, + 'p': {'sort_key': 'name'}, 'P': {'switch': 'disable_ports'}, 'Q': {'switch': 'enable_irq'}, + 'r': {'switch': 'disable_smart'}, 'R': {'switch': 'disable_raid'}, 's': {'switch': 'disable_sensors'}, 'S': {'switch': 'sparkline'}, + 't': {'sort_key': 'cpu_times'}, 'T': {'switch': 'network_sum'}, + 'u': {'sort_key': 'username'}, 'U': {'switch': 'network_cumul'}, 'W': {'switch': 'disable_wifi'}, - # Processes sort hotkeys - 'a': {'sort_key': 'auto'}, - 'c': {'sort_key': 'cpu_percent'}, - 'i': {'sort_key': 'io_counters'}, - 'm': {'sort_key': 'memory_percent'}, - 'p': {'sort_key': 'name'}, - 't': {'sort_key': 'cpu_times'}, - 'u': {'sort_key': 'username'}, } _sort_loop = ['cpu_percent', 'memory_percent', 'username', @@ -98,7 +98,7 @@ class _GlancesCurses(object): # Define left sidebar _left_sidebar = ['network', 'connections', 'wifi', 'ports', 'diskio', 'fs', - 'irq', 'folders', 'raid', 'sensors', 'now'] + 'irq', 'folders', 'raid', 'smart', 'sensors', 'now'] _left_sidebar_min_width = 23 _left_sidebar_max_width = 34 diff --git a/glances/plugins/glances_raid.py b/glances/plugins/glances_raid.py index 7e5275b2..795812e7 100644 --- a/glances/plugins/glances_raid.py +++ b/glances/plugins/glances_raid.py @@ -83,7 +83,7 @@ class Plugin(GlancesPlugin): ret = [] # Only process if stats exist... - if not self.stats: + if not self.stats or self.is_disable(): return ret # Max size for the interface name diff --git a/glances/plugins/glances_smart.py b/glances/plugins/glances_smart.py index f0291cad..445942cb 100644 --- a/glances/plugins/glances_smart.py +++ b/glances/plugins/glances_smart.py @@ -47,7 +47,7 @@ If smartmontools is not installed, we should catch the error upstream in plugin from glances.plugins.glances_plugin import GlancesPlugin from glances.logger import logger from glances.main import disable -import os +from glances.compat import is_admin # Import plugin specific dependency try: @@ -58,35 +58,10 @@ except ImportError as e: else: import_error_tag = False -DEVKEY = "DeviceName" - - -def is_admin(): - """ - https://stackoverflow.com/a/19719292 - @return: True if the current user is an 'Admin' whatever that - means (root on Unix), otherwise False. - Warning: The inner function fails unless you have Windows XP SP2 or - higher. The failure causes a traceback to be printed and this - function to return False. - """ - - if os.name == 'nt': - import ctypes - import traceback - # WARNING: requires Windows XP SP2 or higher! - try: - return ctypes.windll.shell32.IsUserAnAdmin() - except: - traceback.print_exc() - return False - else: - # Check for root on Posix - return os.getuid() == 0 - def convert_attribute_to_dict(attr): return { + 'name': attr.name, 'num': attr.num, 'flags': attr.flags, 'raw': attr.raw, @@ -114,6 +89,7 @@ def get_smart_data(): "raw": "..", etc, } + ... } ] """ @@ -123,7 +99,7 @@ def get_smart_data(): for dev in devlist.devices: stats.append({ - DEVKEY: str(dev) + 'DeviceName': '{} {}'.format(dev.name, dev.model), }) for attribute in dev.attributes: if attribute is None: @@ -187,4 +163,37 @@ class Plugin(GlancesPlugin): def get_key(self): """Return the key of the list.""" - return DEVKEY + return 'DeviceName' + + def msg_curse(self, args=None, max_width=None): + """Return the dict to display in the curse interface.""" + # Init the return message + ret = [] + + # Only process if stats exist... + if not self.stats or self.is_disable(): + return ret + + # Max size for the interface name + name_max_width = max_width - 6 + + # Header + msg = '{:{width}}'.format('SMART disks', + width=name_max_width) + ret.append(self.curse_add_line(msg, "TITLE")) + # Data + for device_stat in self.stats: + # New line + ret.append(self.curse_new_line()) + msg = '{:{width}}'.format(device_stat['DeviceName'][:max_width], + width=max_width) + ret.append(self.curse_add_line(msg)) + for smart_stat in sorted([i for i in device_stat.keys() if i != 'DeviceName'], key=int): + ret.append(self.curse_new_line()) + msg = ' {:{width}}'.format(device_stat[smart_stat]['name'][:name_max_width-1].replace('_', ' '), + width=name_max_width-1) + ret.append(self.curse_add_line(msg)) + msg = '{:>8}'.format(device_stat[smart_stat]['raw']) + ret.append(self.curse_add_line(msg)) + + return ret @@ -257,7 +257,7 @@ class TestGlances(unittest.TestCase): def test_016_hddsmart(self): """Check hard disk SMART data plugin.""" try: - from glances.plugins.glances_smart import is_admin + from glances.compat import is_admin except ImportError: print("INFO: [TEST_016] pySMART not found, not running SMART plugin test") return |