Test Failed
Push — master ( 4c6c3d...040528 )
by Nicolas
04:27
created

glances/amps/glances_amp.py (3 issues)

Checks for unused imports

Unused Code Minor
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
0 ignored issues
show
Unused nativestr imported from glances.compat
Loading history...
Unused b imported from glances.compat
Loading history...
Unused n imported from glances.compat
Loading history...
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
        if self.enable():
103
            # Refresh option is mandatory
104
            for k in ['refresh']:
105
                if k not in self.configs:
106
                    logger.warning("AMP - {}: Can not find configuration key {} in section {} (the AMP will be disabled)".format(self.NAME, k, self.amp_name))
107
                    self.configs['enable'] = 'false'
108
        else:
109
            logger.debug("AMP - {} is disabled".format(self.NAME))
110
111
        # Init the count to 0
112
        self.configs['count'] = 0
113
114
        return self.enable()
115
116
    def get(self, key):
117
        """Generic method to get the item in the AMP configuration"""
118
        if key in self.configs:
119
            return self.configs[key]
120
        else:
121
            return None
122
123
    def enable(self):
124
        """Return True|False if the AMP is enabled in the configuration file (enable=true|false)."""
125
        ret = self.get('enable')
126
        if ret is None:
127
            return False
128
        else:
129
            return ret.lower().startswith('true')
130
131
    def regex(self):
132
        """Return regular expression used to identified the current application."""
133
        return self.get('regex')
134
135
    def refresh(self):
136
        """Return refresh time in seconds for the current application monitoring process."""
137
        return self.get('refresh')
138
139
    def one_line(self):
140
        """Return True|False if the AMP shoukd be displayed in oneline (one_lineline=true|false)."""
141
        ret = self.get('one_line')
142
        if ret is None:
143
            return False
144
        else:
145
            return ret.lower().startswith('true')
146
147
    def time_until_refresh(self):
148
        """Return time in seconds until refresh."""
149
        return self.timer.get()
150
151
    def should_update(self):
152
        """Return True is the AMP should be updated:
153
        - AMP is enable
154
        - only update every 'refresh' seconds
155
        """
156
        if self.timer.finished():
157
            self.timer.set(self.refresh())
158
            self.timer.reset()
159
            return self.enable()
160
        return False
161
162
    def set_count(self, count):
163
        """Set the number of processes matching the regex"""
164
        self.configs['count'] = count
165
166
    def count(self):
167
        """Get the number of processes matching the regex"""
168
        return self.get('count')
169
170
    def count_min(self):
171
        """Get the minimum number of processes"""
172
        return self.get('countmin')
173
174
    def count_max(self):
175
        """Get the maximum number of processes"""
176
        return self.get('countmax')
177
178
    def set_result(self, result, separator=''):
179
        """Store the result (string) into the result key of the AMP
180
        if one_line is true then replace \n by separator
181
        """
182
        if self.one_line():
183
            self.configs['result'] = u(result).replace('\n', separator)
184
        else:
185
            self.configs['result'] = u(result)
186
187
    def result(self):
188
        """ Return the result of the AMP (as a string)"""
189
        ret = self.get('result')
190
        if ret is not None:
191
            ret = u(ret)
192
        return ret
193
194
    def update_wrapper(self, process_list):
195
        """Wrapper for the children update"""
196
        # Set the number of running process
197
        self.set_count(len(process_list))
198
        # Call the children update method
199
        if self.should_update():
200
            return self.update(process_list)
201
        else:
202
            return self.result()
203