Completed
Push — master ( 793552...8b5b19 )
by Nicolas
05:48 queued 01:54
created

glances.processes.GlancesProcesses.__init__()   B

Complexity

Conditions 5

Size

Total Lines 69
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 35
nop 2
dl 0
loc 69
rs 8.5733
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
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
import operator
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
Unused Code introduced by
The import operator seems to be unused.
Loading history...
21
import os
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
Unused Code introduced by
The import os seems to be unused.
Loading history...
22
23
from glances.compat import iteritems, itervalues, listitems, iterkeys
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
Unused Code introduced by
Unused listitems imported from glances.compat
Loading history...
Unused Code introduced by
Unused itervalues imported from glances.compat
Loading history...
Unused Code introduced by
Unused iteritems imported from glances.compat
Loading history...
24
from glances.globals import BSD, LINUX, MACOS, SUNOS, WINDOWS, WSL
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
Unused Code introduced by
Unused SUNOS imported from glances.globals
Loading history...
Unused Code introduced by
Unused WSL imported from glances.globals
Loading history...
25
from glances.timer import Timer, getTimeSinceLastUpdate
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
26
from glances.filter import GlancesFilter
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
27
from glances.logger import logger
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
28
29
import psutil
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
introduced by
Unable to import 'psutil'
Loading history...
30
31
32
class GlancesProcesses(object):
0 ignored issues
show
best-practice introduced by
Too many public methods (23/20)
Loading history...
best-practice introduced by
Too many instance attributes (20/7)
Loading history...
33
    """Get processed stats using the psutil library."""
34
35
    def __init__(self, cache_timeout=60):
36
        """Init the class to collect stats about processes."""
37
        # Add internals caches because psutil do not cache all the stats
38
        # See: https://code.google.com/p/psutil/issues/detail?id=462
39
        self.username_cache = {}
40
        self.cmdline_cache = {}
41
42
        # The internals caches will be cleaned each 'cache_timeout' seconds
43
        self.cache_timeout = cache_timeout
44
        self.cache_timer = Timer(self.cache_timeout)
45
46
        # Init the io dict
47
        # key = pid
48
        # value = [ read_bytes_old, write_bytes_old ]
49
        self.io_old = {}
50
51
        # Init stats
52
        self.auto_sort = None
53
        self._sort_key = None
54
        # Default processes sort key is 'auto'
55
        # Can be overwrite from the configuration file (issue#1536) => See glances_processlist.py init
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
56
        self.set_sort_key('auto', auto=True)
57
        self.processlist = []
58
        self.reset_processcount()
59
60
        # Tag to enable/disable the processes stats (to reduce the Glances CPU consumption)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (91/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
61
        # Default is to enable the processes stats
62
        self.disable_tag = False
63
64
        # Extended stats for top process is enable by default
65
        self.disable_extended_tag = False
66
67
        # Test if the system can grab io_counters
68
        try:
69
            p = psutil.Process()
0 ignored issues
show
Coding Style Naming introduced by
The name p does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
70
            p.io_counters()
71
        except Exception as e:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
