Test Failed
Push — develop ( 24a3ae...5f48d5 )
by Nicolas
02:20 queued 14s
created

glances.standalone   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 112
dl 0
loc 209
rs 10
c 0
b 0
f 0
wmc 29

8 Methods

Rating   Name   Duplication   Size   Complexity  
A GlancesStandalone.display_modules_list() 0 4 1
A GlancesStandalone.serve_forever() 0 7 3
A GlancesStandalone.end() 0 19 3
A GlancesStandalone.__serve_once() 0 34 3
A GlancesStandalone.serve_n() 0 5 3
A GlancesStandalone.serve_issue() 0 8 1
A GlancesStandalone.quiet() 0 3 1
F GlancesStandalone.__init__() 0 86 14
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <[email protected]>
6
#
7
# SPDX-License-Identifier: LGPL-3.0-only
8
#
9
10
"""Manage the Glances standalone session."""
11
12
import sys
13
import time
14
15
from glances.logger import logger
16
17
from glances.globals import WINDOWS
18
from glances.processes import glances_processes
19
from glances.stats import GlancesStats
20
from glances.outputs.glances_curses import GlancesCursesStandalone
21
from glances.outputs.glances_stdout import GlancesStdout
22
from glances.outputs.glances_stdout_json import GlancesStdoutJson
23
from glances.outputs.glances_stdout_csv import GlancesStdoutCsv
24
from glances.outputs.glances_stdout_issue import GlancesStdoutIssue
25
from glances.outputs.glances_stdout_apidoc import GlancesStdoutApiDoc
26
from glances.outdated import Outdated
27
from glances.timer import Counter
28
29
30
class GlancesStandalone(object):
31
32
    """This class creates and manages the Glances standalone session."""
33
34
    def __init__(self, config=None, args=None):
35
        self.config = config
36
        self.args = args
37
38
        # Quiet mode
39
        self._quiet = args.quiet
40
        self.refresh_time = args.time
41
42
        # Init stats
43
        start_duration = Counter()
44
        start_duration.reset()
45
        self.stats = GlancesStats(config=config, args=args)
46
        logger.debug("Plugins initialisation duration: {} seconds".format(start_duration.get()))
47
48
        # Modules (plugins and exporters) are loaded at this point
49
        # Glances can display the list if asked...
50
        if args.modules_list:
51
            self.display_modules_list()
52
            sys.exit(0)
53
54
        # The args is needed to get the selected process in the process list (Curses mode)
55
        glances_processes.set_args(args)
56
57
        # If process extended stats is disabled by user
58
        if not args.enable_process_extended:
59
            logger.debug("Extended stats for top process are disabled")
60
            glances_processes.disable_extended()
61
        else:
62
            logger.debug("Extended stats for top process are enabled")
63
            glances_processes.enable_extended()
64
65
        # Manage optional process filter
66
        if args.process_filter is not None:
67
            logger.info("Process filter is set to: {}".format(args.process_filter))
68
            glances_processes.process_filter = args.process_filter
69
70
        if args.export and args.export_process_filter is not None:
71
            logger.info("Export process filter is set to: {}".format(args.export_process_filter))
72
            glances_processes.export_process_filter = args.export_process_filter
73
74
        if (not WINDOWS) and args.no_kernel_threads:
75
            # Ignore kernel threads in process list
76
            glances_processes.disable_kernel_threads()
77
78
        # Initial system information update
79
        start_duration.reset()
80
        self.stats.update()
81
        logger.debug("First stats update duration: {} seconds".format(start_duration.get()))
82
83
        if self.quiet:
84
            logger.info("Quiet mode is ON, nothing will be displayed")
85
            # In quiet mode, nothing is displayed
86
            glances_processes.max_processes = 0
87
        elif args.stdout_issue:
88
            logger.info("Issue mode is ON")
89
            # Init screen
90
            self.screen = GlancesStdoutIssue(config=config, args=args)
91
        elif args.stdout_apidoc:
92
            logger.info("Fields descriptions mode is ON")
93
            # Init screen
94
            self.screen = GlancesStdoutApiDoc(config=config, args=args)
95
        elif args.stdout:
96
            logger.info("Stdout mode is ON, following stats will be displayed: {}".format(args.stdout))
97
            # Init screen
98
            self.screen = GlancesStdout(config=config, args=args)
99
        elif args.stdout_json:
100
            logger.info("Stdout JSON mode is ON, following stats will be displayed: {}".format(args.stdout_json))
101
            # Init screen
102
            self.screen = GlancesStdoutJson(config=config, args=args)
103
        elif args.stdout_csv:
104
            logger.info("Stdout CSV mode is ON, following stats will be displayed: {}".format(args.stdout_csv))
105
            # Init screen
106
            self.screen = GlancesStdoutCsv(config=config, args=args)
107
        else:
108
            # Default number of processes to displayed is set to 50
109
            glances_processes.max_processes = 50
110
111
            # Init screen
112
            self.screen = GlancesCursesStandalone(config=config, args=args)
113
114
            # If an error occur during the screen init, continue if export option is set
115
            # It is done in the screen.init function
116
            self._quiet = args.quiet
117
118
        # Check the latest Glances version
119
        self.outdated = Outdated(config=config, args=args)
120
121
    @property
122
    def quiet(self):
123
        return self._quiet
124
125
    def display_modules_list(self):
126
        """Display modules list"""
127
        print("Plugins list: {}".format(', '.join(sorted(self.stats.getPluginsList(enable=False)))))
128
        print("Exporters list: {}".format(', '.join(sorted(self.stats.getExportsList(enable=False)))))
129
130
    def serve_issue(self):
131
        """Special mode for the --issue option
132
133
        Update is done in the screen.update function
134
        """
135
        ret = not self.screen.update(self.stats)
136
        self.end()
137
        return ret
138
139
    def __serve_once(self):
140
        """Main loop for the CLI.
141
142
        :return: True if we should continue (no exit key has been pressed)
143
        """
144
        # Update stats
145
        # Start a counter used to compute the time needed
146
        counter = Counter()
147
        self.stats.update()
148
        logger.debug('Stats updated duration: {} seconds'.format(counter.get()))
149
150
        # Patch for issue1326 to avoid < 0 refresh
151
        adapted_refresh = self.refresh_time - counter.get()
152
        adapted_refresh = adapted_refresh if adapted_refresh > 0 else 0
153
154
        # Display stats
155
        # and wait refresh_time - counter
156
        if not self.quiet:
157
            # The update function return True if an exit key 'q' or 'ESC'
158
            # has been pressed.
159
            ret = not self.screen.update(self.stats, duration=adapted_refresh)
160
        else:
161
            # Nothing is displayed
162
            # Break should be done via a signal (CTRL-C)
163
            time.sleep(adapted_refresh)
164
            ret = True
165
166
        # Export stats
167
        # Start a counter used to compute the time needed
168
        counter_export = Counter()
169
        self.stats.export(self.stats)
170
        logger.debug('Stats exported duration: {} seconds'.format(counter_export.get()))
171
172
        return ret
173
174
    def serve_n(self, n=1):
175
        """Serve n time."""
176
        for _ in range(n):
177
            if not self.__serve_once():
178
                break
179
        # self.end()
180
181
    def serve_forever(self):
182
        """Wrapper to the serve_forever function."""
183
        if self.args.stop_after:
184
            self.serve_n(self.args.stop_after)
185
        else:
186
            while self.__serve_once():
187
                pass
188
        # self.end()
189
190
    def end(self):
191
        """End of the standalone CLI."""
192
        if not self.quiet:
193
            self.screen.end()
194
195
        # Exit from export modules
196
        self.stats.end()
197
198
        # Check Glances version versus PyPI one
199
        if self.outdated.is_outdated():
200
            print(
201
                "You are using Glances version {}, however version {} is available.".format(
202
                    self.outdated.installed_version(), self.outdated.latest_version()
203
                )
204
            )
205
            print("You should consider upgrading using: pip install --upgrade glances")
206
            print("Disable this warning temporarily using: glances --disable-check-update")
207
            print(
208
                "To disable it permanently, refer config reference at "
209
                "https://glances.readthedocs.io/en/latest/config.html#syntax"
210
            )
211