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

View File

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

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage the configuration file."""
# Import system libs # Import system libs
import os import os
import sys import sys
@ -41,8 +43,8 @@ from glances.core.glances_globals import (
class Config(object): 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 :param location: the custom path to search for config file
:type location: str or None :type location: str or None
@ -56,9 +58,7 @@ class Config(object):
self.load() self.load()
def load(self): 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(): for config_file in self.get_config_paths():
if os.path.isfile(config_file) and os.path.getsize(config_file) > 0: if os.path.isfile(config_file) and os.path.getsize(config_file) > 0:
try: try:
@ -73,9 +73,9 @@ class Config(object):
break break
def get_config_paths(self): def get_config_paths(self):
""" r"""Get a list of config file paths.
Get a list of config file paths, taking into account of the OS,
priority and location. The list is built taking into account of the OS, priority and location.
* running from source: /path/to/glances/conf * running from source: /path/to/glances/conf
* Linux: ~/.config/glances, /etc/glances * Linux: ~/.config/glances, /etc/glances
@ -119,21 +119,15 @@ class Config(object):
return paths return paths
def items(self, section): def items(self, section):
""" """Return the items list of a section."""
Return the items list of a section
"""
return self.parser.items(section) return self.parser.items(section)
def has_section(self, 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) return self.parser.has_section(section)
def get_option(self, section, option): 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: try:
value = self.parser.getfloat(section, option) value = self.parser.getfloat(section, option)
except NoOptionError: except NoOptionError:
@ -142,9 +136,7 @@ class Config(object):
return value return value
def get_raw_option(self, section, option): 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: try:
value = self.parser.get(section, option) value = self.parser.get(section, option)
except NoOptionError: except NoOptionError:

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Common objects shared by all Glances modules."""
import os import os
import sys import sys

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage logs."""
# Import system libs # Import system libs
import time import time
from datetime import datetime from datetime import datetime
@ -26,13 +28,14 @@ from glances.core.glances_globals import glances_processes
class GlancesLogs(object): 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_state = "OK|CAREFUL|WARNING|CRITICAL"
item_type = "CPU*|LOAD|MEM|MON" item_type = "CPU*|LOAD|MEM|MON"
item_value = value item_value = value
Item is defined by: Item is defined by:
["begin", ["begin",
"end", "end",
@ -44,10 +47,7 @@ class GlancesLogs(object):
""" """
def __init__(self): def __init__(self):
""" """Init the logs class."""
Init the logs class
"""
# Maximum size of the logs list # Maximum size of the logs list
self.logs_max = 10 self.logs_max = 10
@ -55,24 +55,20 @@ class GlancesLogs(object):
self.logs_list = [] self.logs_list = []
def get(self): def get(self):
""" """Return the raw logs list."""
Return the logs list (RAW)
"""
return self.logs_list return self.logs_list
def len(self): def len(self):
""" """Return the number of item in the logs list."""
Return the number of item in the log list
"""
return self.logs_list.__len__() return self.logs_list.__len__()
def __itemexist__(self, item_type): def __itemexist__(self, item_type):
""" """Return the item position, if it exists.
An item exist in the list if: An item exist in the list if:
* end is < 0 * end is < 0
* item_type is matching * item_type is matching
Return the item position if exist Return -1 if the item is not found.
-1 if the item is not found
""" """
for i in range(self.len()): for i in range(self.len()):
if self.logs_list[i][1] < 0 and self.logs_list[i][3] == item_type: if self.logs_list[i][1] < 0 and self.logs_list[i][3] == item_type:
@ -80,9 +76,7 @@ class GlancesLogs(object):
return -1 return -1
def set_process_sort(self, item_type): 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 # Process sort depending on alert type
if item_type.startswith("MEM"): if item_type.startswith("MEM"):
# Sort TOP process by memory_percent # Sort TOP process by memory_percent
@ -99,9 +93,7 @@ class GlancesLogs(object):
return process_auto_by return process_auto_by
def reset_process_sort(self): def reset_process_sort(self):
""" """Reset the process_auto_by variable."""
Reset the process_auto_by variable
"""
# Default sort is... # Default sort is...
process_auto_by = 'cpu_percent' process_auto_by = 'cpu_percent'
@ -110,11 +102,11 @@ class GlancesLogs(object):
return process_auto_by return process_auto_by
def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""): def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""):
""" """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 a 'new one', add the new item at the beginning of the logs
Else: list.
Update the existing item If 'item' is not a 'new one', update the existing item.
""" """
# Add or update the log # Add or update the log
item_index = self.__itemexist__(item_type) item_index = self.__itemexist__(item_type)
@ -190,8 +182,8 @@ class GlancesLogs(object):
return self.len() return self.len()
def clean(self, critical=False): def clean(self, critical=False):
""" """Clean the logs list by deleting finished items.
Clean the log list by deleting finished item
By default, only delete WARNING message By default, only delete WARNING message
If critical = True, also delete CRITICAL 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 # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Main Glances script """Glances main class."""
"""
# Import system libs # Import system libs
import argparse import argparse
# Import Glances libs # Import Glances libs
from glances.core.glances_config import Config from glances.core.glances_config import Config
from glances.core.glances_globals import ( from glances.core.glances_globals import appname, psutil_version, version
appname,
psutil_version,
version
)
class GlancesMain(object): class GlancesMain(object):
"""
Main class to manage Glances instance """Main class to manage Glances instance."""
"""
# Default stats' refresh time is 3 seconds # Default stats' refresh time is 3 seconds
refresh_time = 3 refresh_time = 3
@ -161,7 +155,6 @@ class GlancesMain(object):
self.server_ip = args.client self.server_ip = args.client
# /!!! # /!!!
# Interactive cmds like CLI args?
# By default help is hidden # By default help is hidden
args.help_tag = False args.help_tag = False
@ -172,9 +165,7 @@ class GlancesMain(object):
return args return args
def __hash_password(self, plain_password): 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 from glances.core.glances_password import GlancesPassword
password = GlancesPassword() password = GlancesPassword()
@ -182,10 +173,10 @@ class GlancesMain(object):
return password.hash_password(plain_password) return password.hash_password(plain_password)
def __get_password(self, description='', confirm=False, clear=False): def __get_password(self, description='', confirm=False, clear=False):
""" """Read a password from the command line.
Read a password from the command line
- with confirmation if confirm = True - if confirm = True, with confirmation
- plain (clear password) if clear = True - if clear = True, plain (clear password)
""" """
from glances.core.glances_password import GlancesPassword from glances.core.glances_password import GlancesPassword
@ -194,37 +185,25 @@ class GlancesMain(object):
return password.get_password(description, confirm, clear) return password.get_password(description, confirm, clear)
def is_standalone(self): 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 return not self.client_tag and not self.server_tag and not self.webserver_tag
def is_client(self): 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 return self.client_tag and not self.server_tag
def is_server(self): 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 return not self.client_tag and self.server_tag
def is_webserver(self): 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 return not self.client_tag and self.webserver_tag
def get_config(self): def get_config(self):
""" """Return configuration file object."""
Return configuration file object
"""
return self.config return self.config
def get_args(self): def get_args(self):
""" """Return the arguments."""
Return the arguments
"""
return self.args return self.args