72
            logger.warning('PsUtil can not grab processes io_counters ({})'.format(e))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (86/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
73
            self.disable_io_counters = True
74
        else:
75
            logger.debug('PsUtil can grab processes io_counters')
76
            self.disable_io_counters = False
77
78
        # Test if the system can grab gids
79
        try:
80
            p = psutil.Process()
0 ignored issues
show
Coding Style Naming introduced by
The name p does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
81
            p.gids()
82
        except Exception as e:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
83
            logger.warning('PsUtil can not grab processes gids ({})'.format(e))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
84
            self.disable_gids = True
85
        else:
86
            logger.debug('PsUtil can grab processes gids')
87
            self.disable_gids = False
88
89
        # Maximum number of processes showed in the UI (None if no limit)
90
        self._max_processes = None
91
92
        # Process filter is a regular expression
93
        self._filter = GlancesFilter()
94
95
        # Whether or not to hide kernel threads
96
        self.no_kernel_threads = False
97
98
        # Store maximums values in a dict
99
        # Used in the UI to highlight the maximum value
100
        self._max_values_list = ('cpu_percent', 'memory_percent')
101
        # { 'cpu_percent': 0.0, 'memory_percent': 0.0 }
102
        self._max_values = {}
103
        self.reset_max_values()
104
105
    def reset_processcount(self):
106
        """Reset the global process count"""
107
        self.processcount = {'total': 0,
108
                             'running': 0,
109
                             'sleeping': 0,
110
                             'thread': 0,
111
                             'pid_max': None}
112
113
    def update_processcount(self, plist):
114
        """Update the global process count from the current processes list"""
115
        # Update the maximum process ID (pid) number
116
        self.processcount['pid_max'] = self.pid_max
117
        # For each key in the processcount dict
118
        # count the number of processes with the same status
119
        for k in iterkeys(self.processcount):
120
            self.processcount[k] = len(list(filter(lambda v: v['status'] is k,
0 ignored issues
show
introduced by
map/filter on lambda could be replaced by comprehension
Loading history...
introduced by
Cell variable k defined in loop
Loading history...
introduced by
The variable k does not seem to be defined in case the for loop on line 119 is not entered. Are you sure this can never be the case?
Loading history...
121
                                                   plist)))
122
        # Compute thread
123
        self.processcount['thread'] = sum(i['num_threads'] for i in plist
124
                                          if i['num_threads'] is not None)
125
        # Compute total
126
        self.processcount['total'] = len(plist)
127
128
    def enable(self):
129
        """Enable process stats."""
130
        self.disable_tag = False
131
        self.update()
132
133
    def disable(self):
134
        """Disable process stats."""
135
        self.disable_tag = True
136
137
    def enable_extended(self):
138
        """Enable extended process stats."""
139
        self.disable_extended_tag = False
140
        self.update()
141
142
    def disable_extended(self):
143
        """Disable extended process stats."""
144
        self.disable_extended_tag = True
145
146
    @property
147
    def pid_max(self):
148
        """
149
        Get the maximum PID value.
150
151
        On Linux, the value is read from the `/proc/sys/kernel/pid_max` file.
152
153
        From `man 5 proc`:
154
        The default value for this file, 32768, results in the same range of
155
        PIDs as on earlier kernels. On 32-bit platfroms, 32768 is the maximum
156
        value for pid_max. On 64-bit systems, pid_max can be set to any value
157
        up to 2^22 (PID_MAX_LIMIT, approximately 4 million).
158
159
        If the file is unreadable or not available for whatever reason,
160
        returns None.
161
162
        Some other OSes:
163
        - On FreeBSD and macOS the maximum is 99999.
164
        - On OpenBSD >= 6.0 the maximum is 99999 (was 32766).
165
        - On NetBSD the maximum is 30000.
166
167
        :returns: int or None
168
        """
169
        if LINUX:
170
            # XXX: waiting for https://github.com/giampaolo/psutil/issues/720
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
171
            try:
172
                with open('/proc/sys/kernel/pid_max', 'rb') as f:
0 ignored issues
show
Coding Style Naming introduced by
The name f does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
173
                    return int(f.read())
174
            except (OSError, IOError):
175
                return None
176
        else:
177
            return None
178
179
    @property
180
    def max_processes(self):
181
        """Get the maximum number of processes showed in the UI."""
182
        return self._max_processes
183
184
    @max_processes.setter
185
    def max_processes(self, value):
186
        """Set the maximum number of processes showed in the UI."""
187
        self._max_processes = value
188
189
    @property
190
    def process_filter_input(self):
191
        """Get the process filter (given by the user)."""
192
        return self._filter.filter_input
193
194
    @property
195
    def process_filter(self):
196
        """Get the process filter (current apply filter)."""
197
        return self._filter.filter
198
199
    @process_filter.setter
200
    def process_filter(self, value):
201
        """Set the process filter."""
202
        self._filter.filter = value
203
204
    @property
205
    def process_filter_key(self):
206
        """Get the process filter key."""
207
        return self._filter.filter_key
208
209
    @property
210
    def process_filter_re(self):
211
        """Get the process regular expression compiled."""
212
        return self._filter.filter_re
213
214
    def disable_kernel_threads(self):
215
        """Ignore kernel threads in process list."""
216
        self.no_kernel_threads = True
217
218
    @property
219
    def sort_reverse(self):
220
        """Return True to sort processes in reverse 'key' order, False instead."""
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
221
        if self.sort_key == 'name' or self.sort_key == 'username':
222
            return False
223
224
        return True
225
226
    def max_values(self):
227
        """Return the max values dict."""
228
        return self._max_values
229
230
    def get_max_values(self, key):
231
        """Get the maximum values of the given stat (key)."""
232
        return self._max_values[key]
233
234
    def set_max_values(self, key, value):
235
        """Set the maximum value for a specific stat (key)."""
236
        self._max_values[key] = value
237
238
    def reset_max_values(self):
239
        """Reset the maximum values dict."""
240
        self._max_values = {}
241
        for k in self._max_values_list:
242
            self._max_values[k] = 0.0
243
244
    def update(self):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (16/15).
Loading history...
245
        """Update the processes stats."""
246
        # Reset the stats
247
        self.processlist = []
248
        self.reset_processcount()
249
250
        # Do not process if disable tag is set
251
        if self.disable_tag:
252
            return
253
254
        # Time since last update (for disk_io rate computation)
255
        time_since_update = getTimeSinceLastUpdate('process_disk')
256
257
        # Grab standard stats
258
        #####################
259
        standard_attrs = ['cmdline', 'cpu_percent', 'cpu_times', 'memory_info',
260
                          'memory_percent', 'name', 'nice', 'pid', 'ppid',
261
                          'status', 'username', 'status', 'num_threads']
262
        if not self.disable_io_counters:
263
            standard_attrs += ['io_counters']
264
        if not self.disable_gids:
265
            standard_attrs += ['gids']
266
267
        # and build the processes stats list (psutil>=5.3.0)
268
        self.processlist = [p.info for p in psutil.process_iter(attrs=standard_attrs,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (85/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
269
                                                                ad_value=None)
270
                            # OS-related processes filter
271
                            if not (BSD and p.info['name'] == 'idle') and
272
                            not (WINDOWS and p.info['name'] == 'System Idle Process') and
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (89/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
273
                            not (MACOS and p.info['name'] == 'kernel_task') and
274
                            # Kernel threads filter
275
                            not (self.no_kernel_threads and LINUX and p.info['gids'].real == 0) and
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (99/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
276
                            # User filter
277
                            not (self._filter.is_filtered(p.info))]
0 ignored issues
show
Unused Code Coding Style introduced by
Unnecessary parens after u'not' keyword
Loading history...
278
279
        # Sort the processes list by the current sort_key
280
        self.processlist = sort_stats(self.processlist,
281
                                      sortedby=self.sort_key,
282
                                      reverse=True)
283
284
        # Update the processcount
285
        self.update_processcount(self.processlist)
286
287
        # Loop over processes and add metadata
288
        first = True
289
        for proc in self.processlist:
290
            # Get extended stats, only for top processes (see issue #403).
291
            if first and not self.disable_extended_tag:
292
                # - cpu_affinity (Linux, Windows, FreeBSD)
293
                # - ionice (Linux and Windows > Vista)
294
                # - num_ctx_switches (not available on Illumos/Solaris)
295
                # - num_fds (Unix-like)
296
                # - num_handles (Windows)
297
                # - memory_maps (only swap, Linux)
298
                #   https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (84/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
299
                # - connections (TCP and UDP)
300
                extended = {}
301
                try:
302
                    top_process = psutil.Process(proc['pid'])
303
                    extended_stats = ['cpu_affinity', 'ionice',
304
                                      'num_ctx_switches']
305
                    if LINUX:
306
                        # num_fds only avalable on Unix system (see issue #1351)
307
                        extended_stats += ['num_fds']
308
                    if WINDOWS:
309
                        extended_stats += ['num_handles']
310
311
                    # Get the extended stats
312
                    extended = top_process.as_dict(attrs=extended_stats,
313
                                                   ad_value=None)
314
315
                    if LINUX:
316
                        try:
317
                            extended['memory_swap'] = sum([v.swap for v in top_process.memory_maps()])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
318
                        except (psutil.NoSuchProcess, KeyError):
319
                            # KeyError catch for issue #1551)
320
                            pass
321
                        except (psutil.AccessDenied, NotImplementedError):
322
                            # NotImplementedError: /proc/${PID}/smaps file doesn't exist
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
323
                            # on kernel < 2.6.14 or CONFIG_MMU kernel configuration option
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (90/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
324
                            # is not enabled (see psutil #533/glances #413).
325
                            extended['memory_swap'] = None
326
                    try:
327
                        extended['tcp'] = len(top_process.connections(kind="tcp"))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
328
                        extended['udp'] = len(top_process.connections(kind="udp"))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
329
                    except (psutil.AccessDenied, psutil.NoSuchProcess):
330
                        # Manage issue1283 (psutil.AccessDenied)
331
                        extended['tcp'] = None
332
                        extended['udp'] = None
333
                except (psutil.NoSuchProcess, ValueError, AttributeError) as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
334
                    logger.error('Can not grab extended stats ({})'.format(e))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
335
                    extended['extended_stats'] = False
336
                else:
337
                    logger.debug('Grab extended stats for process {}'.format(proc['pid']))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (90/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
338
                    extended['extended_stats'] = True
339
                proc.update(extended)
340
            first = False
341
            # /End of extended stats
342
343
            # Time since last update (for disk_io rate computation)
344
            proc['time_since_update'] = time_since_update
345
346
            # Process status (only keep the first char)
347
            proc['status'] = str(proc['status'])[:1].upper()
348
349
            # Process IO
350
            # procstat['io_counters'] is a list:
351
            # [read_bytes, write_bytes, read_bytes_old, write_bytes_old, io_tag]
352
            # If io_tag = 0 > Access denied or first time (display "?")
353
            # If io_tag = 1 > No access denied (display the IO rate)
354
            if 'io_counters' in proc and proc['io_counters'] is not None:
355
                io_new = [proc['io_counters'].read_bytes,
356
                          proc['io_counters'].write_bytes]
357
                # For IO rate computation
358
                # Append saved IO r/w bytes
359
                try:
360
                    proc['io_counters'] = io_new + self.io_old[proc['pid']]
361
                    io_tag = 1
362
                except KeyError:
363
                    proc['io_counters'] = io_new + [0, 0]
364
                    io_tag = 0
365
                # then save the IO r/w bytes
366
                self.io_old[proc['pid']] = io_new
367
            else:
368
                proc['io_counters'] = [0, 0] + [0, 0]
369
                io_tag = 0
370
            # Append the IO tag (for display)
371
            proc['io_counters'] += [io_tag]
372
373
        # Compute the maximum value for keys in self._max_values_list: CPU, MEM
374
        # Usefull to highlight the processes with maximum values
375
        for k in self._max_values_list:
376
            values_list = [i[k] for i in self.processlist if i[k] is not None]
377
            if values_list != []:
378
                self.set_max_values(k, max(values_list))
379
380
    def getcount(self):
381
        """Get the number of processes."""
382
        return self.processcount
383
384
    def getlist(self, sortedby=None):
0 ignored issues
show
Unused Code introduced by
The argument sortedby seems to be unused.
Loading history...
385
        """Get the processlist."""
386
        return self.processlist
387
388
    @property
389
    def sort_key(self):
390
        """Get the current sort key."""
391
        return self._sort_key
392
393
    def set_sort_key(self, key, auto=True):
394
        """Set the current sort key."""
395
        if key == 'auto':
396
            self.auto_sort = True
397
            self._sort_key = 'cpu_percent'
398
        else:
399
            self.auto_sort = auto
400
            self._sort_key = key
401
402
403
def weighted(value):
404
    """Manage None value in dict value."""
405
    return -float('inf') if value is None else value
406
407
408
def _sort_io_counters(process,
409
                      sortedby='io_counters',
410
                      sortedby_secondary='memory_percent'):
0 ignored issues
show
Unused Code introduced by
The argument sortedby_secondary seems to be unused.
Loading history...
411
    """Specific case for io_counters
412
    Sum of io_r + io_w"""
413
    return process[sortedby][0] - process[sortedby][2] + process[sortedby][1] - process[sortedby][3]
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (100/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
414
415
416
def _sort_cpu_times(process,
417
                    sortedby='cpu_times',
418
                    sortedby_secondary='memory_percent'):
0 ignored issues
show
Unused Code introduced by
The argument sortedby_secondary seems to be unused.
Loading history...
419
    """ Specific case for cpu_times
420
    Patch for "Sorting by process time works not as expected #1321"
421
    By default PsUtil only takes user time into account
422
    see (https://github.com/giampaolo/psutil/issues/1339)
423
    The following implementation takes user and system time into account"""
424
    return process[sortedby][0] + process[sortedby][1]
425
426
427
def _sort_lambda(sortedby='cpu_percent',
428
                 sortedby_secondary='memory_percent'):
0 ignored issues
show
Unused Code introduced by
The argument sortedby_secondary seems to be unused.
Loading history...
429
    """Return a sort lambda function for the sortedbykey"""
430
    ret = None
431
    if sortedby == 'io_counters':
432
        ret = _sort_io_counters
433
    elif sortedby == 'cpu_times':
434
        ret = _sort_cpu_times
435
    return ret
436
437
438
def sort_stats(stats,
439
               sortedby='cpu_percent',
440
               sortedby_secondary='memory_percent',
441
               reverse=True):
442
    """Return the stats (dict) sorted by (sortedby).
443
444
    Reverse the sort if reverse is True.
445
    """
446
    if sortedby is None and sortedby_secondary is None:
447
        # No need to sort...
448
        return stats
449
450
    # Check if a specific sort should be done
451
    sort_lambda = _sort_lambda(sortedby=sortedby,
452
                               sortedby_secondary=sortedby_secondary)
453
454
    if sort_lambda is not None:
455
        # Specific sort
456
        try:
457
            stats.sort(key=sort_lambda, reverse=reverse)
458
        except Exception:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
459
            # If an error is detected, fallback to cpu_percent
460
            stats.sort(key=lambda process: (weighted(process['cpu_percent']),
461
                                            weighted(process[sortedby_secondary])),
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
462
                       reverse=reverse)
463
    else:
464
        # Standard sort
465
        try:
466
            stats.sort(key=lambda process: (weighted(process[sortedby]),
467
                                            weighted(process[sortedby_secondary])),
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
468
                       reverse=reverse)
469
        except (KeyError, TypeError):
470
            # Fallback to name
471
            stats.sort(key=lambda process: process['name'] if process['name'] is not None else '~',
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (99/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
472
                       reverse=False)
473
474
    return stats
475
476
477
glances_processes = GlancesProcesses()
0 ignored issues
show
Coding Style Naming introduced by
The name glances_processes does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
478