Merge branch 'release/v2.0' of github.com:nicolargo/glances into release/v2.0

This commit is contained in:
Nicolargo 2014-06-13 20:15:31 +02:00
commit 8b637e91f1
41 changed files with 579 additions and 915 deletions

View File

@ -17,9 +17,7 @@
# 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/>.
"""
Init the Glances software
"""
"""Init the Glances software."""
__appname__ = 'glances'
__version__ = '2.0'
@ -54,17 +52,12 @@ from glances.core.glances_main import GlancesMain
def __signal_handler(signal, frame):
"""
Call back for CTRL-C
"""
"""Callback for CTRL-C."""
end()
def end():
"""
Stop Glances
"""
"""Stop Glances."""
if core.is_standalone():
# Stop the standalone (CLI)
standalone.end()
@ -80,8 +73,7 @@ def end():
def main():
"""
Main entry point for Glances
"""Main entry point for Glances.
Select the mode (standalone, client or server)
Run it...

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Manage the Glances' client
"""
"""Manage the Glances client."""
# Import system libs
import json
@ -36,9 +35,8 @@ from glances.outputs.glances_curses import GlancesCurses
class GlancesClient(object):
"""
This class creates and manages the TCP client
"""
"""This class creates and manages the TCP client."""
def __init__(self, config=None, args=None):
# Store the arg/config
@ -63,8 +61,8 @@ class GlancesClient(object):
sys.exit(2)
def set_mode(self, mode='glances'):
"""
Set the client mode
"""Set the client mode.
- 'glances' = Glances server (default)
- 'snmp' = SNMP (fallback)
"""
@ -72,18 +70,15 @@ class GlancesClient(object):
return self.mode
def get_mode(self):
"""
Return the client mode
"""Get the client mode.
- 'glances' = Glances server (default)
- 'snmp' = SNMP (fallback)
"""
return self.mode
def login(self):
"""
Logon to the server
"""
"""Logon to the server."""
ret = True
# First of all, trying to connect to a Glances server
@ -132,13 +127,7 @@ class GlancesClient(object):
return ret
def update(self):
"""
Get stats from server
Return the client/server connection status:
- Connected: Connection OK
- Disconnected: Connection NOK
"""
# Update the stats
"""Update stats from Glances/SNMP server."""
if self.get_mode() == 'glances':
return self.update_glances()
elif self.get_mode() == 'snmp':
@ -148,8 +137,8 @@ class GlancesClient(object):
sys.exit(2)
def update_glances(self):
"""
Get stats from Glances server
"""Get stats from Glances server.
Return the client/server connection status:
- Connected: Connection OK
- Disconnected: Connection NOK
@ -159,7 +148,7 @@ class GlancesClient(object):
server_stats = json.loads(self.client.getAll())
server_stats['monitor'] = json.loads(self.client.getAllMonitored())
except socket.error:
# Client can not get server stats
# Client cannot get server stats
return "Disconnected"
else:
# Put it in the internal dict
@ -167,8 +156,8 @@ class GlancesClient(object):
return "Connected"
def update_snmp(self):
"""
Get stats from SNMP server
"""Get stats from SNMP server.
Return the client/server connection status:
- SNMP: Connection with SNMP server OK
- Disconnected: Connection NOK
@ -184,9 +173,7 @@ class GlancesClient(object):
return "SNMP"
def serve_forever(self):
"""
Main client loop
"""
"""Main client loop."""
while True:
# Update the stats
cs_status = self.update()
@ -197,7 +184,5 @@ class GlancesClient(object):
# print self.stats.getAll()
def end(self):
"""
End of the client session
"""
"""End of the client session."""
self.screen.end()

View File

@ -17,6 +17,8 @@
# 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/>.
"""Manage the configuration file."""
# Import system libs
import os
import sys
@ -41,8 +43,8 @@ from glances.core.glances_globals import (
class Config(object):
"""
This class is used to access/read config file, if it exists
"""This class is used to access/read config file, if it exists.
:param location: the custom path to search for config file
:type location: str or None
@ -56,9 +58,7 @@ class Config(object):
self.load()
def load(self):
"""
Load a config file from the list of paths, if it exists
"""
"""Load a config file from the list of paths, if it exists."""
for config_file in self.get_config_paths():
if os.path.isfile(config_file) and os.path.getsize(config_file) > 0:
try:
@ -73,9 +73,9 @@ class Config(object):
break
def get_config_paths(self):
"""
Get a list of config file paths, taking into account of the OS,
priority and location.
r"""Get a list of config file paths.
The list is built taking into account of the OS, priority and location.
* running from source: /path/to/glances/conf
* Linux: ~/.config/glances, /etc/glances
@ -119,21 +119,15 @@ class Config(object):
return paths
def items(self, section):
"""
Return the items list of a section
"""
"""Return the items list of a section."""
return self.parser.items(section)
def has_section(self, section):
"""
Return info about the existence of a section
"""
"""Return info about the existence of a section."""
return self.parser.has_section(section)
def get_option(self, section, option):
"""
Get the float value of an option, if it exists
"""
"""Get the float value of an option, if it exists."""
try:
value = self.parser.getfloat(section, option)
except NoOptionError:
@ -142,9 +136,7 @@ class Config(object):
return value
def get_raw_option(self, section, option):
"""
Get the raw value of an option, if it exists
"""
"""Get the raw value of an option, if it exists."""
try:
value = self.parser.get(section, option)
except NoOptionError:

View File

@ -17,6 +17,8 @@
# 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/>.
"""Common objects shared by all Glances modules."""
import os
import sys

View File

@ -17,6 +17,8 @@
# 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/>.
"""Manage logs."""
# Import system libs
import time
from datetime import datetime
@ -26,13 +28,14 @@ from glances.core.glances_globals import glances_processes
class GlancesLogs(object):
"""
Manage logs inside the Glances software
Logs is a list of list (stored in the self.logs_list var)
"""This class manages logs inside the Glances software.
Logs is a list of list (stored in the self.logs_list var)
item_state = "OK|CAREFUL|WARNING|CRITICAL"
item_type = "CPU*|LOAD|MEM|MON"
item_value = value
Item is defined by:
["begin",
"end",
@ -44,10 +47,7 @@ class GlancesLogs(object):
"""
def __init__(self):
"""
Init the logs class
"""
"""Init the logs class."""
# Maximum size of the logs list
self.logs_max = 10
@ -55,24 +55,20 @@ class GlancesLogs(object):
self.logs_list = []
def get(self):
"""
Return the logs list (RAW)
"""
"""Return the raw logs list."""
return self.logs_list
def len(self):
"""
Return the number of item in the log list
"""
"""Return the number of item in the logs list."""
return self.logs_list.__len__()
def __itemexist__(self, item_type):
"""
"""Return the item position, if it exists.
An item exist in the list if:
* end is < 0
* item_type is matching
Return the item position if exist
-1 if the item is not found
Return -1 if the item is not found.
"""
for i in range(self.len()):
if self.logs_list[i][1] < 0 and self.logs_list[i][3] == item_type:
@ -80,9 +76,7 @@ class GlancesLogs(object):
return -1
def set_process_sort(self, item_type):
"""
Define the process auto sort key from the alert type
"""
"""Define the process auto sort key from the alert type."""
# Process sort depending on alert type
if item_type.startswith("MEM"):
# Sort TOP process by memory_percent
@ -99,9 +93,7 @@ class GlancesLogs(object):
return process_auto_by
def reset_process_sort(self):
"""
Reset the process_auto_by variable
"""
"""Reset the process_auto_by variable."""
# Default sort is...
process_auto_by = 'cpu_percent'
@ -110,11 +102,11 @@ class GlancesLogs(object):
return process_auto_by
def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""):
"""
If item is a 'new one':
Add the new item at the beginning of the logs list
Else:
Update the existing item
"""Add a new item to the logs list.
If 'item' is a 'new one', add the new item at the beginning of the logs
list.
If 'item' is not a 'new one', update the existing item.
"""
# Add or update the log
item_index = self.__itemexist__(item_type)
@ -190,8 +182,8 @@ class GlancesLogs(object):
return self.len()
def clean(self, critical=False):
"""
Clean the log list by deleting finished item
"""Clean the logs list by deleting finished items.
By default, only delete WARNING message
If critical = True, also delete CRITICAL message
"""

View File

@ -16,26 +16,20 @@
#
# 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/>.
"""
Main Glances script
"""
"""Glances main class."""
# Import system libs
import argparse
# Import Glances libs
from glances.core.glances_config import Config
from glances.core.glances_globals import (
appname,
psutil_version,
version
)
from glances.core.glances_globals import appname, psutil_version, version
class GlancesMain(object):
"""
Main class to manage Glances instance
"""
"""Main class to manage Glances instance."""
# Default stats' refresh time is 3 seconds
refresh_time = 3
@ -161,7 +155,6 @@ class GlancesMain(object):
self.server_ip = args.client
# /!!!
# Interactive cmds like CLI args?
# By default help is hidden
args.help_tag = False
@ -172,9 +165,7 @@ class GlancesMain(object):
return args
def __hash_password(self, plain_password):
"""
Hash a plain password and return the hashed one
"""
"""Hash a plain password and return the hashed one."""
from glances.core.glances_password import GlancesPassword
password = GlancesPassword()
@ -182,10 +173,10 @@ class GlancesMain(object):
return password.hash_password(plain_password)
def __get_password(self, description='', confirm=False, clear=False):
"""
Read a password from the command line
- with confirmation if confirm = True
- plain (clear password) if clear = True
"""Read a password from the command line.
- if confirm = True, with confirmation
- if clear = True, plain (clear password)
"""
from glances.core.glances_password import GlancesPassword
@ -194,37 +185,25 @@ class GlancesMain(object):
return password.get_password(description, confirm, clear)
def is_standalone(self):
"""
Return True if Glances is running in standalone mode
"""
"""Return True if Glances is running in standalone mode."""
return not self.client_tag and not self.server_tag and not self.webserver_tag
def is_client(self):
"""
Return True if Glances is running in client mode
"""
"""Return True if Glances is running in client mode."""
return self.client_tag and not self.server_tag
def is_server(self):
"""
Return True if Glances is running in server mode
"""
"""Return True if Glances is running in server mode."""
return not self.client_tag and self.server_tag
def is_webserver(self):
"""
Return True if Glances is running in Web server mode
"""
"""Return True if Glances is running in Web server mode."""
return not self.client_tag and self.webserver_tag
def get_config(self):
"""
Return configuration file object
"""
"""Return configuration file object."""
return self.config
def get_args(self):
"""
Return the arguments
"""
"""Return the arguments."""
return self.args