View File

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

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage password."""
# Import system libs # Import system libs
import getpass import getpass
import hashlib import hashlib
@ -41,9 +43,8 @@ except NameError:
class GlancesPassword(object): class GlancesPassword(object):
"""
Manage password """This class contains all the methods relating to password."""
"""
def __init__(self): def __init__(self):
self.password_path = self.get_password_path() 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) self.password_filepath = os.path.join(self.password_path, self.password_filename)
def get_password_path(self): def get_password_path(self):
""" r"""Get the path where the password file will be stored.
Get the path where the password file will be stored
* Linux and BSD: ~/.config/glances * Linux and BSD: ~/.config/glances
* OS X: ~/Library/glances * OS X: ~/Library/glances
* Windows: %APPDATA%\glances * Windows: %APPDATA%\glances
@ -72,40 +73,37 @@ class GlancesPassword(object):
return app_path return app_path
def get_hash(self, salt, plain_password): 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() return hashlib.sha256(salt.encode() + plain_password.encode()).hexdigest()
def hash_password(self, plain_password): 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 salt = uuid.uuid4().hex
encrypted_password = self.get_hash(salt, plain_password) encrypted_password = self.get_hash(salt, plain_password)
return salt + '$' + encrypted_password return salt + '$' + encrypted_password
def check_password(self, hashed_password, plain_password): def check_password(self, hashed_password, plain_password):
""" """Encode the plain_password with the salt of the hashed_password.
Encode the plain_password with the salt of the hashed_password
and return the comparison with the encrypted_password Return the comparison with the encrypted_password.
""" """
salt, encrypted_password = hashed_password.split('$') salt, encrypted_password = hashed_password.split('$')
re_encrypted_password = self.get_hash(salt, plain_password) re_encrypted_password = self.get_hash(salt, plain_password)
return encrypted_password == re_encrypted_password return encrypted_password == re_encrypted_password
def get_password(self, description='', confirm=False, clear=False): def get_password(self, description='', confirm=False, 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) For Glances server, get the password (confirm=True, clear=False):
2) from the CLI 1) from the password file (if it exists)
2) from the CLI
Optionally: save the password to a file (hashed with salt + SHA-256) 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 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 os.path.exists(self.password_filepath) and not clear:
# If the password file exist then use it # If the password file exist then use it
print(_("Info: Read password from file: {0}").format(self.password_filepath)) print(_("Info: Read password from file: {0}").format(self.password_filepath))
@ -142,9 +140,7 @@ class GlancesPassword(object):
return password return password
def save_password(self, hashed_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 # Check if the Glances folder already exists
if not os.path.exists(self.password_path): if not os.path.exists(self.password_path):
# Create the Glances folder # Create the Glances folder
@ -159,9 +155,7 @@ class GlancesPassword(object):
file_pwd.write(hashed_password) file_pwd.write(hashed_password)
def load_password(self): 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 # Read the password file, if it exists
with open(self.password_filepath, 'r') as file_pwd: with open(self.password_filepath, 'r') as file_pwd:
hashed_password = file_pwd.read() hashed_password = file_pwd.read()

View File

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

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage the Glances server."""
# Import system libs # Import system libs
import json import json
import socket import socket
@ -36,9 +38,9 @@ from glances.core.glances_timer import Timer
class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler): class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
"""
Main XMLRPC handler """Main XML-RPC handler."""
"""
rpc_paths = ('/RPC2', ) rpc_paths = ('/RPC2', )
def end_headers(self): def end_headers(self):
@ -63,20 +65,20 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
# Client authentication # Client authentication
(basic, _, encoded) = headers.get('Authorization').partition(' ') (basic, _, encoded) = headers.get('Authorization').partition(' ')
assert basic == 'Basic', 'Only basic authentication supported' assert basic == 'Basic', 'Only basic authentication supported'
# Encoded portion of the header is a string # Encoded portion of the header is a string
# Need to convert to bytestring # Need to convert to bytestring
encoded_byte_string = encoded.encode() 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) 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() decoded_string = decoded_bytes.decode()
# Get the username and password from the string # Get the username and password from the string
(username, _, password) = decoded_string.partition(':') (username, _, password) = decoded_string.partition(':')
# Check that username and password match internal global dictionary # Check that username and password match internal global dictionary
return self.check_user(username, password) return self.check_user(username, password)
def check_user(self, 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: if username in self.server.user_dict:
from glances.core.glances_password import GlancesPassword from glances.core.glances_password import GlancesPassword
@ -102,9 +104,8 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler):
class GlancesXMLRPCServer(SimpleXMLRPCServer): class GlancesXMLRPCServer(SimpleXMLRPCServer):
"""
Init a SimpleXMLRPCServer instance (IPv6-ready) """Init a SimpleXMLRPCServer instance (IPv6-ready)."""
"""
def __init__(self, bind_address, bind_port=61209, def __init__(self, bind_address, bind_port=61209,
requestHandler=GlancesXMLRPCHandler): requestHandler=GlancesXMLRPCHandler):
@ -120,9 +121,8 @@ class GlancesXMLRPCServer(SimpleXMLRPCServer):
class GlancesInstance(object): 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): def __init__(self, cached_time=1, config=None):
# Init stats # Init stats
@ -166,11 +166,10 @@ class GlancesInstance(object):
return json.dumps(self.stats.getAll()['monitor']) return json.dumps(self.stats.getAll()['monitor'])
def __getattr__(self, item): def __getattr__(self, item):
""" """Overwrite the getattr method in case of attribute is not found.
Overwrite the getattr in case of attribute is not found
The goal is to dynamicaly generate the API get'Stats'() methods
"""
The goal is to dynamically generate the API get'Stats'() methods.
"""
# print "DEBUG: Call method: %s" % item # print "DEBUG: Call method: %s" % item
header = 'get' header = 'get'
# Check if the attribute starts with 'get' # Check if the attribute starts with 'get'
@ -190,9 +189,8 @@ class GlancesInstance(object):
class GlancesServer(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, def __init__(self, requestHandler=GlancesXMLRPCHandler,
cached_time=1, cached_time=1,
@ -216,23 +214,18 @@ class GlancesServer(object):
self.server.register_instance(GlancesInstance(cached_time, config)) self.server.register_instance(GlancesInstance(cached_time, config))
def add_user(self, username, password): def add_user(self, username, password):
""" """Add an user to the dictionary."""
Add an user to the dictionnary
"""
self.server.user_dict[username] = password self.server.user_dict[username] = password
self.server.isAuth = True self.server.isAuth = True
def serve_forever(self): def serve_forever(self):
""" """Call the main loop."""
Call the main loop
"""
self.server.serve_forever() self.server.serve_forever()
def server_close(self): def server_close(self):
"""Close the Glances server session."""
self.server.server_close() self.server.server_close()
def end(self): def end(self):
""" """End of the Glances server session."""
End of the Glances server session
"""
self.server_close() self.server_close()

View File

@ -28,7 +28,8 @@ except ImportError:
class GlancesSNMPClient(object): 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', def __init__(self, host='localhost', port=161, version='2c',
community='public', user='private', auth=''): community='public', user='private', auth=''):
@ -46,10 +47,7 @@ class GlancesSNMPClient(object):
self.auth = auth self.auth = auth
def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds): def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds):
""" """Put results in table."""
Put results in table
"""
ret = {} ret = {}
if not errorIndication or not errorStatus: if not errorIndication or not errorStatus:
for name, val in varBinds: for name, val in varBinds:
@ -60,13 +58,13 @@ class GlancesSNMPClient(object):
return ret return ret
def get_by_oid(self, *oid): def get_by_oid(self, *oid):
""" """SNMP simple request (list of OID).
SNMP simple request (list of OID)
One request per OID list One request per OID list.
* oid: oid list * oid: oid list
> Return a dict > Return a dict
""" """
if self.version == '3': if self.version == '3':
errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd( errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
cmdgen.UsmUserData(self.user, self.auth), cmdgen.UsmUserData(self.user, self.auth),
@ -95,16 +93,19 @@ class GlancesSNMPClient(object):
return ret return ret
def getbulk_by_oid(self, non_repeaters, max_repetitions, *oid): def getbulk_by_oid(self, non_repeaters, max_repetitions, *oid):
""" """SNMP getbulk request.
SNMP getbulk request
In contrast to snmpwalk, this information will typically be gathered in a In contrast to snmpwalk, this information will typically be gathered in
single transaction with the agent, rather than one transaction per variable found. a single transaction with the agent, rather than one transaction per
* non_repeaters: This specifies the number of supplied variables that should not be iterated over. variable found.
* max_repetitions: This specifies the maximum number of iterations over the repeating variables.
* 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 * oid: oid list
> Return a list of dicts > Return a list of dicts
""" """
if self.version.startswith('3'): if self.version.startswith('3'):
errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd( errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
cmdgen.UsmUserData(self.user, self.auth), 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 # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage the Glances standalone session."""
# Import Glances libs # Import Glances libs
from glances.core.glances_stats import GlancesStats from glances.core.glances_stats import GlancesStats
from glances.outputs.glances_curses import GlancesCurses from glances.outputs.glances_curses import GlancesCurses
class GlancesStandalone(object): 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): def __init__(self, config=None, args=None):
# Init stats # Init stats
self.stats = GlancesStats(config) self.stats = GlancesStats(config)
@ -48,9 +48,7 @@ class GlancesStandalone(object):
self.screen = GlancesCurses(args=args) self.screen = GlancesCurses(args=args)
def serve_forever(self): def serve_forever(self):
""" """Main loop for the CLI."""
Main loop for the CLI
"""
while True: while True:
# Update system informations # Update system informations
self.stats.update() self.stats.update()
@ -63,9 +61,7 @@ class GlancesStandalone(object):
self.csvoutput.update(self.stats) self.csvoutput.update(self.stats)
def end(self): def end(self):
""" """End of the CLI."""
End of the CLI
"""
self.screen.end() self.screen.end()
# Close the CSV file # Close the CSV file

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The stats manager."""
import collections import collections
import os import os
import sys import sys
@ -25,15 +27,10 @@ from glances.core.glances_globals import plugins_path, sys_path
class GlancesStats(object): class GlancesStats(object):
"""
This class store, update and give stats """This class stores, updates and gives stats."""
"""
def __init__(self, config=None): def __init__(self, config=None):
"""
Init the stats
"""
# Init the plugin list dict # Init the plugin list dict
self._plugins = collections.defaultdict(dict) self._plugins = collections.defaultdict(dict)
@ -44,12 +41,11 @@ class GlancesStats(object):
self.load_limits(config) self.load_limits(config)
def __getattr__(self, item): def __getattr__(self, item):
""" """Overwrite the getattr method in case of attribute is not found.
Overwrite the getattr in case of attribute is not found
The goal is to dynamically generate the following methods: The goal is to dynamically generate the following methods:
- getPlugname(): return Plugname stat in JSON format - getPlugname(): return Plugname stat in JSON format
""" """
# Check if the attribute starts with 'get' # Check if the attribute starts with 'get'
if item.startswith('get'): if item.startswith('get'):
# Get the plugin name # Get the plugin name
@ -67,9 +63,7 @@ class GlancesStats(object):
raise AttributeError(item) raise AttributeError(item)
def load_plugins(self, args=None): def load_plugins(self, args=None):
""" """Load all plugins in the 'plugins' folder."""
Load all plugins in the "plugins" folder
"""
header = "glances_" header = "glances_"
for item in os.listdir(plugins_path): for item in os.listdir(plugins_path):
if (item.startswith(header) and if (item.startswith(header) and
@ -87,26 +81,18 @@ class GlancesStats(object):
sys.path = sys_path sys.path = sys_path
def getAllPlugins(self): def getAllPlugins(self):
""" """Return the plugins list."""
Return the plugins list
"""
return [p for p in self._plugins] return [p for p in self._plugins]
def load_limits(self, config=None): def load_limits(self, config=None):
""" """Load the stats limits."""
Load the stats limits
"""
# For each plugins, call the init_limits method # For each plugins, call the init_limits method
for p in self._plugins: for p in self._plugins:
# print "DEBUG: Load limits for %s" % p # print "DEBUG: Load limits for %s" % p
self._plugins[p].load_limits(config) self._plugins[p].load_limits(config)
def __update__(self, input_stats): def __update__(self, input_stats):
""" """Update all the stats."""
Update the stats
"""
if input_stats == {}: if input_stats == {}:
# For standalone and server modes # For standalone and server modes
# For each plugins, call the update method # For each plugins, call the update method
@ -120,21 +106,19 @@ class GlancesStats(object):
self._plugins[p].set_stats(input_stats[p]) self._plugins[p].set_stats(input_stats[p])
def update(self, input_stats={}): def update(self, input_stats={}):
# Update the stats """Wrapper method to update the stats."""
self.__update__(input_stats) self.__update__(input_stats)
def getAll(self): def getAll(self):
""" """Return all the stats."""
Return all the stats
"""
return [self._plugins[p].get_raw() for p in self._plugins] return [self._plugins[p].get_raw() for p in self._plugins]
def get_plugin_list(self): def get_plugin_list(self):
# Return the plugin list """Return the plugin list."""
self._plugins self._plugins
def get_plugin(self, plugin_name): def get_plugin(self, plugin_name):
# Return the plugin name """Return the plugin name."""
if plugin_name in self._plugins: if plugin_name in self._plugins:
return self._plugins[plugin_name] return self._plugins[plugin_name]
else: else:
@ -142,9 +126,8 @@ class GlancesStats(object):
class GlancesStatsServer(GlancesStats): 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): def __init__(self, config=None):
# Init the stats # Init the stats
@ -155,11 +138,7 @@ class GlancesStatsServer(GlancesStats):
self.all_stats = collections.defaultdict(dict) self.all_stats = collections.defaultdict(dict)
def update(self, input_stats={}): def update(self, input_stats={}):
""" """Update the stats."""
Update the stats
"""
# Update the stats
GlancesStats.update(self) GlancesStats.update(self)
# Build the all_stats with the get_raw() method of the plugins # 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() self.all_stats[p] = self._plugins[p].get_raw()
def getAll(self): def getAll(self):
""" """Return the stats as a dict."""
Return the stats as a dict
"""
return self.all_stats return self.all_stats
def getAllPlugins(self): def getAllPlugins(self):
""" """Return the plugins list."""
Return the plugins list
"""
return [p for p in self._plugins] return [p for p in self._plugins]
def getAllLimits(self): def getAllLimits(self):
""" """Return the plugins limits list."""
Return the plugins limits list
"""
return [self._plugins[p].get_limits() for p in self._plugins] return [self._plugins[p].get_limits() for p in self._plugins]
class GlancesStatsClient(GlancesStats): 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): def __init__(self):
"""Init the GlancesStatsClient class."""
# Init the plugin list dict # Init the plugin list dict
self._plugins = collections.defaultdict(dict) self._plugins = collections.defaultdict(dict)
def set_plugins(self, input_plugins): 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_" header = "glances_"
for item in input_plugins: for item in input_plugins:
# Import the plugin # Import the plugin
@ -213,9 +184,8 @@ class GlancesStatsClient(GlancesStats):
class GlancesStatsClientSNMP(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): def __init__(self, config=None, args=None):
# Init the plugin list dict # Init the plugin list dict
@ -231,10 +201,7 @@ class GlancesStatsClientSNMP(GlancesStats):
self.load_plugins(args=self.args) self.load_plugins(args=self.args)
def check_snmp(self): 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 # Import the SNMP client class
from glances.core.glances_snmp import GlancesSNMPClient 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") != {} return clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {}
def update(self): def update(self):
""" """Update the stats using SNMP."""
Update the stats using SNMP
"""
# For each plugins, call the update method # For each plugins, call the update method
for p in self._plugins: for p in self._plugins:
# Set the input method to SNMP # 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 # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The timer manager."""
from time import time from time import time
# Global list to manage the elapsed time # Global list to manage the elapsed time
@ -24,6 +26,7 @@ last_update_times = {}
def getTimeSinceLastUpdate(IOType): def getTimeSinceLastUpdate(IOType):
"""Return the elapsed time since last update."""
global last_update_times global last_update_times
# assert(IOType in ['net', 'disk', 'process_disk']) # assert(IOType in ['net', 'disk', 'process_disk'])
current_time = time() current_time = time()
@ -37,10 +40,8 @@ def getTimeSinceLastUpdate(IOType):
class Timer(object): class Timer(object):
"""
The timer class """The timer class. A simple chronometer."""
A simple chrono
"""
def __init__(self, duration): def __init__(self, duration):
self.duration = duration self.duration = duration

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # 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 # Import Glances libs
from glances.core.glances_stats import GlancesStats from glances.core.glances_stats import GlancesStats
@ -26,12 +25,10 @@ from glances.outputs.glances_bottle import GlancesBottle
class GlancesWebServer(object): 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): def __init__(self, config=None, args=None):
# Init stats # Init stats
self.stats = GlancesStats(config) self.stats = GlancesStats(config)
@ -42,13 +39,9 @@ class GlancesWebServer(object):
self.web = GlancesBottle(args=args) self.web = GlancesBottle(args=args)
def serve_forever(self): def serve_forever(self):
""" """Main loop for the Web server."""
Main loop for the Web Server
"""
self.web.start(self.stats) self.web.start(self.stats)
def end(self): def end(self):
""" """End of the Web server."""
End of the Web Server
"""
self.web.end() self.web.end()

