diff --git a/glances/core/glances_stats.py b/glances/core/glances_stats.py index d36c0e94ea6ded7e1b5bf0d2ca22428e05805858..9ae35a873a27c2409cc1a58574e6f89dcbba89b3 100644 --- a/glances/core/glances_stats.py +++ b/glances/core/glances_stats.py @@ -22,9 +22,17 @@ import collections import os import sys +import re from glances.core.glances_globals import plugins_path, sys_path +# SNMP OID regexp pattern to short system name dict +oid_to_short_system_name = {'.*Linux.*': 'linux', + '.*BSD.*': 'bsd', + '.*Darwin.*': 'mac', + '.*Windows.*': 'windows', + '.*Cisco.*': 'cisco'} + class GlancesStats(object): @@ -203,6 +211,9 @@ class GlancesStatsClientSNMP(GlancesStats): # Init the arguments self.args = args + # OS name is used because OID is differents between system + self.os_name = None + # Load plugins self.load_plugins(args=self.args) @@ -219,14 +230,40 @@ class GlancesStatsClientSNMP(GlancesStats): user=self.args.snmp_user, auth=self.args.snmp_auth) - return clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {} + # If we can not grab the hostname, then exit... + ret = clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {} + if ret: + # Get the OS name (need to grab the good OID...) + oid_os_name = clientsnmp.get_by_oid("1.3.6.1.2.1.1.1.0") + try: + self.system_name = self.get_system_name(oid_os_name['1.3.6.1.2.1.1.1.0']) + except KeyError: + self.system_name = None + + return ret + + def get_system_name(self, oid_system_name): + """Get the short os name from the OS name OID string""" + short_system_name = None + + if oid_system_name == '': + return short_system_name + + # Find the short name in the oid_to_short_os_name dict + for r,v in oid_to_short_system_name.iteritems(): + if re.search(r, oid_system_name): + short_system_name = v + break + + return short_system_name + def update(self): """Update the stats using SNMP.""" # For each plugins, call the update method for p in self._plugins: # Set the input method to SNMP - self._plugins[p].set_input('snmp') + self._plugins[p].set_input('snmp', self.system_name) # print "DEBUG: Update %s stats using SNMP request" % p try: self._plugins[p].update() diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py index 479e635874e69eeb1a5e49cdb7ad34f4c6bf5704..9d37ab07b268cc6f2fec0419952b5d8f47494dce 100644 --- a/glances/plugins/glances_cpu.py +++ b/glances/plugins/glances_cpu.py @@ -27,10 +27,9 @@ import psutil # percentage of user CPU time: .1.3.6.1.4.1.2021.11.9.0 # percentages of system CPU time: .1.3.6.1.4.1.2021.11.10.0 # percentages of idle CPU time: .1.3.6.1.4.1.2021.11.11.0 -snmp_oid = {'user': '1.3.6.1.4.1.2021.11.9.0', - 'system': '1.3.6.1.4.1.2021.11.10.0', - 'idle': '1.3.6.1.4.1.2021.11.11.0'} - +snmp_oid = {'default': {'user': '1.3.6.1.4.1.2021.11.9.0', + 'system': '1.3.6.1.4.1.2021.11.10.0', + 'idle': '1.3.6.1.4.1.2021.11.11.0'}} class Plugin(GlancesPlugin): @@ -91,7 +90,10 @@ class Plugin(GlancesPlugin): self.stats[cpu] = getattr(cputimespercent, cpu) elif self.get_input() == 'snmp': # Update stats using SNMP - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid) + try: + self.stats = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()]) + except KeyError: + self.stats = self.set_stats_snmp(snmp_oid=snmp_oid['default']) if self.stats['user'] == '': self.reset() diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py index c4f7d322f88b5c4966a117841786fa090b8f6bc3..ca3d01dc49df0fd4b35824a778b279dc9fb3b8e2 100644 --- a/glances/plugins/glances_fs.py +++ b/glances/plugins/glances_fs.py @@ -19,6 +19,8 @@ """File system plugin.""" +import base64 + from glances.plugins.glances_plugin import GlancesPlugin import psutil @@ -37,11 +39,15 @@ import psutil # Used space on the disk: .1.3.6.1.4.1.2021.9.1.8.1 # Percentage of space used on disk: .1.3.6.1.4.1.2021.9.1.9.1 # Percentage of inodes used on disk: .1.3.6.1.4.1.2021.9.1.10.1 -snmp_oid = {'mnt_point': '1.3.6.1.4.1.2021.9.1.2', - 'device_name': '1.3.6.1.4.1.2021.9.1.3', - 'size': '1.3.6.1.4.1.2021.9.1.6', - 'used': '1.3.6.1.4.1.2021.9.1.8', - 'percent': '1.3.6.1.4.1.2021.9.1.9'} +snmp_oid = {'default': {'mnt_point': '1.3.6.1.4.1.2021.9.1.2', + 'device_name': '1.3.6.1.4.1.2021.9.1.3', + 'size': '1.3.6.1.4.1.2021.9.1.6', + 'used': '1.3.6.1.4.1.2021.9.1.8', + 'percent': '1.3.6.1.4.1.2021.9.1.9'}, + 'windows': {'mnt_point': '1.3.6.1.2.1.25.2.3.1.3', + 'alloc_unit': '1.3.6.1.2.1.25.2.3.1.4', + 'size': '1.3.6.1.2.1.25.2.3.1.5', + 'used': '1.3.6.1.2.1.25.2.3.1.6'}} class Plugin(GlancesPlugin): @@ -110,17 +116,38 @@ class Plugin(GlancesPlugin): # Update stats using SNMP # SNMP bulk command to get all file system in one shot - fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid, bulk=True) + + try: + fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + bulk=True) + except KeyError: + fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid['default'], + bulk=True) # Loop over fs - for fs in fs_stat: - fs_current = {} - fs_current['device_name'] = fs_stat[fs]['device_name'] - fs_current['mnt_point'] = fs - fs_current['size'] = int(fs_stat[fs]['size']) * 1024 - fs_current['used'] = int(fs_stat[fs]['used']) * 1024 - fs_current['percent'] = float(fs_stat[fs]['percent']) - self.stats.append(fs_current) + if self.get_short_system_name() == 'windows': + # Windows tips + for fs in fs_stat: + # Memory stats are grabed in the same OID table (ignore it) + if fs == 'Virtual Memory' or fs == 'Physical Memory': + continue + fs_current = {} + fs_current['device_name'] = '' + fs_current['mnt_point'] = fs.partition(' ')[0] + fs_current['size'] = int(fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) + fs_current['used'] = int(fs_stat[fs]['used']) * int(fs_stat[fs]['alloc_unit']) + fs_current['percent'] = float(fs_current['used'] * 100 / fs_current['size']) + self.stats.append(fs_current) + else: + # Default behavor + for fs in fs_stat: + fs_current = {} + fs_current['device_name'] = fs_stat[fs]['device_name'] + fs_current['mnt_point'] = fs + fs_current['size'] = int(fs_stat[fs]['size']) * 1024 + fs_current['used'] = int(fs_stat[fs]['used']) * 1024 + fs_current['percent'] = float(fs_stat[fs]['percent']) + self.stats.append(fs_current) return self.stats @@ -146,7 +173,9 @@ class Plugin(GlancesPlugin): for i in sorted(self.stats, key=lambda fs: fs['mnt_point']): # New line ret.append(self.curse_new_line()) - if len(i['mnt_point']) + len(i['device_name'].split('/')[-1]) <= 6: + if i['device_name'] == '': + mnt_point = i['mnt_point'] + elif len(i['mnt_point']) + len(i['device_name'].split('/')[-1]) <= 6: # If possible concatenate mode info... Glances touch inside :) mnt_point = i['mnt_point'] + ' (' + i['device_name'].split('/')[-1] + ')' elif len(i['mnt_point']) > 9: diff --git a/glances/plugins/glances_load.py b/glances/plugins/glances_load.py index 4b6a7a144f1151e71edd99b71597cf9fc752449a..526a3bda0ac990536e925392f5c018db1ef671eb 100644 --- a/glances/plugins/glances_load.py +++ b/glances/plugins/glances_load.py @@ -116,7 +116,7 @@ class Plugin(GlancesPlugin): ret.append(self.curse_add_line(msg, "TITLE")) # Core number if self.stats['cpucore'] > 0: - msg = _("{0}-core").format(self.stats['cpucore'], '>1') + msg = _("{0:d}-core").format(int(self.stats['cpucore']), '>1') ret.append(self.curse_add_line(msg)) # New line ret.append(self.curse_new_line()) diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py index 356832f17bb242d2d8e2954cee27d4b6140e62bf..5dd5f515a0c410ea9e0537a661bdaa0e357949e3 100644 --- a/glances/plugins/glances_network.py +++ b/glances/plugins/glances_network.py @@ -19,6 +19,8 @@ """Network plugin.""" +import base64 + from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin @@ -27,9 +29,9 @@ import psutil # SNMP OID # http://www.net-snmp.org/docs/mibs/interfaces.html # Dict key = interface_name -snmp_oid = {'interface_name': '1.3.6.1.2.1.2.2.1.2', - 'cumulative_rx': '1.3.6.1.2.1.2.2.1.10', - 'cumulative_tx': '1.3.6.1.2.1.2.2.1.16'} +snmp_oid = {'default': {'interface_name': '1.3.6.1.2.1.2.2.1.2', + 'cumulative_rx': '1.3.6.1.2.1.2.2.1.10', + 'cumulative_tx': '1.3.6.1.2.1.2.2.1.16'}} class Plugin(GlancesPlugin): @@ -94,7 +96,7 @@ class Plugin(GlancesPlugin): for net in network_new: try: # Try necessary to manage dynamic network interface - netstat = {} + netstat = {} netstat['interface_name'] = net netstat['time_since_update'] = time_since_update netstat['cumulative_rx'] = network_new[net].bytes_recv @@ -118,7 +120,12 @@ class Plugin(GlancesPlugin): # Update stats using SNMP # SNMP bulk command to get all network interface in one shot - netiocounters = self.set_stats_snmp(snmp_oid=snmp_oid, bulk=True) + try: + netiocounters = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + bulk=True) + except KeyError: + netiocounters = self.set_stats_snmp(snmp_oid=snmp_oid['default'], + bulk=True) # Previous network interface stats are stored in the network_old variable if not hasattr(self, 'network_old'): @@ -138,7 +145,15 @@ class Plugin(GlancesPlugin): try: # Try necessary to manage dynamic network interface netstat = {} - netstat['interface_name'] = net + # Windows: a tips is needed to convert HEX to TXT + # http://blogs.technet.com/b/networking/archive/2009/12/18/how-to-query-the-list-of-network-interfaces-using-snmp-via-the-ifdescr-counter.aspx + if self.get_short_system_name() == 'windows': + try: + netstat['interface_name'] = str(base64.b16decode(net[2:-2].upper())) + except TypeError: + netstat['interface_name'] = net + else: + netstat['interface_name'] = net netstat['time_since_update'] = time_since_update netstat['cumulative_rx'] = float(network_new[net]['cumulative_rx']) netstat['rx'] = (float(network_new[net]['cumulative_rx']) - diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index a1daf1c99324f648bfc8f63c6e61d1614eac3371..dd439b8f783642f89368bf2f290dcac2878e28b7 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -44,6 +44,7 @@ class GlancesPlugin(object): # Init the input method self.input_method = 'local' + self.short_system_name = None # Init the stats list self.stats = None @@ -59,20 +60,27 @@ class GlancesPlugin(object): """Return the human-readable stats.""" return str(self.stats) - def set_input(self, input_method): + def set_input(self, input_method, short_system_name=None): """Set the input method. * local: system local grab (psutil or direct access) * snmp: Client server mode via SNMP * glances: Client server mode via Glances API + + For SNMP, short_system_name is detected short OS name """ self.input_method = input_method + self.short_system_name = short_system_name return self.input_method def get_input(self): """Get the input method.""" return self.input_method + def get_short_system_name(self): + """Get the short detected OS name""" + return self.short_system_name + def set_stats(self, input_stats): """Set the stats to input_stats.""" self.stats = input_stats diff --git a/glances/plugins/glances_system.py b/glances/plugins/glances_system.py index d51ace3c7499d331b410804e0f3b63865cf65bcf..efb8bf304aeef26e476fbe7e1c08c040a0550674 100644 --- a/glances/plugins/glances_system.py +++ b/glances/plugins/glances_system.py @@ -22,13 +22,25 @@ # Import system libs import os import platform +import re # Import Glances libs from glances.plugins.glances_plugin import GlancesPlugin # SNMP OID -snmp_oid = {'hostname': '1.3.6.1.2.1.1.5.0', - 'os_name': '1.3.6.1.2.1.1.1.0'} +snmp_oid = {'default': {'hostname': '1.3.6.1.2.1.1.5.0', + 'system_name': '1.3.6.1.2.1.1.1.0'}} + +# SNMP to human read +# Dict (key: OS short name) of dict (reg exp OID to human) +# Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx +snmp_to_human = {'windows': {'Windows Version 6.3': 'Windows 8.1 or Server 2012R2', + 'Windows Version 6.2': 'Windows 8 or Server 2012', + 'Windows Version 6.1': 'Windows 7 or Server 2008R2', + 'Windows Version 6.0': 'Windows Vista or Server 2008', + 'Windows Version 5.2': 'Windows XP 64bits or 2003 server', + 'Windows Version 5.1': 'Windows XP', + 'Windows Version 5.0': 'Windows 2000'}} class Plugin(GlancesPlugin): @@ -90,7 +102,18 @@ class Plugin(GlancesPlugin): self.stats['os_version'] = "" elif self.get_input() == 'snmp': # Update stats using SNMP - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid) + try: + self.stats = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()]) + except KeyError: + self.stats = self.set_stats_snmp(snmp_oid=snmp_oid['default']) + # Default behavor: display all the information + self.stats['os_name'] = self.stats['system_name'] + # Windows OS tips + if self.get_short_system_name() == 'windows': + for r,v in snmp_to_human['windows'].iteritems(): + if re.search(r, self.stats['system_name']): + self.stats['os_name'] = v + break return self.stats