Split stats in several files

This commit is contained in:
nicolargo 2016-03-20 15:03:02 +01:00
parent 98d1e5cc4c
commit 37a95425c5
6 changed files with 249 additions and 175 deletions

View File

@ -26,7 +26,7 @@ import sys
from glances.compat import Fault, ProtocolError, ServerProxy, Transport from glances.compat import Fault, ProtocolError, ServerProxy, Transport
from glances.globals import version from glances.globals import version
from glances.logger import logger from glances.logger import logger
from glances.stats import GlancesStatsClient from glances.stats_client import GlancesStatsClient
from glances.outputs.glances_curses import GlancesCursesClient from glances.outputs.glances_curses import GlancesCursesClient
@ -139,7 +139,7 @@ class GlancesClient(object):
if self.client_mode == 'snmp': if self.client_mode == 'snmp':
logger.info("Trying to grab stats by SNMP...") logger.info("Trying to grab stats by SNMP...")
from glances.stats import GlancesStatsClientSNMP from glances.stats_client_snmp import GlancesStatsClientSNMP
# Init stats # Init stats
self.stats = GlancesStatsClientSNMP(config=self.config, args=self.args) self.stats = GlancesStatsClientSNMP(config=self.config, args=self.args)

View File

@ -28,7 +28,7 @@ from glances.compat import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
from glances.autodiscover import GlancesAutoDiscoverClient from glances.autodiscover import GlancesAutoDiscoverClient
from glances.globals import version from glances.globals import version
from glances.logger import logger from glances.logger import logger
from glances.stats import GlancesStatsServer from glances.stats_server import GlancesStatsServer
from glances.timer import Timer from glances.timer import Timer

View File

@ -2,7 +2,7 @@
# #
# This file is part of Glances. # This file is part of Glances.
# #
# Copyright (C) 2015 Nicolargo <nicolas@nicolargo.com> # Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
# #
# Glances is free software; you can redistribute it and/or modify # Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by # it under the terms of the GNU Lesser General Public License as published by
@ -21,23 +21,12 @@
import collections import collections
import os import os
import re
import sys import sys
import threading import threading
from glances.compat import iteritems
from glances.globals import exports_path, plugins_path, sys_path from glances.globals import exports_path, plugins_path, sys_path
from glances.logger import logger from glances.logger import logger
# SNMP OID regexp pattern to short system name dict
oid_to_short_system_name = {'.*Linux.*': 'linux',
'.*Darwin.*': 'mac',
'.*BSD.*': 'bsd',
'.*Windows.*': 'windows',
'.*Cisco.*': 'cisco',
'.*VMware ESXi.*': 'esxi',
'.*NetApp.*': 'netapp'}
class GlancesStats(object): class GlancesStats(object):
@ -240,163 +229,3 @@ class GlancesStats(object):
# Close plugins # Close plugins
for p in self._plugins: for p in self._plugins:
self._plugins[p].exit() self._plugins[p].exit()
class GlancesStatsServer(GlancesStats):
"""This class stores, updates and gives stats for the server."""
def __init__(self, config=None):
# Init the stats
super(GlancesStatsServer, self).__init__(config)
# Init the all_stats dict used by the server
# all_stats is a dict of dicts filled by the server
self.all_stats = collections.defaultdict(dict)
def update(self, input_stats=None):
"""Update the stats."""
input_stats = input_stats or {}
# Force update of all the stats
super(GlancesStatsServer, self).update()
# Build all_stats variable (concatenation of all the stats)
self.all_stats = self._set_stats(input_stats)
def _set_stats(self, input_stats):
"""Set the stats to the input_stats one."""
# Build the all_stats with the get_raw() method of the plugins
ret = collections.defaultdict(dict)
for p in self._plugins:
ret[p] = self._plugins[p].get_raw()
return ret
def getAll(self):
"""Return the stats as a list."""
return self.all_stats
def getAllAsDict(self):
"""Return the stats as a dict."""
# Python > 2.6
# return {p: self.all_stats[p] for p in self._plugins}
ret = {}
for p in self._plugins:
ret[p] = self.all_stats[p]
return ret
class GlancesStatsClient(GlancesStats):
"""This class stores, updates and gives stats for the client."""
def __init__(self, config=None, args=None):
"""Init the GlancesStatsClient class."""
super(GlancesStatsClient, self).__init__()
# Init the configuration
self.config = config
# Init the arguments
self.args = args
# Load plugins and exports
self.load_plugins_and_exports(self.args)
def set_plugins(self, input_plugins):
"""Set the plugin list according to the Glances server."""
header = "glances_"
for item in input_plugins:
# Import the plugin
plugin = __import__(header + item)
# Add the plugin to the dictionary
# The key is the plugin name
# for example, the file glances_xxx.py
# generate self._plugins_list["xxx"] = ...
logger.debug("Server uses {0} plugin".format(item))
self._plugins[item] = plugin.Plugin()
# Restoring system path
sys.path = sys_path
def update(self, input_stats):
"""Update all the stats."""
# For Glances client mode
for p in input_stats:
# Update plugin stats with items sent by the server
self._plugins[p].set_stats(input_stats[p])
# Update the views for the updated stats
self._plugins[p].update_views()
class GlancesStatsClientSNMP(GlancesStats):
"""This class stores, updates and gives stats for the SNMP client."""
def __init__(self, config=None, args=None):
super(GlancesStatsClientSNMP, self).__init__()
# Init the configuration
self.config = config
# Init the arguments
self.args = args
# OS name is used because OID is differents between system
self.os_name = None
# Load plugins and export modules
self.load_plugins_and_exports(self.args)
def check_snmp(self):
"""Chek if SNMP is available on the server."""
# Import the SNMP client class
from glances.snmp import GlancesSNMPClient
# Create an instance of the SNMP client
clientsnmp = GlancesSNMPClient(host=self.args.client,
port=self.args.snmp_port,
version=self.args.snmp_version,
community=self.args.snmp_community,
user=self.args.snmp_user,
auth=self.args.snmp_auth)
# If we cannot 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'])
logger.info("SNMP system name detected: {0}".format(self.system_name))
except KeyError:
self.system_name = None
logger.warning("Cannot detect SNMP system name")
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 iteritems(oid_to_short_system_name):
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].input_method = 'snmp'
self._plugins[p].short_system_name = self.system_name
try:
self._plugins[p].update()
except Exception as e:
logger.error("Update {0} failed: {1}".format(p, e))