View File

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

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""CSV interface class."""
# Import sys libs # Import sys libs
import csv import csv
import sys import sys
@ -29,9 +31,8 @@ csv_stats_list = ['cpu', 'load', 'mem', 'memswap']
class GlancesCSV(object): class GlancesCSV(object):
"""
This class manages the CSV output """This class manages the CSV output."""
"""
def __init__(self, args=None): def __init__(self, args=None):
# CSV file name # CSV file name
@ -51,12 +52,11 @@ class GlancesCSV(object):
print(_("Stats dumped to CSV file: {0}").format(self.csv_filename)) print(_("Stats dumped to CSV file: {0}").format(self.csv_filename))
def exit(self): def exit(self):
"""Close the CSV file."""
self.csv_file.close() self.csv_file.close()
def update(self, stats): def update(self, stats):
""" """Update stats in the CSV output file."""
Update stats in the CSV output file
"""
all_stats = stats.getAll() all_stats = stats.getAll()
plugins = stats.getAllPlugins() plugins = stats.getAllPlugins()

View File

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

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Alert plugin."""
# Import system lib # Import system lib
from datetime import datetime from datetime import datetime
@ -26,13 +28,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's alert Plugin
Only for display """Glances' alert plugin.
Only for display.
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -48,23 +51,16 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): 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 # Set the stats to the glances_logs
self.stats = glances_logs.get() self.stats = glances_logs.get()
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

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

View File

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

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Glances CPU plugin """CPU plugin."""
"""
from glances.plugins.glances_plugin import GlancesPlugin 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): class Plugin(GlancesPlugin):
""" """
Glances' Cpu Plugin Glances' CPU plugin.
stats is a dict stats is a dict
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the CPU plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -57,16 +58,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update CPU stats using the input method."""
Update CPU stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -107,10 +103,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Glances DiskIO plugin """Disk I/O plugin."""
"""
# Import Glances libs # Import Glances libs
from glances.core.glances_timer import getTimeSinceLastUpdate from glances.core.glances_timer import getTimeSinceLastUpdate
@ -28,13 +27,14 @@ import psutil
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's disks IO Plugin """Glances' disks I/O plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -50,16 +50,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): def update(self):
""" """Update disk I/O stats using the input method."""
Update disk IO stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -118,10 +113,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""File system plugin."""
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
import psutil import psutil
@ -43,13 +45,14 @@ snmp_oid = {'mnt_point': '1.3.6.1.4.1.2021.9.1.2',
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's File System (fs) Plugin """Glances' file system plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -65,16 +68,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): def update(self):
""" """Update the FS stats using the input method."""
Update the FS stats using the input method
"""
# Reset the list # Reset the list
self.reset() self.reset()
@ -127,9 +125,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

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