View File

@ -17,6 +17,8 @@
# 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/>.
"""Manage the monitor list."""
# Import system lib
import re
import subprocess
@ -26,28 +28,27 @@ from glances.core.glances_globals import glances_processes
class MonitorList(object):
"""
This class describes the optionnal monitored processes list
A list of 'important' processes to monitor.
The list (Python list) is composed of items (Python dict)
An item is defined (Dict keys'):
"""This class describes the optional monitored processes list.
The monitored list is a list of 'important' processes to monitor.
The list (Python list) is composed of items (Python dict).
An item is defined (dict keys):
* description: Description of the processes (max 16 chars)
* regex: regular expression of the processes to monitor
* command: (optional) shell command for extended stat
* countmin: (optional) minimal number of processes
* countmax: (optional) maximum number of processes
"""
# Maximum number of items in the list
__monitor_list_max_size = 10
# The list
__monitor_list = []
def __init__(self, config):
"""
Init the monitoring list from the configuration file
"""
"""Init the monitoring list from the configuration file."""
self.config = config
if self.config is not None and self.config.has_section('monitor'):
@ -57,9 +58,9 @@ class MonitorList(object):
self.__monitor_list = []
def __set_monitor_list(self, section, key):
"""
Init the monitored processes list
The list is defined in the Glances configuration file
"""Init the monitored processes list.
The list is defined in the Glances configuration file.
"""
for l in range(1, self.__monitor_list_max_size + 1):
value = {}
@ -99,9 +100,9 @@ class MonitorList(object):
return len(self.__monitor_list)
def __get__(self, item, key):
"""
Meta function to return key value of item
None if not defined or item > len(list)
"""Meta function to return key value of item.
Return None if not defined or item > len(list)
"""
if item < len(self.__monitor_list):
try:
@ -112,15 +113,12 @@ class MonitorList(object):
return None
def update(self):
"""
Update the command result attributed
"""
"""Update the command result attributed."""
# Only continue if monitor list is not empty
if len(self.__monitor_list) == 0:
return self.__monitor_list
# Iter uppon the monitored list
# Iter upon the monitored list
for i in range(0, len(self.get())):
# Search monitored processes by a regular expression
processlist = glances_processes.getlist()
@ -147,15 +145,11 @@ class MonitorList(object):
return self.__monitor_list
def get(self):
"""
Return the monitored list (list of dict)
"""
"""Return the monitored list (list of dict)."""
return self.__monitor_list
def set(self, newlist):
"""
Set the monitored list (list of dict)
"""
"""Set the monitored list (list of dict)."""
self.__monitor_list = newlist
def getAll(self):
@ -167,37 +161,25 @@ class MonitorList(object):
self.set(newlist)
def description(self, item):
"""
Return the description of the item number (item)
"""
"""Return the description of the item number (item)."""
return self.__get__(item, "description")
def regex(self, item):
"""
Return the regular expression of the item number (item)
"""
"""Return the regular expression of the item number (item)."""
return self.__get__(item, "regex")
def command(self, item):
"""
Return the stats command of the item number (item)
"""
"""Return the stat command of the item number (item)."""
return self.__get__(item, "command")
def result(self, item):
"""
Return the reult command of the item number (item)
"""
"""Return the reult command of the item number (item)."""
return self.__get__(item, "result")
def countmin(self, item):
"""
Return the minimum number of processes of the item number (item)
"""
"""Return the minimum number of processes of the item number (item)."""
return self.__get__(item, "countmin")
def countmax(self, item):
"""
Return the maximum number of processes of the item number (item)
"""
"""Return the maximum number of processes of the item number (item)."""
return self.__get__(item, "countmax")

View File

@ -17,6 +17,8 @@
# 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/>.
"""Manage password."""
# Import system libs
import getpass
import hashlib
@ -41,9 +43,8 @@ except NameError:
class GlancesPassword(object):
"""
Manage password
"""
"""This class contains all the methods relating to password."""
def __init__(self):
self.password_path = self.get_password_path()
@ -51,8 +52,8 @@ class GlancesPassword(object):
self.password_filepath = os.path.join(self.password_path, self.password_filename)
def get_password_path(self):
"""
Get the path where the password file will be stored
r"""Get the path where the password file will be stored.
* Linux and BSD: ~/.config/glances
* OS X: ~/Library/glances
* Windows: %APPDATA%\glances
@ -72,40 +73,37 @@ class GlancesPassword(object):
return app_path
def get_hash(self, salt, plain_password):
"""
Return the hashed password salt + SHA-256
"""
"""Return the hashed password, salt + SHA-256."""
return hashlib.sha256(salt.encode() + plain_password.encode()).hexdigest()
def hash_password(self, plain_password):
"""
Hash password with a salt based on UUID (universally unique identifier)
"""
"""Hash password with a salt based on UUID (universally unique identifier)."""
salt = uuid.uuid4().hex
encrypted_password = self.get_hash(salt, plain_password)
return salt + '$' + encrypted_password
def check_password(self, hashed_password, plain_password):
"""
Encode the plain_password with the salt of the hashed_password
and return the comparison with the encrypted_password
"""Encode the plain_password with the salt of the hashed_password.
Return the comparison with the encrypted_password.
"""
salt, encrypted_password = hashed_password.split('$')
re_encrypted_password = self.get_hash(salt, plain_password)
return encrypted_password == re_encrypted_password
def get_password(self, description='', confirm=False, clear=False):
"""
For Glances server, get the password (confirm=True, clear=False)
"""Get the password from a Glances client or server.
For Glances server, get the password (confirm=True, clear=False):
1) from the password file (if it exists)
2) from the CLI
Optionally: save the password to a file (hashed with salt + SHA-256)
For Glances client, get the password (confirm=False, clear=True)
For Glances client, get the password (confirm=False, clear=True):
1) from the CLI
2) the password is hashed with SHA-256 (only SHA string transit through the network)
2) the password is hashed with SHA-256 (only SHA string transit
through the network)
"""
if os.path.exists(self.password_filepath) and not clear:
# If the password file exist then use it
print(_("Info: Read password from file: {0}").format(self.password_filepath))
@ -142,9 +140,7 @@ class GlancesPassword(object):
return password
def save_password(self, hashed_password):
"""
Save the hashed password to the Glances folder
"""
"""Save the hashed password to the Glances folder."""
# Check if the Glances folder already exists
if not os.path.exists(self.password_path):
# Create the Glances folder
@ -159,9 +155,7 @@ class GlancesPassword(object):
file_pwd.write(hashed_password)
def load_password(self):
"""
Load the hashed password from the Glances folder
"""
"""Load the hashed password from the Glances folder."""
# Read the password file, if it exists
with open(self.password_filepath, 'r') as file_pwd:
hashed_password = file_pwd.read()

View File

@ -24,14 +24,11 @@ import psutil
class GlancesProcesses(object):
"""
Get processed stats using the PsUtil lib
"""
"""Get processed stats using the psutil library."""
def __init__(self, cache_timeout=60):
"""
Init the class to collect stats about processes
"""
"""Init the class to collect stats about processes."""
# Add internals caches because PSUtil do not cache all the stats
# See: https://code.google.com/p/psutil/issues/detail?id=462
self.username_cache = {}
@ -56,22 +53,16 @@ class GlancesProcesses(object):
self.disable_tag = False
def enable(self):
"""
Enable process stats
"""
"""Enable process stats."""
self.disable_tag = False
self.update()
def disable(self):
"""
Enable process stats
"""
"""Disable process stats."""
self.disable_tag = True
def __get_process_stats(self, proc):
"""
Get process statistics
"""
"""Get process stats."""
procstat = {}
# Process ID
@ -156,10 +147,7 @@ class GlancesProcesses(object):
return procstat
def update(self):
"""
Update the processes sats
"""
"""Update the processes stats."""
# Reset the stats
self.processlist = []
self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0}
@ -212,31 +200,24 @@ class GlancesProcesses(object):
self.cache_timer.reset()
def getcount(self):
"""Get the number of processes."""
return self.processcount
def getlist(self, sortedby=None):
"""
Return the processlist
"""
"""Get the processlist."""
return self.processlist
def getsortkey(self):
"""
Return the current sort key for automatic sort
"""
"""Get the current sort key for automatic sort."""
return self.processsort
def setsortkey(self, sortedby):
"""
Return the current sort key for automatic sort
"""
"""Set the current sort key for automatic sort."""
self.processsort = sortedby
return self.processsort
def getsortlist(self, sortedby=None):
"""
Return the processlist
"""
"""Get the sorted processlist."""
if sortedby is None:
# No need to sort...
return self.processlist

View File

@ -17,6 +17,8 @@
# 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/>.
"""Manage the Glances server."""
# Import system libs
import json
import socket
@ -36,9 +38,9 @@ from glances.core.glances_timer import Timer
class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
"""
Main XMLRPC handler
"""
"""Main XML-RPC handler."""
rpc_paths = ('/RPC2', )
def end_headers(self):
@ -66,9 +68,9 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
# Encoded portion of the header is a string
# Need to convert to bytestring
encoded_byte_string = encoded.encode()
# Decode Base64 byte String to a decoded Byte String
# Decode base64 byte string to a decoded byte string
decoded_bytes = b64decode(encoded_byte_string)
# Convert from byte string to a regular String
# Convert from byte string to a regular string
decoded_string = decoded_bytes.decode()
# Get the username and password from the string
(username, _, password) = decoded_string.partition(':')
@ -76,7 +78,7 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
return self.check_user(username, password)
def check_user(self, username, password):
# Check username and password in the dictionnary
# Check username and password in the dictionary
if username in self.server.user_dict:
from glances.core.glances_password import GlancesPassword
@ -102,9 +104,8 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
class GlancesXMLRPCServer(SimpleXMLRPCServer):
"""
Init a SimpleXMLRPCServer instance (IPv6-ready)
"""
"""Init a SimpleXMLRPCServer instance (IPv6-ready)."""
def __init__(self, bind_address, bind_port=61209,
requestHandler=GlancesXMLRPCHandler):
@ -120,9 +121,8 @@ class GlancesXMLRPCServer(SimpleXMLRPCServer):
class GlancesInstance(object):
"""
All the methods of this class are published as XML RPC methods
"""
"""All the methods of this class are published as XML-RPC methods."""
def __init__(self, cached_time=1, config=None):
# Init stats
@ -166,11 +166,10 @@ class GlancesInstance(object):
return json.dumps(self.stats.getAll()['monitor'])
def __getattr__(self, item):
"""
Overwrite the getattr in case of attribute is not found
The goal is to dynamicaly generate the API get'Stats'() methods
"""
"""Overwrite the getattr method in case of attribute is not found.
The goal is to dynamically generate the API get'Stats'() methods.
"""
# print "DEBUG: Call method: %s" % item
header = 'get'
# Check if the attribute starts with 'get'
@ -190,9 +189,8 @@ class GlancesInstance(object):
class GlancesServer(object):
"""
This class creates and manages the TCP server
"""
"""This class creates and manages the TCP server."""
def __init__(self, requestHandler=GlancesXMLRPCHandler,
cached_time=1,
@ -216,23 +214,18 @@ class GlancesServer(object):
self.server.register_instance(GlancesInstance(cached_time, config))
def add_user(self, username, password):
"""
Add an user to the dictionnary
"""
"""Add an user to the dictionary."""
self.server.user_dict[username] = password
self.server.isAuth = True
def serve_forever(self):
"""
Call the main loop
"""
"""Call the main loop."""
self.server.serve_forever()
def server_close(self):
"""Close the Glances server session."""
self.server.server_close()
def end(self):
"""
End of the Glances server session
"""
"""End of the Glances server session."""
self.server_close()

View File

@ -28,7 +28,8 @@ except ImportError:
class GlancesSNMPClient(object):
""" SNMP client class (based on PySNMP) """
"""SNMP client class (based on pysnmp library)."""
def __init__(self, host='localhost', port=161, version='2c',
community='public', user='private', auth=''):
@ -46,10 +47,7 @@ class GlancesSNMPClient(object):
self.auth = auth
def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds):
"""
Put results in table
"""
"""Put results in table."""
ret = {}
if not errorIndication or not errorStatus:
for name, val in varBinds:
@ -60,13 +58,13 @@ class GlancesSNMPClient(object):
return ret
def get_by_oid(self, *oid):
"""
SNMP simple request (list of OID)
One request per OID list
"""SNMP simple request (list of OID).
One request per OID list.
* oid: oid list
> Return a dict
"""
if self.version == '3':
errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
cmdgen.UsmUserData(self.user, self.auth),
@ -95,16 +93,19 @@ class GlancesSNMPClient(object):
return ret
def getbulk_by_oid(self, non_repeaters, max_repetitions, *oid):
"""
SNMP getbulk request
In contrast to snmpwalk, this information will typically be gathered in a
single transaction with the agent, rather than one transaction per variable found.
* non_repeaters: This specifies the number of supplied variables that should not be iterated over.
* max_repetitions: This specifies the maximum number of iterations over the repeating variables.
"""SNMP getbulk request.
In contrast to snmpwalk, this information will typically be gathered in
a single transaction with the agent, rather than one transaction per
variable found.
* non_repeaters: This specifies the number of supplied variables that
should not be iterated over.
* max_repetitions: This specifies the maximum number of iterations over
the repeating variables.
* oid: oid list
> Return a list of dicts
"""
if self.version.startswith('3'):
errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
cmdgen.UsmUserData(self.user, self.auth),

View File

@ -17,18 +17,18 @@
# 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/>.
"""Manage the Glances standalone session."""
# Import Glances libs
from glances.core.glances_stats import GlancesStats
from glances.outputs.glances_curses import GlancesCurses
class GlancesStandalone(object):
"""
This class creates and manages the Glances standalone session
"""
"""This class creates and manages the Glances standalone session."""
def __init__(self, config=None, args=None):
# Init stats
self.stats = GlancesStats(config)
@ -48,9 +48,7 @@ class GlancesStandalone(object):
self.screen = GlancesCurses(args=args)
def serve_forever(self):
"""
Main loop for the CLI
"""
"""Main loop for the CLI."""
while True:
# Update system informations
self.stats.update()
@ -63,9 +61,7 @@ class GlancesStandalone(object):
self.csvoutput.update(self.stats)
def end(self):
"""
End of the CLI
"""
"""End of the CLI."""
self.screen.end()
# Close the CSV file

View File

@ -17,6 +17,8 @@
# 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 collections
import os
import sys
@ -25,15 +27,10 @@ from glances.core.glances_globals import plugins_path, sys_path
class GlancesStats(object):
"""
This class store, update and give stats
"""
"""This class stores, updates and gives stats."""
def __init__(self, config=None):
"""
Init the stats
"""
# Init the plugin list dict
self._plugins = collections.defaultdict(dict)
@ -44,12 +41,11 @@ class GlancesStats(object):
self.load_limits(config)
def __getattr__(self, item):
"""
Overwrite the getattr in case of attribute is not found
"""Overwrite the getattr method in case of attribute is not found.
The goal is to dynamically generate the following methods:
- getPlugname(): return Plugname stat in JSON format
"""
# Check if the attribute starts with 'get'
if item.startswith('get'):
# Get the plugin name
@ -67,9 +63,7 @@ class GlancesStats(object):
raise AttributeError(item)
def load_plugins(self, args=None):
"""
Load all plugins in the "plugins" folder
"""
"""Load all plugins in the 'plugins' folder."""
header = "glances_"
for item in os.listdir(plugins_path):
if (item.startswith(header) and
@ -87,26 +81,18 @@ class GlancesStats(object):
sys.path = sys_path
def getAllPlugins(self):
"""
Return the plugins list
"""
"""Return the plugins list."""
return [p for p in self._plugins]
def load_limits(self, config=None):
"""
Load the stats limits
"""
"""Load the stats limits."""
# For each plugins, call the init_limits method
for p in self._plugins:
# print "DEBUG: Load limits for %s" % p
self._plugins[p].load_limits(config)
def __update__(self, input_stats):
"""
Update the stats
"""
"""Update all the stats."""
if input_stats == {}:
# For standalone and server modes
# For each plugins, call the update method
@ -120,21 +106,19 @@ class GlancesStats(object):
self._plugins[p].set_stats(input_stats[p])
def update(self, input_stats={}):
# Update the stats
"""Wrapper method to update the stats."""
self.__update__(input_stats)
def getAll(self):
"""
Return all the stats
"""
"""Return all the stats."""
return [self._plugins[p].get_raw() for p in self._plugins]
def get_plugin_list(self):
# Return the plugin list
"""Return the plugin list."""
self._plugins
def get_plugin(self, plugin_name):
# Return the plugin name
"""Return the plugin name."""
if plugin_name in self._plugins:
return self._plugins[plugin_name]
else:
@ -142,9 +126,8 @@ class GlancesStats(object):
class GlancesStatsServer(GlancesStats):
"""
This class store, update and give stats for the server
"""
"""This class stores, updates and gives stats for the server."""
def __init__(self, config=None):
# Init the stats
@ -155,11 +138,7 @@ class GlancesStatsServer(GlancesStats):
self.all_stats = collections.defaultdict(dict)
def update(self, input_stats={}):
"""
Update the stats
"""
# Update the stats
"""Update the stats."""
GlancesStats.update(self)
# Build the all_stats with the get_raw() method of the plugins
@ -167,37 +146,29 @@ class GlancesStatsServer(GlancesStats):
self.all_stats[p] = self._plugins[p].get_raw()
def getAll(self):
"""
Return the stats as a dict
"""
"""Return the stats as a dict."""
return self.all_stats
def getAllPlugins(self):
"""
Return the plugins list
"""
"""Return the plugins list."""
return [p for p in self._plugins]
def getAllLimits(self):
"""
Return the plugins limits list
"""
"""Return the plugins limits list."""
return [self._plugins[p].get_limits() for p in self._plugins]
class GlancesStatsClient(GlancesStats):
"""
This class store, update and give stats for the client
"""
"""This class stores, updates and gives stats for the client."""
def __init__(self):
"""Init the GlancesStatsClient class."""
# Init the plugin list dict
self._plugins = collections.defaultdict(dict)
def set_plugins(self, input_plugins):
"""
Set the plugin list according to the Glances server
"""
"""Set the plugin list according to the Glances server."""
header = "glances_"
for item in input_plugins:
# Import the plugin
@ -213,9 +184,8 @@ class GlancesStatsClient(GlancesStats):
class GlancesStatsClientSNMP(GlancesStats):
"""
This class store, update and give stats for the SNMP client
"""
"""This class stores, updates and gives stats for the SNMP client."""
def __init__(self, config=None, args=None):
# Init the plugin list dict
@ -231,10 +201,7 @@ class GlancesStatsClientSNMP(GlancesStats):
self.load_plugins(args=self.args)
def check_snmp(self):
"""
Chek if SNMP is available on the server
"""
"""Chek if SNMP is available on the server."""
# Import the SNMP client class
from glances.core.glances_snmp import GlancesSNMPClient
@ -249,10 +216,7 @@ class GlancesStatsClientSNMP(GlancesStats):
return clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {}
def update(self):
"""
Update the stats using SNMP
"""
"""Update the stats using SNMP."""
# For each plugins, call the update method
for p in self._plugins:
# Set the input method to SNMP

View File

@ -17,6 +17,8 @@
# 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 timer manager."""
from time import time
# Global list to manage the elapsed time
@ -24,6 +26,7 @@ last_update_times = {}
def getTimeSinceLastUpdate(IOType):
"""Return the elapsed time since last update."""
global last_update_times
# assert(IOType in ['net', 'disk', 'process_disk'])
current_time = time()
@ -37,10 +40,8 @@ def getTimeSinceLastUpdate(IOType):
class Timer(object):
"""
The timer class
A simple chrono
"""
"""The timer class. A simple chronometer."""
def __init__(self, duration):
self.duration = duration

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances Web Interface (Bottle based)
"""
"""Glances Web Interface (Bottle based)."""
# Import Glances libs
from glances.core.glances_stats import GlancesStats
@ -26,12 +25,10 @@ from glances.outputs.glances_bottle import GlancesBottle
class GlancesWebServer(object):
"""
This class creates and manages the Glances Web Server session
"""
"""This class creates and manages the Glances Web server session."""
def __init__(self, config=None, args=None):
# Init stats
self.stats = GlancesStats(config)
@ -42,13 +39,9 @@ class GlancesWebServer(object):
self.web = GlancesBottle(args=args)
def serve_forever(self):
"""
Main loop for the Web Server
"""
"""Main loop for the Web server."""
self.web.start(self.stats)
def end(self):
"""
End of the Web Server
"""
"""End of the Web server."""
self.web.end()

View File

@ -17,6 +17,8 @@
# 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/>.
"""Web interface class."""
import os
import sys
@ -28,12 +30,10 @@ except ImportError:
class GlancesBottle(object):
"""
This class manage the Bottle Web Server
"""
"""This class manages the Bottle Web server."""
def __init__(self, args=None):
# Init args
self.args = args
@ -72,29 +72,25 @@ class GlancesBottle(object):
}
def _route(self):
"""
Define route
"""
"""Define route."""
self._app.route('/', method="GET", callback=self._index)
self._app.route('/<refresh_time:int>', method=["GET", "POST"], callback=self._index)
self._app.route('/<filename:re:.*\.css>', method="GET", callback=self._css)
self._app.route('/<filename:re:.*\.js>', method="GET", callback=self._js)
def start(self, stats):
"""Start the bottle."""
# Init stats
self.stats = stats
# Start the Bottle
self._app.run(host=self.args.bind_address, port=self.args.port)
def end(self):
# End the Bottle
"""End the bottle."""
pass
def _index(self, refresh_time=None):
"""
Bottle callback for index.html (/) file
"""
"""Bottle callback for index.html (/) file."""
# Manage parameter
if refresh_time is None:
refresh_time = self.args.time
@ -106,26 +102,20 @@ class GlancesBottle(object):
return self.display(self.stats, refresh_time=refresh_time)
def _css(self, filename):
"""
Bottle callback for *.css files
"""
"""Bottle callback for *.css files."""
# Return the static file
return static_file(filename, root=os.path.join(self.STATIC_PATH, 'css'))
def _js(self, filename):
"""
Bottle callback for *.js files
"""
"""Bottle callback for *.js files."""
# Return the static file
return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js'))
def display(self, stats, refresh_time=None):
"""
Display stats on the Webpage
"""Display stats on the web page.
stats: Stats database to display
"""
html = template('header', refresh_time=refresh_time)
html += '<header>'
html += self.display_plugin('system', self.stats.get_plugin('system').get_stats_display(args=self.args))
@ -163,10 +153,7 @@ class GlancesBottle(object):
return html
def display_plugin(self, plugin_name, plugin_stats):
"""
Generate the Bootle template for the plugin_stats
"""
"""Generate the Bottle template for the plugin_stats."""
# Template header
tpl = """ \
%#Template for Bottle

View File

@ -17,6 +17,8 @@
# 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/>.
"""CSV interface class."""
# Import sys libs
import csv
import sys
@ -29,9 +31,8 @@ csv_stats_list = ['cpu', 'load', 'mem', 'memswap']
class GlancesCSV(object):
"""
This class manages the CSV output
"""
"""This class manages the CSV output."""
def __init__(self, args=None):
# CSV file name
@ -51,12 +52,11 @@ class GlancesCSV(object):
print(_("Stats dumped to CSV file: {0}").format(self.csv_filename))
def exit(self):
"""Close the CSV file."""
self.csv_file.close()
def update(self, stats):
"""
Update stats in the CSV output file
"""
"""Update stats in the CSV output file."""
all_stats = stats.getAll()
plugins = stats.getAllPlugins()

View File

@ -17,6 +17,8 @@
# 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/>.
"""Curses interface class."""
# Import system lib
import sys
@ -38,12 +40,10 @@ else:
class GlancesCurses(object):
"""
This class manage the curses display (and key pressed)
"""
"""This class manages the curses display (and key pressed)."""
def __init__(self, args=None):
# Init args
self.args = args
@ -161,9 +161,7 @@ class GlancesCurses(object):
self.pressedkey = -1
def __get_key(self, window):
"""
A getKey function to catch ESC key AND Numlock key (issue #163)
"""
# Catch ESC key AND numlock key (issue #163)
keycode = [0, 0]
keycode[0] = window.getch()
keycode[1] = window.getch()
@ -175,7 +173,7 @@ class GlancesCurses(object):
return keycode[0]
def __catch_key(self):
# Get key
# Catch the pressed key
# ~ self.pressedkey = self.term_window.getch()
self.pressedkey = self.__get_key(self.term_window)
@ -249,15 +247,14 @@ class GlancesCurses(object):
return self.pressedkey
def end(self):
# Shutdown the curses window
"""Shutdown the curses window."""
curses.echo()
curses.nocbreak()
curses.curs_set(1)
curses.endwin()
def display(self, stats, cs_status="None"):
"""
Display stats on the screen
"""Display stats on the screen.
stats: Stats database to display
cs_status:
@ -270,7 +267,6 @@ class GlancesCurses(object):
True if the stats have been displayed
False if the help have been displayed
"""
# Init the internal line/column dict for Glances Curses
self.line_to_y = {}
self.column_to_x = {}
@ -346,9 +342,9 @@ class GlancesCurses(object):
return True
def display_plugin(self, plugin_stats, display_optional=True, max_y=65535):
"""
Display the plugin_stats on the screen
If display_optional=True display the optional stats
"""Display the plugin_stats on the screen.
If display_optional=True display the optional stats.
max_y do not display line > max_y
"""
# Exit if:
@ -425,12 +421,12 @@ class GlancesCurses(object):
self.line_to_y[plugin_stats['line'] + 1] = y + self.space_between_line
def erase(self):
# Erase the content of the screen
"""Erase the content of the screen."""
self.term_window.erase()
def flush(self, stats, cs_status="None"):
"""
Clear and update screen
"""Clear and update the screen.
stats: Stats database to display
cs_status:
"None": standalone or server mode
@ -441,8 +437,10 @@ class GlancesCurses(object):
self.display(stats, cs_status=cs_status)
def update(self, stats, cs_status="None"):
"""
Update the screen and wait __refresh_time sec / catch key every 100 ms
"""Update the screen.
Wait for __refresh_time sec / catch key every 100 ms.
stats: Stats database to display
cs_status:
"None": standalone or server mode
@ -454,7 +452,7 @@ class GlancesCurses(object):
# Wait
countdown = Timer(self.__refresh_time)
while (not countdown.finished()):
while not countdown.finished():
# Getkey
if self.__catch_key() > -1:
# flush display
@ -463,9 +461,10 @@ class GlancesCurses(object):
curses.napms(100)
def get_stats_display_width(self, curse_msg, without_option=False):
# Return the width of the formated curses message
# The height is defined by the maximum line
"""Return the width of the formatted curses message.
The height is defined by the maximum line.
"""
try:
if without_option:
# Size without options
@ -481,9 +480,10 @@ class GlancesCurses(object):
return c
def get_stats_display_height(self, curse_msg):
# Return the height of the formated curses message
# The height is defined by the number of '\n'
r"""Return the height of the formatted curses message.
The height is defined by the number of '\n' (new line).
"""
try:
c = [i['msg'] for i in curse_msg['msgdict']].count('\n')
except:

View File

@ -17,6 +17,8 @@
# 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/>.
"""Alert plugin."""
# Import system lib
from datetime import datetime
@ -26,13 +28,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances's alert Plugin
Only for display
"""Glances' alert plugin.
Only for display.
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -48,23 +51,16 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Nothing to do here
Just return the global glances_log
"""
"""Nothing to do here. Just return the global glances_log."""
# Set the stats to the glances_logs
self.stats = glances_logs.get()
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Batinfo (battery) plugin
"""
"""Battery plugin."""
# Batinfo library (optional; Linux-only)
try:
@ -31,13 +30,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances battery capacity plugin
"""Glances' battery capacity plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# Init the sensor class
@ -51,17 +51,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update battery capacity stats using the input method
"""
"""Update battery capacity stats using the input method."""
# Reset stats
self.reset()
@ -79,14 +73,11 @@ class Plugin(GlancesPlugin):
class GlancesGrabBat(object):
"""
Get batteries stats using the Batinfo library
"""
"""Get batteries stats using the batinfo library."""
def __init__(self):
"""
Init batteries stats
"""
"""Init batteries stats."""
try:
self.bat = batinfo.batteries()
self.initok = True
@ -97,9 +88,7 @@ class GlancesGrabBat(object):
self.initok = False
def update(self):
"""
Update the stats
"""
"""Update the stats."""
if self.initok:
reply = self.bat.update()
if reply is not None:
@ -111,10 +100,11 @@ class GlancesGrabBat(object):
self.bat_list = []
def get(self):
# Update the stats
"""Get the stats."""
return self.bat_list
def getcapacitypercent(self):
"""Get batteries capacity percent."""
if not self.initok or self.bat.stat == []:
return []

View File

@ -17,20 +17,24 @@
# 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/>.
"""CPU core plugin."""
from glances.plugins.glances_plugin import GlancesPlugin
import psutil
class Plugin(GlancesPlugin):
"""
Glances' Core Plugin
Get stats about CPU core number
"""Glances' CPU core plugin.
Get stats about CPU core number.
stats is integer (number of core)
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We dot not want to display the stat in the curse interface
@ -41,17 +45,14 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stat using the input method
"""
"""Reset/init the stat using the input method."""
self.stats = {}
def update(self):
"""
Update core stats
Stats is a dict (with both physical and log cpu number) instead of a integer
"""
"""Update core stats.
Stats is a dict (with both physical and log cpu number) instead of a integer.
"""
# Reset the stats
self.reset()

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances CPU plugin
"""
"""CPU plugin."""
from glances.plugins.glances_plugin import GlancesPlugin
@ -34,13 +33,15 @@ snmp_oid = {'user': '1.3.6.1.4.1.2021.11.9.0',
class Plugin(GlancesPlugin):
"""
Glances' Cpu Plugin
Glances' CPU plugin.
stats is a dict
"""
def __init__(self, args=None):
"""Init the CPU plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -57,16 +58,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update CPU stats using the input method
"""
"""Update CPU stats using the input method."""
# Reset stats
self.reset()
@ -107,10 +103,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the list to display in the curse interface
"""
"""Return the list to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances DiskIO plugin
"""
"""Disk I/O plugin."""
# Import Glances libs
from glances.core.glances_timer import getTimeSinceLastUpdate
@ -28,13 +27,14 @@ import psutil
class Plugin(GlancesPlugin):
"""
Glances's disks IO Plugin
"""Glances' disks I/O plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -50,16 +50,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update disk IO stats using the input method
"""
"""Update disk I/O stats using the input method."""
# Reset stats
self.reset()
@ -118,10 +113,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,6 +17,8 @@
# 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/>.
"""File system plugin."""
from glances.plugins.glances_plugin import GlancesPlugin
import psutil
@ -43,13 +45,14 @@ snmp_oid = {'mnt_point': '1.3.6.1.4.1.2021.9.1.2',
class Plugin(GlancesPlugin):
"""
Glances's File System (fs) Plugin
"""Glances' file system plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -65,16 +68,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update the FS stats using the input method
"""
"""Update the FS stats using the input method."""
# Reset the list
self.reset()
@ -127,9 +125,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,6 +17,8 @@
# 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/>.
"""HDD temperature plugin."""
# Import system libs
import socket
@ -25,13 +27,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances' HDD temperature sensors plugin
"""Glances' HDD temperature sensors plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# Init the sensor class
@ -45,16 +48,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update HDD stats using the input method
"""
"""Update HDD stats using the input method."""
# Reset stats
self.reset()
@ -71,24 +69,24 @@ class Plugin(GlancesPlugin):
class GlancesGrabHDDTemp(object):
"""
Get hddtemp stats using a socket connection
"""
def __init__(self, host="127.0.0.1", port=7634):
"""
Init hddtemp stats
"""
"""Get hddtemp stats using a socket connection."""
def __init__(self, host='127.0.0.1', port=7634):
"""Init hddtemp stats."""
self.host = host
self.port = port
self.cache = ""
self.reset()
def reset(self):
"""Reset/init the stats."""
self.hddtemp_list = []
def __update__(self):
"""
Update the stats
"""
"""Update the stats."""
# Reset the list
self.hddtemp_list = []
self.reset()
# Fetch the data
data = self.fetch()
@ -118,9 +116,7 @@ class GlancesGrabHDDTemp(object):
self.hddtemp_list.append(hddtemp_current)
def fetch(self):
"""
Fetch the data from hddtemp daemon
"""
"""Fetch the data from hddtemp daemon."""
# Taking care of sudden deaths/stops of hddtemp daemon
try:
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -133,5 +129,6 @@ class GlancesGrabHDDTemp(object):
return data
def get(self):
"""Get HDDs list."""
self.__update__()
return self.hddtemp_list

View File

@ -16,26 +16,24 @@
#
# 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/>.
"""
Glances help plugin
Just a stupid plugin to display the help screen
Help plugin.
Just a stupid plugin to display the help screen.
"""
# Import Glances libs
from glances.core.glances_globals import (
appname,
psutil_version,
version
)
from glances.core.glances_globals import appname, psutil_version, version
from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances' Help Plugin
"""
"""Glances' help plugin."""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -48,16 +46,11 @@ class Plugin(GlancesPlugin):
self.line_curse = 0
def update(self):
"""
No stats, it is just a plugin to display the help...
"""
"""No stats. It is just a plugin to display the help."""
pass
def msg_curse(self, args=None):
"""
Return the list to display in the curse interface
"""
"""Return the list to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances load plugin
"""
"""Load plugin."""
# Import system libs
import os
@ -37,13 +36,14 @@ snmp_oid = {'min1': '1.3.6.1.4.1.2021.10.1.3.1',
class Plugin(GlancesPlugin):
"""
Glances's Load Plugin
"""Glances' load plugin.
stats is a dict
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -59,16 +59,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update load stats
"""
"""Update load stats."""
# Reset stats
self.reset()
@ -107,10 +102,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances virtual memory plugin
"""
"""Virtual memory plugin."""
from glances.plugins.glances_plugin import GlancesPlugin
@ -40,13 +39,14 @@ snmp_oid = {'total': '1.3.6.1.4.1.2021.4.5.0',
class Plugin(GlancesPlugin):
"""
Glances's memory Plugin
"""Glances' memory plugin.
stats is a dict
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -62,16 +62,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update MEM (RAM) stats using the input method
"""
"""Update RAM memory stats using the input method."""
# Reset stats
self.reset()
@ -133,9 +128,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances swap memory plugin
"""
"""Swap memory plugin."""
from glances.plugins.glances_plugin import GlancesPlugin
@ -32,13 +31,14 @@ snmp_oid = {'total': '1.3.6.1.4.1.2021.4.3.0',
class Plugin(GlancesPlugin):
"""
Glances's swap memory Plugin
"""Glances' swap memory plugin.
stats is a dict
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -54,16 +54,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update MEM (SWAP) stats using the input method
"""
"""Update swap memory stats using the input method."""
# Reset stats
self.reset()
@ -104,9 +99,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,17 +17,19 @@
# 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/>.
"""Monitor plugin."""
# Import Glances lib
from glances.core.glances_monitor_list import MonitorList as glancesMonitorList
from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances's monitor Plugin
"""
"""Glances' monitor plugin."""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -44,17 +46,12 @@ class Plugin(GlancesPlugin):
self.stats = []
def load_limits(self, config):
"""
Load the monitored list from the conf file
"""
"""Load the monitored list from the conf file."""
# print "DEBUG: Monitor plugin load config file %s" % config
self.glances_monitors = glancesMonitorList(config)
def update(self):
"""
Update the monitored list
"""
"""Update the monitored list."""
if self.get_input() == 'local':
# Monitor list only available in a full Glances environment
# Check if the glances_monitor instance is init
@ -72,7 +69,7 @@ class Plugin(GlancesPlugin):
return self.stats
def get_alert(self, nbprocess=0, countmin=None, countmax=None, header="", log=False):
# Return the alert status relative to the process number
"""Return the alert status relative to the process number."""
if nbprocess is None:
return 'OK'
if countmin is None:
@ -91,9 +88,7 @@ class Plugin(GlancesPlugin):
return 'CRITICAL'
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances Network interface plugin
"""
"""Network plugin."""
from glances.core.glances_timer import getTimeSinceLastUpdate
from glances.plugins.glances_plugin import GlancesPlugin
@ -34,13 +33,14 @@ snmp_oid = {'interface_name': '1.3.6.1.2.1.2.2.1.2',
class Plugin(GlancesPlugin):
"""
Glances's network Plugin
"""Glances' network Plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -56,17 +56,14 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update network stats using the input method
"""Update network stats using the input method.
Stats is a list of dict (one dict per interface)
"""
# Reset stats
self.reset()
@ -163,10 +160,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to displayoid in the curse interface
"""
"""Return the dict to display in the curse interface."""
# !!! TODO: Add alert on network interface bitrate
# Init the return message

View File

@ -25,14 +25,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances' Core Plugin
Get current date/time
"""Plugin to get the current date/time.
stats is (string)
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -45,19 +45,14 @@ class Plugin(GlancesPlugin):
self.line_curse = -1
def update(self):
"""
Update current date/time
"""
"""Update current date/time."""
# Had to convert it to string because datetime is not JSON serializable
self.stats = datetime.now().strftime(_("%Y-%m-%d %H:%M:%S"))
return self.stats
def msg_curse(self, args=None):
"""
Return the string to display in the curse interface
"""
"""Return the string to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
CPU stats (per cpu)
"""
"""Per-CPU plugin."""
# Import Glances libs
from glances.plugins.glances_plugin import GlancesPlugin
@ -28,13 +27,14 @@ import psutil
class Plugin(GlancesPlugin):
"""
Glances' PerCpu Plugin
"""Glances' per-CPU plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -52,16 +52,11 @@ class Plugin(GlancesPlugin):
self.percputime_new = []
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update Per CPU stats using the input method
"""
"""Update per-CPU stats using the input method."""
# Reset stats
self.reset()
@ -138,10 +133,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -16,9 +16,11 @@
#
# 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/>.
"""
I am your father...
For all Glances plugins
...for all Glances plugins.
"""
# Import system libs
@ -29,11 +31,11 @@ from glances.core.glances_globals import glances_logs
class GlancesPlugin(object):
"""
Main class for Glances' plugin
"""
"""Main class for Glances' plugin."""
def __init__(self, args=None):
"""Init the plugin of plugins class."""
# Plugin name (= module name without glances_)
self.plugin_name = self.__class__.__module__[len('glances_'):]
@ -50,17 +52,17 @@ class GlancesPlugin(object):
self.limits = dict()
def __repr__(self):
# Return the raw stats
"""Return the raw stats."""
return self.stats
def __str__(self):
# Return the human-readable stats
"""Return the human-readable stats."""
return str(self.stats)
def set_input(self, input_method):
"""
Set the input method:
* local: system local grab (PSUtil or direct access)
"""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
"""
@ -68,19 +70,19 @@ class GlancesPlugin(object):
return self.input_method
def get_input(self):
"""
Get the input method
"""
"""Get the input method."""
return self.input_method
def set_stats(self, input_stats):
# Set the stats to input_stats
"""Set the stats to input_stats."""
self.stats = input_stats
return self.stats
def set_stats_snmp(self, bulk=False, snmp_oid={}):
# Update stats using SNMP
# If bulk=True, use a bulk request instead of a get request
"""Update stats using SNMP.
If bulk=True, use a bulk request instead of a get request.
"""
from glances.core.glances_snmp import GlancesSNMPClient
# Init the SNMP request
@ -122,17 +124,15 @@ class GlancesPlugin(object):
return ret
def get_raw(self):
# Return the stats object
"""Return the stats object."""
return self.stats
def get_stats(self):
# Return the stats object in JSON format for the RPC API
"""Return the stats object in JSON format for the XML-RPC API."""
return json.dumps(self.stats)
def load_limits(self, config):
"""
Load the limits from the configuration file
"""
"""Load the limits from the configuration file."""
if (hasattr(config, 'has_section') and
config.has_section(self.plugin_name)):
# print "Load limits for %s" % self.plugin_name
@ -145,27 +145,29 @@ class GlancesPlugin(object):
self.limits[self.plugin_name + '_' + s] = config.get_raw_option(self.plugin_name, s).split(",")
def set_limits(self, input_limits):
# Set the limits to input_limits
"""Set the limits to input_limits."""
self.limits = input_limits
return self.limits
def get_limits(self):
# Return the limits object
"""Return the limits object."""
return self.limits
def get_alert(self, current=0, min=0, max=100, header="", log=False):
# Return the alert status relative to a current value
# Use this function for minor stat
# If current < CAREFUL of max then alert = OK
# If current > CAREFUL of max then alert = CAREFUL
# If current > WARNING of max then alert = WARNING
# If current > CRITICAL of max then alert = CRITICAL
#
# If defined 'header' is added between the plugin name and the status
# Only usefull for stats with several alert status
#
# If log=True than return the logged status
"""Return the alert status relative to a current value.
Use this function for minor stats.
If current < CAREFUL of max then alert = OK
If current > CAREFUL of max then alert = CAREFUL
If current > WARNING of max then alert = WARNING
If current > CRITICAL of max then alert = CRITICAL
If defined 'header' is added between the plugin name and the status.
Only useful for stats with several alert status.
If log=True than return the logged status.
"""
# Compute the %
try:
value = (current * 100) / max
@ -206,6 +208,7 @@ class GlancesPlugin(object):
return ret + log_str
def get_alert_log(self, current=0, min=0, max=100, header=""):
"""Get the alert log."""
return self.get_alert(current, min, max, header, log=True)
def __get_limit_critical(self, header=""):
@ -227,9 +230,7 @@ class GlancesPlugin(object):
return self.limits[self.plugin_name + '_' + header + '_' + 'careful']
def get_hide(self, header=""):
"""
Return the hide configuration list key for the current plugin
"""
"""Return the hide configuration list key for the current plugin."""
if header == "":
try:
return self.limits[self.plugin_name + '_' + 'hide']
@ -242,26 +243,23 @@ class GlancesPlugin(object):
return []
def is_hide(self, value, header=""):
"""
Return True if the value is in the hide configuration list
"""
"""Return True if the value is in the hide configuration list."""
return value in self.get_hide(header=header)
def msg_curse(self, args):
"""
Return default string to display in the curse interface
"""
"""Return default string to display in the curse interface."""
return [self.curse_add_line(str(self.stats))]
def get_stats_display(self, args=None):
# Return a dict with all the information needed to display the stat
# key | description
# ----------------------------
# display | Display the stat (True or False)
# msgdict | Message to display (list of dict [{ 'msg': msg, 'decoration': decoration } ... ])
# column | column number
# line | Line number
"""Return a dict with all the information needed to display the stat.
key | description
----------------------------
display | Display the stat (True or False)
msgdict | Message to display (list of dict [{ 'msg': msg, 'decoration': decoration } ... ])
column | column number
line | Line number
"""
display_curse = False
column_curse = -1
line_curse = -1
@ -279,9 +277,9 @@ class GlancesPlugin(object):
'line': line_curse}
def curse_add_line(self, msg, decoration="DEFAULT", optional=False, splittable=False):
"""
Return a dict with: { 'msg': msg, 'decoration': decoration, 'optional': False }
with:
"""Return a dict with: { 'msg': msg, 'decoration': decoration, 'optional': False }.
Where:
msg: string
decoration:
DEFAULT: no decoration
@ -302,19 +300,16 @@ class GlancesPlugin(object):
optional: True if the stat is optional (display only if space is available)
spittable: Line can be splitted to fit on the screen (default is not)
"""
return {'msg': msg, 'decoration': decoration, 'optional': optional, 'splittable': splittable}
def curse_new_line(self):
"""
Go to a new line
"""
"""Go to a new line."""
return self.curse_add_line('\n')
def auto_unit(self, number, low_precision=False):
"""
Make a nice human readable string out of number
Number of decimal places increases as quantity approaches 1
"""Make a nice human-readable string out of number.
Number of decimal places increases as quantity approaches 1.
examples:
CASE: 613421788 RESULT: 585M low_precision: 585M
@ -325,8 +320,8 @@ class GlancesPlugin(object):
CASE: 1073741824 RESULT: 1024M low_precision: 1024M
CASE: 1181116006 RESULT: 1.10G low_precision: 1.1G
parameter 'low_precision=True' returns less decimal places.
potentially sacrificing precision for more readability
'low_precision=True' returns less decimal places potentially
sacrificing precision for more readability.
"""
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {

View File

@ -17,19 +17,22 @@
# 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/>.
"""Process count plugin."""
# Import Glances libs
from glances.core.glances_globals import glances_processes
from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances's processes Plugin
"""Glances' processes plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -44,16 +47,11 @@ class Plugin(GlancesPlugin):
# Note: 'glances_processes' is already init in the glances_processes.py script
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update processes stats using the input method
"""
"""Update processes stats using the input method."""
# Reset stats
self.reset()
@ -72,10 +70,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,6 +17,8 @@
# 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/>.
"""Process list plugin."""
# Import sys libs
import os
from datetime import timedelta
@ -27,13 +29,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances's processes Plugin
"""Glances' processes plugin.
stats is a list
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -48,16 +51,11 @@ class Plugin(GlancesPlugin):
# Note: 'glances_processes' is already init in the glances_processes.py script
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update processes stats using the input method
"""
"""Update processes stats using the input method."""
# Reset stats
self.reset()
@ -74,10 +72,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []
@ -226,9 +221,7 @@ class Plugin(GlancesPlugin):
return ret
def sortlist(self, sortedby=None):
"""
Return the self.stats sorted by sortedby
"""
"""Return the stats sorted by sortedby variable."""
if sortedby is None:
# No need to sort...
return self.stats

View File

@ -23,28 +23,24 @@ from psutil import __version__ as __psutil_version
class Plugin(GlancesPlugin):
"""
Glances' PsUtil version Plugin
"""Get the psutil version for client/server purposes.
stats is a tuple
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = None
def update(self):
"""
Update core stats
"""
"""Update the stats."""
# Reset stats
self.reset()

View File

@ -17,6 +17,8 @@
# 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/>.
"""Sensors plugin."""
# Sensors library (optional; Linux-only)
# Py3Sensors: https://bitbucket.org/gleb_zhulik/py3sensors
try:
@ -32,15 +34,16 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin):
"""
Glances' sensors plugin
The stats list includes both sensors and hard disks stats, if any
The sensors are already grouped by chip type and then sorted by name
The hard disks are already sorted by name
"""Glances' sensors plugin.
The stats list includes both sensors and hard disks stats, if any.
The sensors are already grouped by chip type and then sorted by name.
The hard disks are already sorted by name.
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# Init the sensor class
@ -65,16 +68,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = []
def update(self):
"""
Update sensors stats using the input method
"""
"""Update sensors stats using the input method."""
# Reset the stats
self.reset()
@ -95,8 +93,9 @@ class Plugin(GlancesPlugin):
return self.stats
def __set_type(self, stats, sensor_type):
"""
3 types of stats is possible in the Sensors plugins:
"""Set the plugin type.
3 types of stats is possible in the sensors plugin:
- Core temperature
- HDD temperature
- Battery capacity
@ -106,9 +105,7 @@ class Plugin(GlancesPlugin):
return stats
def msg_curse(self, args=None):
"""
Return the dict to display in the curse interface
"""
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []
@ -144,14 +141,11 @@ class Plugin(GlancesPlugin):
class GlancesGrabSensors(object):
"""
Get sensors stats using the PySensors library
"""
"""Get sensors stats using the py3sensors library."""
def __init__(self):
"""
Init sensors stats
"""
"""Init sensors stats."""
try:
sensors.init()
except Exception:
@ -163,15 +157,11 @@ class GlancesGrabSensors(object):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.sensors_list = []
def __update__(self):
"""
Update the stats
"""
"""Update the stats."""
# Reset the list
self.reset()
@ -188,9 +178,11 @@ class GlancesGrabSensors(object):
return self.sensors_list
def get(self):
"""Get sensors list."""
self.__update__()
return self.sensors_list
def quit(self):
"""End of connection."""
if self.initok:
sensors.cleanup()

View File

@ -16,9 +16,8 @@
#
# 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/>.
"""
Glances system plugin
"""
"""System plugin."""
# Import system libs
import os
@ -33,13 +32,14 @@ snmp_oid = {'hostname': '1.3.6.1.2.1.1.5.0',
class Plugin(GlancesPlugin):
"""
Glances' Host/System Plugin
"""Glances' host/system plugin.
stats is a dict
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -55,17 +55,14 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update the host/system info using the input method
"""Update the host/system info using the input method.
Return the stats (dict)
"""
# Reset stats
self.reset()
@ -98,10 +95,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the string to display in the curse interface
"""
"""Return the string to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,6 +17,8 @@
# 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/>.
"""Uptime plugin."""
# Import system libs
from datetime import datetime, timedelta
@ -31,14 +33,14 @@ snmp_oid = {'_uptime': '1.3.6.1.2.1.1.3.0'}
class Plugin(GlancesPlugin):
"""
Glances' Uptime Plugin
Get stats about uptime
"""Glances' uptime plugin.
stats is date (string)
"""
def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface
@ -53,16 +55,11 @@ class Plugin(GlancesPlugin):
self.reset()
def reset(self):
"""
Reset/init the stats
"""
"""Reset/init the stats."""
self.stats = {}
def update(self):
"""
Update uptime stat using the input method
"""
"""Update uptime stat using the input method."""
# Reset stats
self.reset()
@ -85,10 +82,7 @@ class Plugin(GlancesPlugin):
return self.stats
def msg_curse(self, args=None):
"""
Return the string to display in the curse interface
"""
"""Return the string to display in the curse interface."""
# Init the return message
ret = []

View File

@ -17,38 +17,30 @@
#
# 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/>.
"""
Glances unitary tests suite...
"""
import os
import sys
import time
"""Glances unitary tests suite."""
import gettext
import locale
import sys
import time
import unittest
from glances.core.glances_globals import (
__appname__,
__version__,
is_bsd,
appname,
is_linux,
is_mac,
is_py3,
is_windows,
sys_prefix,
work_path
version
)
# Global variables
#=================
# =================
# Unitary test is only available from a GNU/Linus machine
if not is_linux:
print('ERROR: Unitaries tests should be ran on GNU/Linux operating system')
sys.exit(2)
else:
print('{} {} {}'.format('Unitary tests for', __appname__, __version__))
print('Unitary tests for {0} {1}'.format(appname, version))
# Import local settings
from glances.core.glances_globals import gettext_domain, locale_dir
@ -66,26 +58,23 @@ if not core.is_standalone():
from glances.core.glances_stats import GlancesStats
stats = GlancesStats()
# Unitest class
#==============
class testGlances(unittest.TestCase):
"""
Test glances class
"""
# Unitest class
# ==============
class TestGlances(unittest.TestCase):
"""Test Glances class."""
def setUp(self):
"""
This function is called *every time* before test_*
"""
print('\n' + '='*78)
"""The function is called *every time* before test_*."""
print('\n' + '=' * 78)
def test_000_update(self):
"""
Update stats (mandatory step for all the stats)
The update is made twice (for rate computation)
"""
"""Update stats (mandatory step for all the stats).
The update is made twice (for rate computation).
"""
print('INFO: [TEST_000] Test the stats update function')
try:
stats.update()
@ -102,130 +91,100 @@ class testGlances(unittest.TestCase):
self.assertTrue(True)
def test_001_plugins(self):
"""
Check mandatory plugins
"""
plug_to_check = [ 'system', 'cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs' ]
print('INFO: [TEST_001] Check the mandatory plugins list: %s' % ', '.join(plug_to_check))
plug_list = stats.getAllPlugins()
for p in plug_to_check:
self.assertTrue(p in plug_list)
"""Check mandatory plugins."""
plugins_to_check = ['system', 'cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs']
print('INFO: [TEST_001] Check the mandatory plugins list: %s' % ', '.join(plugins_to_check))
plugins_list = stats.getAllPlugins()
for plugin in plugins_to_check:
self.assertTrue(plugin in plugins_list)
def test_002_cpu(self):
"""
Check SYSTEM plugin
"""
stats_to_check = [ 'hostname', 'os_name' ]
"""Check SYSTEM plugin."""
stats_to_check = ['hostname', 'os_name']
print('INFO: [TEST_002] Check SYSTEM stats: %s' % ', '.join(stats_to_check))
stats_grab = stats.get_plugin('system').get_raw()
for s in stats_to_check:
for stat in stats_to_check:
# Check that the key exist
self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s)
self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
print('INFO: SYSTEM stats: %s' % stats_grab)
def test_003_cpu(self):
"""
Check CPU plugin
"""
stats_to_check = [ 'system', 'user', 'idle' ]
"""Check CPU plugin."""
stats_to_check = ['system', 'user', 'idle']
print('INFO: [TEST_003] Check mandatory CPU stats: %s' % ', '.join(stats_to_check))
stats_grab = stats.get_plugin('cpu').get_raw()
for s in stats_to_check:
for stat in stats_to_check:
# Check that the key exist
self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s)
self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
# Check that % is > 0 and < 100
self.assertGreaterEqual(stats_grab[s], 0)
self.assertLessEqual(stats_grab[s], 100)
self.assertGreaterEqual(stats_grab[stat], 0)
self.assertLessEqual(stats_grab[stat], 100)
print('INFO: CPU stats: %s' % stats_grab)
def test_004_load(self):
"""
Check LOAD plugin
"""
stats_to_check = [ 'cpucore', 'min1', 'min5', 'min15' ]
"""Check LOAD plugin."""
stats_to_check = ['cpucore', 'min1', 'min5', 'min15']
print('INFO: [TEST_004] Check LOAD stats: %s' % ', '.join(stats_to_check))
stats_grab = stats.get_plugin('load').get_raw()
for s in stats_to_check:
for stat in stats_to_check:
# Check that the key exist
self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s)
self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
# Check that % is > 0
self.assertGreaterEqual(stats_grab[s], 0)
self.assertGreaterEqual(stats_grab[stat], 0)
print('INFO: LOAD stats: %s' % stats_grab)
def test_005_mem(self):
"""
Check MEM plugin
"""
stats_to_check = [ 'available', 'used', 'free', 'total' ]
"""Check MEM plugin."""
stats_to_check = ['available', 'used', 'free', 'total']
print('INFO: [TEST_005] Check MEM stats: %s' % ', '.join(stats_to_check))
stats_grab = stats.get_plugin('mem').get_raw()
for s in stats_to_check:
for stat in stats_to_check:
# Check that the key exist
self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s)
self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
# Check that % is > 0
self.assertGreaterEqual(stats_grab[s], 0)
self.assertGreaterEqual(stats_grab[stat], 0)
print('INFO: MEM stats: %s' % stats_grab)
def test_006_swap(self):
"""
Check MEMSWAP plugin
"""
stats_to_check = [ 'used', 'free', 'total' ]
"""Check MEMSWAP plugin."""
stats_to_check = ['used', 'free', 'total']
print('INFO: [TEST_006] Check SWAP stats: %s' % ', '.join(stats_to_check))
stats_grab = stats.get_plugin('memswap').get_raw()
for s in stats_to_check:
for stat in stats_to_check:
# Check that the key exist
self.assertTrue(stats_grab.has_key(s), msg='Can not find key: %s' % s)
self.assertTrue(stat in stats_grab, msg='Cannot find key: %s' % stat)
# Check that % is > 0
self.assertGreaterEqual(stats_grab[s], 0)
self.assertGreaterEqual(stats_grab[stat], 0)
print('INFO: SWAP stats: %s' % stats_grab)
def test_007_network(self):
"""
Check NETWORK plugin
"""
"""Check NETWORK plugin."""
print('INFO: [TEST_007] Check NETWORK stats')
stats_grab = stats.get_plugin('network').get_raw()
self.assertTrue(type(stats_grab) is list, msg='Network stats is not a list')
print('INFO: NETWORK stats: %s' % stats_grab)
def test_008_diskio(self):
"""
Check DISKIO plugin
"""
"""Check DISKIO plugin."""
print('INFO: [TEST_008] Check DiskIO stats')
stats_grab = stats.get_plugin('diskio').get_raw()
self.assertTrue(type(stats_grab) is list, msg='DiskIO stats is not a list')
print('INFO: diskio stats: %s' % stats_grab)
def test_009_fs(self):
"""
Check FileSystem plugin
"""
stats_to_check = [ ]
"""Check File System plugin."""
# stats_to_check = [ ]
print('INFO: [TEST_009] Check FS stats')
stats_grab = stats.get_plugin('fs').get_raw()
self.assertTrue(type(stats_grab) is list, msg='FileSystem stats is not a list')
print('INFO: FS stats: %s' % stats_grab)
def test_010_processes(self):
"""
Check Process plugin
"""
stats_to_check = [ ]
"""Check Process plugin."""
# stats_to_check = [ ]
print('INFO: [TEST_010] Check PROCESS stats')
stats_grab = stats.get_plugin('processcount').get_raw()
total = stats_grab['total']
# total = stats_grab['total']
self.assertTrue(type(stats_grab) is dict, msg='Process count stats is not a dict')
print('INFO: PROCESS count stats: %s' % stats_grab)
stats_grab = stats.get_plugin('processlist').get_raw()