68
glances/stats_client.py Normal file
View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The stats server manager."""
import sys
from glances.stats import GlancesStats
from glances.globals import sys_path
from glances.logger import logger
class GlancesStatsClient(GlancesStats):
"""This class stores, updates and gives stats for the client."""
def __init__(self, config=None, args=None):
"""Init the GlancesStatsClient class."""
super(GlancesStatsClient, self).__init__()
# Init the configuration
self.config = config
# Init the arguments
self.args = args
# Load plugins and exports
self.load_plugins_and_exports(self.args)
def set_plugins(self, input_plugins):
"""Set the plugin list according to the Glances server."""
header = "glances_"
for item in input_plugins:
# Import the plugin
plugin = __import__(header + item)
# Add the plugin to the dictionary
# The key is the plugin name
# for example, the file glances_xxx.py
# generate self._plugins_list["xxx"] = ...
logger.debug("Server uses {0} plugin".format(item))
self._plugins[item] = plugin.Plugin()
# Restoring system path
sys.path = sys_path
def update(self, input_stats):
"""Update all the stats."""
# For Glances client mode
for p in input_stats:
# Update plugin stats with items sent by the server
self._plugins[p].set_stats(input_stats[p])
# Update the views for the updated stats
self._plugins[p].update_views()

View File

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The stats manager."""
import re
from glances.stats import GlancesStats
from glances.compat import iteritems
from glances.logger import logger
# SNMP OID regexp pattern to short system name dict
oid_to_short_system_name = {'.*Linux.*': 'linux',
'.*Darwin.*': 'mac',
'.*BSD.*': 'bsd',
'.*Windows.*': 'windows',
'.*Cisco.*': 'cisco',
'.*VMware ESXi.*': 'esxi',
'.*NetApp.*': 'netapp'}
class GlancesStatsClientSNMP(GlancesStats):
"""This class stores, updates and gives stats for the SNMP client."""
def __init__(self, config=None, args=None):
super(GlancesStatsClientSNMP, self).__init__()
# Init the configuration
self.config = config
# Init the arguments
self.args = args
# OS name is used because OID is differents between system
self.os_name = None
# Load plugins and export modules
self.load_plugins_and_exports(self.args)
def check_snmp(self):
"""Chek if SNMP is available on the server."""
# Import the SNMP client class
from glances.snmp import GlancesSNMPClient
# Create an instance of the SNMP client
clientsnmp = GlancesSNMPClient(host=self.args.client,
port=self.args.snmp_port,
version=self.args.snmp_version,
community=self.args.snmp_community,
user=self.args.snmp_user,
auth=self.args.snmp_auth)
# If we cannot 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'])
logger.info("SNMP system name detected: {0}".format(self.system_name))
except KeyError:
self.system_name = None
logger.warning("Cannot detect SNMP system name")
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 iteritems(oid_to_short_system_name):
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].input_method = 'snmp'
self._plugins[p].short_system_name = self.system_name
try:
self._plugins[p].update()
except Exception as e:
logger.error("Update {0} failed: {1}".format(p, e))

68
glances/stats_server.py Normal file
View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The stats server manager."""
import collections
from glances.stats import GlancesStats
class GlancesStatsServer(GlancesStats):
"""This class stores, updates and gives stats for the server."""
def __init__(self, config=None):
# Init the stats
super(GlancesStatsServer, self).__init__(config)
# Init the all_stats dict used by the server
# all_stats is a dict of dicts filled by the server
self.all_stats = collections.defaultdict(dict)
def update(self, input_stats=None):
"""Update the stats."""
input_stats = input_stats or {}
# Force update of all the stats
super(GlancesStatsServer, self).update()
# Build all_stats variable (concatenation of all the stats)
self.all_stats = self._set_stats(input_stats)
def _set_stats(self, input_stats):
"""Set the stats to the input_stats one."""
# Build the all_stats with the get_raw() method of the plugins
ret = collections.defaultdict(dict)
for p in self._plugins:
ret[p] = self._plugins[p].get_raw()
return ret
def getAll(self):
"""Return the stats as a list."""
return self.all_stats
def getAllAsDict(self):
"""Return the stats as a dict."""
# Python > 2.6
# return {p: self.all_stats[p] for p in self._plugins}
ret = {}
for p in self._plugins:
ret[p] = self.all_stats[p]
return ret