View File

@ -16,26 +16,24 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
Glances help plugin Help plugin.
Just a stupid plugin to display the help screen
Just a stupid plugin to display the help screen.
""" """
# Import Glances libs # Import Glances libs
from glances.core.glances_globals import ( from glances.core.glances_globals import appname, psutil_version, version
appname,
psutil_version,
version
)
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances' Help Plugin """Glances' help plugin."""
"""
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -48,16 +46,11 @@ class Plugin(GlancesPlugin):
self.line_curse = 0 self.line_curse = 0
def update(self): 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 pass
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Glances load plugin """Load plugin."""
"""
# Import system libs # Import system libs
import os import os
@ -37,13 +36,14 @@ snmp_oid = {'min1': '1.3.6.1.4.1.2021.10.1.3.1',
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's Load Plugin """Glances' load plugin.
stats is a dict stats is a dict
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -59,16 +59,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update load stats."""
Update load stats
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -107,10 +102,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # 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 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): class Plugin(GlancesPlugin):
"""
Glances's memory Plugin """Glances' memory plugin.
stats is a dict stats is a dict
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -62,16 +62,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update RAM memory stats using the input method."""
Update MEM (RAM) stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -133,9 +128,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # 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 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): class Plugin(GlancesPlugin):
"""
Glances's swap memory Plugin """Glances' swap memory plugin.
stats is a dict stats is a dict
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -54,16 +54,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update swap memory stats using the input method."""
Update MEM (SWAP) stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -104,9 +99,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -17,17 +17,19 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Monitor plugin."""
# Import Glances lib # Import Glances lib
from glances.core.glances_monitor_list import MonitorList as glancesMonitorList from glances.core.glances_monitor_list import MonitorList as glancesMonitorList
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's monitor Plugin """Glances' monitor plugin."""
"""
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -44,17 +46,12 @@ class Plugin(GlancesPlugin):
self.stats = [] self.stats = []
def load_limits(self, config): 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 # print "DEBUG: Monitor plugin load config file %s" % config
self.glances_monitors = glancesMonitorList(config) self.glances_monitors = glancesMonitorList(config)
def update(self): def update(self):
""" """Update the monitored list."""
Update the monitored list
"""
if self.get_input() == 'local': if self.get_input() == 'local':
# Monitor list only available in a full Glances environment # Monitor list only available in a full Glances environment
# Check if the glances_monitor instance is init # Check if the glances_monitor instance is init
@ -72,7 +69,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def get_alert(self, nbprocess=0, countmin=None, countmax=None, header="", log=False): 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: if nbprocess is None:
return 'OK' return 'OK'
if countmin is None: if countmin is None:
@ -91,9 +88,7 @@ class Plugin(GlancesPlugin):
return 'CRITICAL' return 'CRITICAL'
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # 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.core.glances_timer import getTimeSinceLastUpdate
from glances.plugins.glances_plugin import GlancesPlugin 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): class Plugin(GlancesPlugin):
"""
Glances's network Plugin """Glances' network Plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -56,17 +56,14 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): 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) Stats is a list of dict (one dict per interface)
""" """
# Reset stats # Reset stats
self.reset() self.reset()
@ -163,10 +160,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): def msg_curse(self, args=None):
""" """Return the dict to display in the curse interface."""
Return the dict to displayoid in the curse interface
"""
# !!! TODO: Add alert on network interface bitrate # !!! TODO: Add alert on network interface bitrate
# Init the return message # Init the return message

