Completed
Push — master ( 1806d1...053f07 )
by Nicolas
01:42
created

MonitorList.get()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 3
rs 10
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2015 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
"""Manage the monitor list."""
21
22
import re
23
import subprocess
24
25
from glances.compat import range, u
26
from glances.logger import logger
27
from glances.processes import glances_processes
28
29
30
class MonitorList(object):
31
32
    """This class describes the optional monitored processes list.
33
34
    The monitored list is a list of 'important' processes to monitor.
35
36
    The list (Python list) is composed of items (Python dict).
37
    An item is defined (dict keys):
38
    * description: Description of the processes (max 16 chars)
39
    * regex: regular expression of the processes to monitor
40
    * command: (optional) shell command for extended stat
41
    * countmin: (optional) minimal number of processes
42
    * countmax: (optional) maximum number of processes
43
    """
44
45
    # Maximum number of items in the list
46
    __monitor_list_max_size = 10
47
    # The list
48
    __monitor_list = []
49
50
    def __init__(self, config):
51
        """Init the monitoring list from the configuration file, if it exists."""
52
        self.config = config
53
54
        if self.config is not None and self.config.has_section('monitor'):
55
            # Process monitoring list
56
            logger.debug("Monitor list configuration detected")
57
            self.__set_monitor_list('monitor', 'list')
58
        else:
59
            self.__monitor_list = []
60
61
    def __set_monitor_list(self, section, key):
62
        """Init the monitored processes list.
63
64
        The list is defined in the Glances configuration file.
65
        """
66
        for l in range(1, self.__monitor_list_max_size + 1):
67
            value = {}
68
            key = "list_" + str(l) + "_"
69
            try:
70
                description = self.config.get_value(section, key + 'description')
71
                regex = self.config.get_value(section, key + 'regex')
72
                command = self.config.get_value(section, key + 'command')
73
                countmin = self.config.get_value(section, key + 'countmin')
74
                countmax = self.config.get_value(section, key + 'countmax')
75
            except Exception as e:
76
                logger.error("Cannot read monitored list: {0}".format(e))
77
            else:
78
                if description is not None and regex is not None:
79
                    # Build the new item
80
                    value["description"] = description
81
                    try:
82
                        re.compile(regex)
83
                    except Exception:
84
                        continue
85
                    else:
86
                        value["regex"] = regex
87
                    value["command"] = command
88
                    value["countmin"] = countmin
89
                    value["countmax"] = countmax
90
                    value["count"] = None
91
                    value["result"] = None
92
                    # Add the item to the list
93
                    self.__monitor_list.append(value)
94
95
    def __str__(self):
96
        return str(self.__monitor_list)
97
98
    def __repr__(self):
99
        return self.__monitor_list
100
101
    def __getitem__(self, item):
102
        return self.__monitor_list[item]
103
104
    def __len__(self):
105
        return len(self.__monitor_list)
106
107
    def __get__(self, item, key):
108
        """Meta function to return key value of item.
109
110
        Return None if not defined or item > len(list)
111
        """
112
        if item < len(self.__monitor_list):
113
            try:
114
                return self.__monitor_list[item][key]
115
            except Exception:
116
                return None
117
        else:
118
            return None
119
120
    def update(self):
121
        """Update the command result attributed."""
122
        # Only continue if monitor list is not empty
123
        if len(self.__monitor_list) == 0:
124
            return self.__monitor_list
125
126
        # Search monitored processes by a regular expression
127
        processlist = [p for p in glances_processes.getalllist()]
128
129
        # Iter upon the monitored list
130
        for i in range(len(self.get())):
131
            monitoredlist = [p for p in processlist for c in p['cmdline'] if re.search(self.regex(i), c) is not None]
132
            self.__monitor_list[i]['count'] = len(monitoredlist)
133
134
            # Always get processes CPU and MEM
135
            self.__monitor_list[i]['default_result'] = 'CPU: {0:.1f}% | MEM: {1:.1f}%'.format(
136
                sum([p['cpu_percent'] for p in monitoredlist]),
137
                sum([p['memory_percent'] for p in monitoredlist]))
138
139
            if self.command(i) is not None:
140
                # Execute the user command line
141
                try:
142
                    self.__monitor_list[i]['result'] = subprocess.check_output(self.command(i),
143
                                                                               shell=True)
144
                except subprocess.CalledProcessError:
145
                    self.__monitor_list[i]['result'] = 'Error: ' + self.command(i)
146
                except Exception:
147
                    self.__monitor_list[i]['result'] = 'Cannot execute command'
148
149
                # Only save the first line
150
                try:
151
                    self.__monitor_list[i]['result'] = u(self.__monitor_list[i]['result']).split('\n')[0]
152
                except:
153
                    self.__monitor_list[i]['result'] = ''
154
155
            if self.command(i) is None or self.__monitor_list[i]['result'] == '':
156
                # If there is no command specified in the conf file
157
                # then display CPU and MEM %
158
                self.__monitor_list[i]['result'] = self.__monitor_list[i]['default_result']
159
160
        return self.__monitor_list
161
162
    def get(self):
163
        """Return the monitored list (list of dict)."""
164
        return self.__monitor_list
165
166
    def set(self, newlist):
167
        """Set the monitored list (list of dict)."""
168
        self.__monitor_list = newlist
169
170
    def getAll(self):
171
        # Deprecated: use get()
172
        return self.get()
173
174
    def setAll(self, newlist):
175
        # Deprecated: use set()
176
        self.set(newlist)
177
178
    def description(self, item):
179
        """Return the description of the item number (item)."""
180
        return self.__get__(item, "description")
181
182
    def regex(self, item):
183
        """Return the regular expression of the item number (item)."""
184
        return self.__get__(item, "regex")
185
186
    def command(self, item):
187
        """Return the stat command of the item number (item)."""
188
        return self.__get__(item, "command")
189
190
    def result(self, item):
191
        """Return the reult command of the item number (item)."""
192
        return self.__get__(item, "result")
193
194
    def countmin(self, item):
195
        """Return the minimum number of processes of the item number (item)."""
196
        return self.__get__(item, "countmin")
197
198
    def countmax(self, item):
199
        """Return the maximum number of processes of the item number (item)."""
200
        return self.__get__(item, "countmax")
201