GlancesStandalone.display_modules_list()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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