View File

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

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
CPU stats (per cpu) """Per-CPU plugin."""
"""
# Import Glances libs # Import Glances libs
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
@ -28,13 +27,14 @@ import psutil
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances' PerCpu Plugin """Glances' per-CPU plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -52,16 +52,11 @@ class Plugin(GlancesPlugin):
self.percputime_new = [] self.percputime_new = []
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): def update(self):
""" """Update per-CPU stats using the input method."""
Update Per CPU stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -138,10 +133,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

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

View File

@ -17,19 +17,22 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Process count plugin."""
# Import Glances libs # Import Glances libs
from glances.core.glances_globals import glances_processes from glances.core.glances_globals import glances_processes
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's processes Plugin """Glances' processes plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # 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 # Note: 'glances_processes' is already init in the glances_processes.py script
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update processes stats using the input method."""
Update processes stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -72,10 +70,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Process list plugin."""
# Import sys libs # Import sys libs
import os import os
from datetime import timedelta from datetime import timedelta
@ -27,13 +29,14 @@ from glances.plugins.glances_plugin import GlancesPlugin
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances's processes Plugin """Glances' processes plugin.
stats is a list stats is a list
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # 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 # Note: 'glances_processes' is already init in the glances_processes.py script
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = [] self.stats = []
def update(self): def update(self):
""" """Update processes stats using the input method."""
Update processes stats using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -74,10 +72,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []
@ -226,9 +221,7 @@ class Plugin(GlancesPlugin):
return ret return ret
def sortlist(self, sortedby=None): def sortlist(self, sortedby=None):
""" """Return the stats sorted by sortedby variable."""
Return the self.stats sorted by sortedby
"""
if sortedby is None: if sortedby is None:
# No need to sort... # No need to sort...
return self.stats return self.stats

View File

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

View File

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

View File

@ -16,9 +16,8 @@
# #
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Glances system plugin """System plugin."""
"""
# Import system libs # Import system libs
import os import os
@ -33,13 +32,14 @@ snmp_oid = {'hostname': '1.3.6.1.2.1.1.5.0',
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances' Host/System Plugin """Glances' host/system plugin.
stats is a dict stats is a dict
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -55,17 +55,14 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): 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) Return the stats (dict)
""" """
# Reset stats # Reset stats
self.reset() self.reset()
@ -98,10 +95,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Uptime plugin."""
# Import system libs # Import system libs
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -31,14 +33,14 @@ snmp_oid = {'_uptime': '1.3.6.1.2.1.1.3.0'}
class Plugin(GlancesPlugin): class Plugin(GlancesPlugin):
"""
Glances' Uptime Plugin """Glances' uptime plugin.
Get stats about uptime
stats is date (string) stats is date (string)
""" """
def __init__(self, args=None): def __init__(self, args=None):
"""Init the plugin."""
GlancesPlugin.__init__(self, args=args) GlancesPlugin.__init__(self, args=args)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
@ -53,16 +55,11 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
def reset(self): def reset(self):
""" """Reset/init the stats."""
Reset/init the stats
"""
self.stats = {} self.stats = {}
def update(self): def update(self):
""" """Update uptime stat using the input method."""
Update uptime stat using the input method
"""
# Reset stats # Reset stats
self.reset() self.reset()
@ -85,10 +82,7 @@ class Plugin(GlancesPlugin):
return self.stats return self.stats
def msg_curse(self, args=None): 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 # Init the return message
ret = [] ret = []

View File

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