Test Failed
Push — develop ( abf64f...1d1151 )
by Nicolas
02:59
created

glances/amps/glances_amp.py (1 issue)

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2019 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""
21
I am your father...
22
23
...for all Glances Application Monitoring Processes (AMP).
24
25
AMP (Application Monitoring Process)
26
A Glances AMP is a Python script called (every *refresh* seconds) if:
27
- the AMP is *enabled* in the Glances configuration file
28
- a process is running (match the *regex* define in the configuration file)
29
The script should define a Amp (GlancesAmp) class with, at least, an update method.
30
The update method should call the set_result method to set the AMP return string.
31
The return string is a string with one or more line (\n between lines).
32
If the *one_line* var is true then the AMP will be displayed in one line.
33
"""
34
35
from glances.compat import u, b, n, nativestr
36
from glances.timer import Timer
37
from glances.logger import logger
38
39
40
class GlancesAmp(object):
41
    """Main class for Glances AMP."""
42
43
    NAME = '?'
44
    VERSION = '?'
45
    DESCRIPTION = '?'
46
    AUTHOR = '?'
47
    EMAIL = '?'
48
49
    def __init__(self, name=None, args=None):
50
        """Init AMP classe."""
51
        logger.debug("AMP - Init {} version {}".format(self.NAME, self.VERSION))
52
53
        # AMP name (= module name without glances_)
54
        if name is None:
55
            self.amp_name = self.__class__.__module__[len('glances_'):]
56
        else:
57
            self.amp_name = name
58
59
        # Init the args
60
        self.args = args
61
62
        # Init the configs
63
        self.configs = {}
64
65
        # A timer is needed to only update every refresh seconds
66
        # Init to 0 in order to update the AMP on startup
67
        self.timer = Timer(0)
68
69
    def load_config(self, config):
70
        """Load AMP parameters from the configuration file."""
71
72
        # Read AMP confifuration.
73
        # For ex, the AMP foo should have the following section:
74
        #
75
        # [foo]
76
        # enable=true
77
        # regex=\/usr\/bin\/nginx
78
        # refresh=60
79
        #
80
        # and optionnaly:
81
        #
82
        # one_line=false
83
        # option1=opt1
84
        # ...
85
        #
86
        amp_section = 'amp_' + self.amp_name
87
        if (hasattr(config, 'has_section') and
88
                config.has_section(amp_section)):
89
            logger.debug("AMP - {}: Load configuration".format(self.NAME))
90
            for param, _ in config.items(amp_section):
91
                try:
92
                    self.configs[param] = config.get_float_value(amp_section, param)
93
                except ValueError:
94
                    self.configs[param] = config.get_value(amp_section, param).split(',')
95
                    if len(self.configs[param]) == 1:
96
                        self.configs[param] = self.configs[param][0]
97
                logger.debug("AMP - {}: Load parameter: {} = {}".format(self.NAME, param, self.configs[param]))
98
        else:
99
            logger.debug("AMP - {}: Can not find section {} in the configuration file".format(self.NAME, self.amp_name))
100
            return False
101
102
        # enable, regex and refresh are mandatories
103
        # if not configured then AMP is disabled
104
        if self.enable():
105
            for k in ['regex', 'refresh']:
106
                if k not in self.configs:
107
                    logger.warning("AMP - {}: Can not find configuration key {} in section {}".format(self.NAME, k, self.amp_name))
108
                    self.configs['enable'] = 'false'
109
        else:
110
            logger.debug("AMP - {} is disabled".format(self.NAME))
111
112
        # Init the count to 0
113
        self.configs['count'] = 0
114
115
        return self.enable()
116
117
    def get(self, key):
118
        """Generic method to get the item in the AMP configuration"""
119
        if key in self.configs:
120
            return self.configs[key]
121
        else:
122
            return None
123
124
    def enable(self):
125
        """Return True|False if the AMP is enabled in the configuration file (enable=true|false)."""
126
        ret = self.get('enable')
127
        if ret is None:
128
            return False
129
        else:
130
            return ret.lower().startswith('true')
131
132
    def regex(self):
133
        """Return regular expression used to identified the current application."""
134
        return self.get('regex')
135
136
    def refresh(self):
137
        """Return refresh time in seconds for the current application monitoring process."""
138
        return self.get('refresh')
139
140
    def one_line(self):
141
        """Return True|False if the AMP shoukd be displayed in oneline (one_lineline=true|false)."""
142
        ret = self.get('one_line')
143
        if ret is None:
144
            return False
145
        else:
146
            return ret.lower().startswith('true')
147
148
    def time_until_refresh(self):
149
        """Return time in seconds until refresh."""
150
        return self.timer.get()
151
152
    def should_update(self):
153
        """Return True is the AMP should be updated:
154
        - AMP is enable
155
        - only update every 'refresh' seconds
156
        """
157
        if self.timer.finished():
158
            self.timer.set(self.refresh())
159
            self.timer.reset()
160
            return self.enable()
161
        return False
162
163
    def set_count(self, count):
164
        """Set the number of processes matching the regex"""
165
        self.configs['count'] = count
166
167
    def count(self):
168
        """Get the number of processes matching the regex"""
169
        return self.get('count')
170
171
    def count_min(self):
172
        """Get the minimum number of processes"""
173
        return self.get('countmin')
174
175
    def count_max(self):
176
        """Get the maximum number of processes"""
177
        return self.get('countmax')
178
179
    def set_result(self, result, separator=''):
180
        """Store the result (string) into the result key of the AMP
181
        if one_line is true then replace \n by separator
182
        """
183
        if self.one_line():
184
            self.configs['result'] = u(result).replace('\n', separator)
185
        else:
186
            self.configs['result'] = u(result)
187
188
    def result(self):
189
        """ Return the result of the AMP (as a string)"""
190
        ret = self.get('result')
191
        if ret is not None:
192
            ret = u(ret)
193
        return ret
194
195
    def update_wrapper(self, process_list):
196
        """Wrapper for the children update"""
197
        # Set the number of running process
198
        self.set_count(len(process_list))
199
        # Call the children update method
200
        if self.should_update():
201
            return self.update(process_list)
0 ignored issues
show
The Instance of GlancesAmp does not seem to have a member named update.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
202
        else:
203
            return self.result()
204