mirror of https://github.com/nicolargo/glances.git
First commit for the Alert module
This commit is contained in:
parent
8b93077e1a
commit
471b04fe85
|
|
@ -5,24 +5,28 @@ If you are lookink for user manual, please follow this link: https://github.com/
|
|||
|
||||
===
|
||||
|
||||
__init__.py Global module init
|
||||
__main__.py Entry point for module
|
||||
__init__.py Global module init
|
||||
__main__.py Entry point for module
|
||||
core/
|
||||
glances_main.py Main script to rule them up...
|
||||
glances_globals.py Share variables uppon modules
|
||||
glances_config.py Manage configuration file
|
||||
glances_timer.py Manage timer
|
||||
glances_stats.py Inteface to grab stats
|
||||
glances_client.py Glances client
|
||||
glances_server.py Glances_server
|
||||
glances_config.py Manage configuration file
|
||||
glances_globals.py Share variables uppon modules
|
||||
glances_limits.py Manage limits
|
||||
glances_logs.py Manage logs
|
||||
glances_main.py Main script to rule them up...
|
||||
glances_stats.py Inteface to grab stats
|
||||
glances_client.py Glances client
|
||||
glances_server.py Glances server
|
||||
glances_standalone.py Glances standalone (with curse interface)
|
||||
glances_stats.py The stats manager
|
||||
glances_timer.py Manage timer
|
||||
plugins/
|
||||
glances_plugins.py "Father class" for others plugins
|
||||
glances_cpu.py Manage CPU stats
|
||||
glances_load.py Manage LOAD stats
|
||||
glances_mem.py Manage MEM (both RAM and SWAP) stats
|
||||
glances_plugins.py "Father class" for others plugins
|
||||
glances_cpu.py Manage CPU stats
|
||||
glances_load.py Manage LOAD stats
|
||||
glances_mem.py Manage MEM (both RAM and SWAP) stats
|
||||
...
|
||||
outputs/
|
||||
glances_curse.py The Curse (console) interface
|
||||
glances_csv.py The CSV interface
|
||||
glances_html.py The HTML interface
|
||||
glances_curse.py The Curse interface
|
||||
glances_csv.py The CSV interface
|
||||
glances_html.py The HTML interface
|
||||
...
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ import os
|
|||
import gettext
|
||||
import locale
|
||||
|
||||
# Import Glances libs
|
||||
from ..core.glances_logs import glancesLogs
|
||||
|
||||
# Import PsUtil
|
||||
try:
|
||||
from psutil import __version__ as __psutil_version__
|
||||
|
|
@ -74,3 +77,6 @@ elif os.path.exists(sys_i18n_path):
|
|||
else:
|
||||
locale_dir = None
|
||||
gettext.install(gettext_domain, locale_dir)
|
||||
|
||||
# Logs instance share between all scripts
|
||||
glances_logs = glancesLogs()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Glances - An eye on your system
|
||||
#
|
||||
# Copyright (C) 2014 Nicolargo <nicolas@nicolargo.com>
|
||||
#
|
||||
# Glances is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Glances is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Import system libs
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
class glancesLogs:
|
||||
"""
|
||||
Manage logs inside the Glances software
|
||||
Logs is a list of list (stored in the self.logs_list var)
|
||||
|
||||
item_state = "OK|CAREFUL|WARNING|CRITICAL"
|
||||
item_type = "CPU*|LOAD|MEM|MON"
|
||||
item_value = value
|
||||
Item is defined by:
|
||||
["begin", "end", "WARNING|CRITICAL", "CPU|LOAD|MEM",
|
||||
MAX, AVG, MIN, SUM, COUNT,
|
||||
[top3 process list],
|
||||
"Processes description"]
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Init the logs class
|
||||
"""
|
||||
|
||||
# Maximum size of the logs list
|
||||
self.logs_max = 10
|
||||
|
||||
# Init the logs list
|
||||
self.logs_list = []
|
||||
|
||||
# Automaticaly define the sort to apply on the processes list
|
||||
self.sort_process_by = 'none'
|
||||
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Return the logs list (RAW)
|
||||
"""
|
||||
return self.logs_list
|
||||
|
||||
|
||||
def len(self):
|
||||
"""
|
||||
Return the number of item in the log list
|
||||
"""
|
||||
return self.logs_list.__len__()
|
||||
|
||||
|
||||
def __itemexist__(self, item_type):
|
||||
"""
|
||||
An item exist in the list if:
|
||||
* end is < 0
|
||||
* item_type is matching
|
||||
"""
|
||||
for i in range(self.len()):
|
||||
if self.logs_list[i][1] < 0 and self.logs_list[i][3] == item_type:
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
||||
def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""):
|
||||
"""
|
||||
If item is a 'new one':
|
||||
Add the new item at the beginning of the logs list
|
||||
Else:
|
||||
Update the existing item
|
||||
"""
|
||||
# Add Top process sort depending on alert type
|
||||
self.sort_process_by = 'none'
|
||||
if (item_type.startswith("MEM")):
|
||||
# Sort TOP process by memory_percent
|
||||
self.sort_process_by = 'memory_percent'
|
||||
elif (item_type.startswith("CPU IO")):
|
||||
# Sort TOP process by io_counters (only for Linux OS)
|
||||
self.sort_process_by = 'io_counters'
|
||||
elif (item_type.startswith("MON")):
|
||||
# Do no sort process for monitored prcesses list
|
||||
self.sort_process_by = 'none'
|
||||
else:
|
||||
# Default TOP process sort is cpu_percent
|
||||
self.sort_process_by = 'cpu_percent'
|
||||
|
||||
# Sort processes
|
||||
if (self.sort_process_by != 'none'):
|
||||
topprocess = sorted(proc_list, key=lambda process: process[self.sort_process_by],
|
||||
reverse=True)
|
||||
else:
|
||||
topprocess = proc_list
|
||||
|
||||
# Add or update the log
|
||||
item_index = self.__itemexist__(item_type)
|
||||
if (item_index < 0):
|
||||
# Item did not exist, add if WARNING or CRITICAL
|
||||
if ((item_state == "WARNING") or (item_state == "CRITICAL")):
|
||||
# Time is stored in Epoch format
|
||||
# Epoch -> DMYHMS = datetime.fromtimestamp(epoch)
|
||||
item = []
|
||||
# START DATE
|
||||
item.append(time.mktime(datetime.now().timetuple()))
|
||||
# END DATE
|
||||
item.append(-1)
|
||||
item.append(item_state) # STATE: WARNING|CRITICAL
|
||||
item.append(item_type) # TYPE: CPU, LOAD, MEM...
|
||||
item.append(item_value) # MAX
|
||||
item.append(item_value) # AVG
|
||||
item.append(item_value) # MIN
|
||||
item.append(item_value) # SUM
|
||||
item.append(1) # COUNT
|
||||
item.append(topprocess[0:3]) # TOP 3 PROCESS LIST
|
||||
item.append(proc_desc) # MONITORED PROCESSES DESC
|
||||
self.logs_list.insert(0, item)
|
||||
if self.len() > self.logs_max:
|
||||
self.logs_list.pop()
|
||||
else:
|
||||
# Item exist, update
|
||||
if ((item_state == "OK") or (item_state == "CAREFUL")):
|
||||
# Close the item
|
||||
self.logs_list[item_index][1] = time.mktime(
|
||||
datetime.now().timetuple())
|
||||
# TOP PROCESS LIST
|
||||
self.logs_list[item_index][9] = []
|
||||
else:
|
||||
# Update the item
|
||||
# State
|
||||
if (item_state == "CRITICAL"):
|
||||
self.logs_list[item_index][2] = item_state
|
||||
# Value
|
||||
if (item_value > self.logs_list[item_index][4]):
|
||||
# MAX
|
||||
self.logs_list[item_index][4] = item_value
|
||||
elif (item_value < self.logs_list[item_index][6]):
|
||||
# MIN
|
||||
self.logs_list[item_index][6] = item_value
|
||||
# AVG
|
||||
self.logs_list[item_index][7] += item_value
|
||||
self.logs_list[item_index][8] += 1
|
||||
self.logs_list[item_index][5] = (self.logs_list[item_index][7] /
|
||||
self.logs_list[item_index][8])
|
||||
# TOP PROCESS LIST
|
||||
self.logs_list[item_index][9] = topprocess[0:3]
|
||||
# MONITORED PROCESSES DESC
|
||||
self.logs_list[item_index][10] = proc_desc
|
||||
|
||||
return self.len()
|
||||
|
||||
|
||||
def clean(self, critical=False):
|
||||
"""
|
||||
Clean the log list by deleting finished item
|
||||
By default, only delete WARNING message
|
||||
If critical = True, also delete CRITICAL message
|
||||
"""
|
||||
# Create a new clean list
|
||||
clean_logs_list = []
|
||||
while self.len() > 0:
|
||||
item = self.logs_list.pop()
|
||||
if item[1] < 0 or (not critical and item[2] == "CRITICAL"):
|
||||
clean_logs_list.insert(0, item)
|
||||
# The list is now the clean one
|
||||
self.logs_list = clean_logs_list
|
||||
return self.len()
|
||||
|
|
@ -50,7 +50,7 @@ class GlancesStandalone():
|
|||
self.stats = GlancesStats(config)
|
||||
|
||||
# Initial update
|
||||
# !!! The first time Glances display wrong CPU information
|
||||
# !!! The first time Glances display wrong CPU/MEM information
|
||||
self.stats.update()
|
||||
|
||||
self.refresh_time = args.time
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Glances - An eye on your system
|
||||
#
|
||||
# Copyright (C) 2014 Nicolargo <nicolas@nicolargo.com>
|
||||
#
|
||||
# Glances is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Glances is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Import Glances lib
|
||||
from glances_plugin import GlancesPlugin
|
||||
from glances.core.glances_globals import glances_logs
|
||||
|
||||
|
||||
class Plugin(GlancesPlugin):
|
||||
"""
|
||||
Glances's alert Plugin
|
||||
|
||||
Only for display
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
GlancesPlugin.__init__(self)
|
||||
|
||||
# We want to display the stat in the curse interface
|
||||
self.display_curse = True
|
||||
# Set the message position
|
||||
# It is NOT the curse position but the Glances column/line
|
||||
# Enter -1 to right align
|
||||
self.column_curse = 1
|
||||
# Enter -1 to diplay bottom
|
||||
self.line_curse = 4
|
||||
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Nothing to do here
|
||||
Just return the global glances_log
|
||||
"""
|
||||
|
||||
self.stats = glances_logs.get()
|
||||
|
||||
|
||||
def msg_curse(self, args=None):
|
||||
"""
|
||||
Return the dict to display in the curse interface
|
||||
"""
|
||||
# Init the return message
|
||||
ret = []
|
||||
|
||||
# Build the string message
|
||||
# Header
|
||||
if (self.stats == []):
|
||||
msg = "{0:8}".format(_("No alert detected"))
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
else:
|
||||
msg = "{0:8}".format(_("ALERT"))
|
||||
ret.append(self.curse_add_line(msg, "TITLE"))
|
||||
|
||||
return ret
|
||||
|
|
@ -25,6 +25,7 @@ from psutil import cpu_times, cpu_times_percent
|
|||
# from ..plugins.glances_plugin import GlancesPlugin
|
||||
from glances_plugin import GlancesPlugin
|
||||
|
||||
|
||||
class Plugin(GlancesPlugin):
|
||||
"""
|
||||
Glances' Cpu Plugin
|
||||
|
|
@ -51,7 +52,10 @@ class Plugin(GlancesPlugin):
|
|||
"""
|
||||
|
||||
# Grab CPU using the PSUtil cpu_times_percent method (PSUtil 0.7 or higher)
|
||||
cputimespercent = cpu_times_percent(interval=0, percpu=False)
|
||||
try:
|
||||
cputimespercent = cpu_times_percent(interval=0, percpu=False)
|
||||
except:
|
||||
return self.update_deprecated()
|
||||
|
||||
self.stats = {}
|
||||
for cpu in ['user', 'system', 'idle', 'nice',
|
||||
|
|
@ -64,8 +68,8 @@ class Plugin(GlancesPlugin):
|
|||
|
||||
def update_deprecated(self):
|
||||
"""
|
||||
!!! Not used anymore...
|
||||
Update CPU stats
|
||||
Only used if cpu_times_percent failed
|
||||
"""
|
||||
|
||||
# Grab CPU using the PSUtil cpu_times method
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
# 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/>.
|
||||
|
||||
# Import system lib
|
||||
from psutil import disk_io_counters
|
||||
|
||||
# Import Glances lib
|
||||
from glances.core.glances_globals import is_Mac
|
||||
from glances_plugin import GlancesPlugin, getTimeSinceLastUpdate
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,16 @@
|
|||
# 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/>.
|
||||
|
||||
# Import system libs
|
||||
import json
|
||||
from time import time
|
||||
|
||||
# Import Glances lib
|
||||
from glances.core.glances_globals import glances_logs
|
||||
|
||||
# Global list to manage the elapsed time
|
||||
last_update_times = {}
|
||||
|
||||
|
||||
def getTimeSinceLastUpdate(IOType):
|
||||
global last_update_times
|
||||
# assert(IOType in ['net', 'disk', 'process_disk'])
|
||||
|
|
@ -112,27 +115,31 @@ class GlancesPlugin(object):
|
|||
except ZeroDivisionError:
|
||||
return 'DEFAULT'
|
||||
|
||||
# If log is enable than add _LOG to the return string
|
||||
if (log):
|
||||
log_str = "_LOG"
|
||||
else:
|
||||
log_str = ""
|
||||
|
||||
# if (self.plugin_name == "processlist"):
|
||||
# print "*"*300
|
||||
# print self.limits
|
||||
# sys.exit(0)
|
||||
|
||||
# Manage limits
|
||||
ret = 'OK'
|
||||
if (value > self.get_limit_critical(header=header)):
|
||||
return 'CRITICAL'+log_str
|
||||
ret = 'CRITICAL'
|
||||
elif (value > self.get_limit_warning(header=header)):
|
||||
return 'WARNING'+log_str
|
||||
ret = 'WARNING'
|
||||
elif (value > self.get_limit_careful(header=header)):
|
||||
return 'CAREFUL'+log_str
|
||||
ret = 'CAREFUL'
|
||||
|
||||
# Manage log (if needed)
|
||||
log_str = ""
|
||||
if (log):
|
||||
# Add _LOG to the return string
|
||||
# So stats will be highlited with a specific color
|
||||
log_str = "_LOG"
|
||||
# Get the stat_name = plugin_name (+ header)
|
||||
if (header == ""):
|
||||
stat_name = self.plugin_name
|
||||
else:
|
||||
stat_name = self.plugin_name + '_' + header
|
||||
# !!! TODO: Manage the process list (last param => [])
|
||||
glances_logs.add(ret, stat_name.upper(), value, [])
|
||||
|
||||
# Default is ok
|
||||
return 'OK'+log_str
|
||||
return ret + log_str
|
||||
|
||||
|
||||
def get_alert_log(self, current=0, min=0, max=100, header=""):
|
||||
|
|
|
|||
Loading…
Reference in New Issue