| Server IP : 93.86.61.54 / Your IP : 216.73.216.206 Web Server : Apache/2.4.62 (Ubuntu) System : Linux rasin.ddns.net 6.8.0-124-generic #124~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 21:05:19 UTC x86_64 User : www-data ( 33) PHP Version : 8.4.22 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/lib/python3/dist-packages/glances/ |
Upload File : |
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2020 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/>.
"""Manage the AMPs list."""
import os
import re
import threading
from glances.compat import listkeys, iteritems
from glances.logger import logger
from glances.globals import amps_path
from glances.processes import glances_processes
class AmpsList(object):
"""This class describes the optional application monitoring process list.
The AMP list is a list of processes with a specific monitoring action.
The list (Python list) is composed of items (Python dict).
An item is defined (dict keys):
*...
"""
# The dict
__amps_dict = {}
def __init__(self, args, config):
"""Init the AMPs list."""
self.args = args
self.config = config
# Load the AMP configurations / scripts
self.load_configs()
def load_configs(self):
"""Load the AMP configuration files."""
if self.config is None:
return False
# Display a warning (deprecated) message if the monitor section exist
if "monitor" in self.config.sections():
logger.warning("A deprecated [monitor] section exists in the Glances configuration file. You should use the new Applications Monitoring Process module instead (http://glances.readthedocs.io/en/develop/aoa/amps.html).")
header = "glances_"
# For each AMP scrip, call the load_config method
for s in self.config.sections():
if s.startswith("amp_"):
# An AMP section exists in the configuration file
# If an AMP script exist in the glances/amps folder, use it
amp_conf_name = s[4:]
amp_script = os.path.join(amps_path, header + s[4:] + ".py")
if not os.path.exists(amp_script):
# If not, use the default script
amp_script = os.path.join(amps_path, "glances_default.py")
try:
amp = __import__(os.path.basename(amp_script)[:-3])
except ImportError as e:
logger.warning("Missing Python Lib ({}), cannot load {} AMP".format(e, amp_conf_name))
except Exception as e:
logger.warning("Cannot load {} AMP ({})".format(amp_conf_name, e))
else:
# Add the AMP to the dictionary
# The key is the AMP name
# for example, the file glances_xxx.py
# generate self._amps_list["xxx"] = ...
self.__amps_dict[amp_conf_name] = amp.Amp(name=amp_conf_name, args=self.args)
# Load the AMP configuration
self.__amps_dict[amp_conf_name].load_config(self.config)
# Log AMPs list
logger.debug("AMPs list: {}".format(self.getList()))
return True
def __str__(self):
return str(self.__amps_dict)
def __repr__(self):
return self.__amps_dict
def __getitem__(self, item):
return self.__amps_dict[item]
def __len__(self):
return len(self.__amps_dict)
def update(self):
"""Update the command result attributed."""
# Get the current processes list (once)
processlist = glances_processes.getlist()
# Iter upon the AMPs dict
for k, v in iteritems(self.get()):
if not v.enable():
# Do not update if the enable tag is set
continue
if v.regex() is None:
# If there is no regex, execute anyway (see issue #1690)
v.set_count(0)
# Call the AMP update method
thread = threading.Thread(target=v.update_wrapper, args=[[]])
thread.start()
continue
amps_list = self._build_amps_list(v, processlist)
if len(amps_list) > 0:
# At least one process is matching the regex
logger.debug("AMPS: {} processes {} detected ({})".format(len(amps_list),
k,
amps_list))
# Call the AMP update method
thread = threading.Thread(target=v.update_wrapper, args=[amps_list])
thread.start()
else:
# Set the process number to 0
v.set_count(0)
if v.count_min() is not None and v.count_min() > 0:
# Only display the "No running process message" if countmin is defined
v.set_result("No running process")
return self.__amps_dict
def _build_amps_list(self, amp_value, processlist):
"""Return the AMPS process list according to the amp_value
Search application monitored processes by a regular expression
"""
ret = []
try:
# Search in both cmdline and name (for kernel thread, see #1261)
for p in processlist:
add_it = False
if (re.search(amp_value.regex(), p['name']) is not None):
add_it = True
else:
if p['cmdline'] is None:
# See issue #1689 (thanks to @darylkell)
continue
for c in p['cmdline']:
if (re.search(amp_value.regex(), c) is not None):
add_it = True
break
if add_it:
ret.append({'pid': p['pid'],
'cpu_percent': p['cpu_percent'],
'memory_percent': p['memory_percent']})
except (TypeError, KeyError) as e:
logger.debug("Can not build AMPS list ({})".format(e))
return ret
def getList(self):
"""Return the AMPs list."""
return listkeys(self.__amps_dict)
def get(self):
"""Return the AMPs dict."""
return self.__amps_dict
def set(self, new_dict):
"""Set the AMPs dict."""
self.__amps_dict = new_dict