Issues (46)

glances/__init__.py (5 issues)

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <[email protected]>
6
#
7
# SPDX-License-Identifier: LGPL-3.0-only
8
#
9
#
10
11
"""Init the Glances software."""
12
13
# Import system libs
14
import locale
15
import platform
16
import signal
17
import sys
18
19
# Global name
20
# Version should start and end with a numerical char
21
# See https://packaging.python.org/specifications/core-metadata/#version
22
__version__ = '3.4.0.5'
23
__author__ = 'Nicolas Hennion <[email protected]>'
24
__license__ = 'LGPLv3'
25
26
# Import psutil
27
try:
28
    from psutil import __version__ as psutil_version
29
except ImportError:
30
    print('psutil library not found. Glances cannot start.')
31
    sys.exit(1)
32
33
# Import Glances libs
34
# Note: others Glances libs will be imported optionally
35
from glances.compat import PY3
36
from glances.logger import logger
37
from glances.main import GlancesMain
38
from glances.timer import Counter
39
40
# Check locale
41
try:
42
    locale.setlocale(locale.LC_ALL, '')
43
except locale.Error:
44
    print("Warning: Unable to set locale. Expect encoding problems.")
45
46
# Check Python version
47
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
48
    print('Glances requires at least Python 2.7 or 3.4 to run.')
49
    sys.exit(1)
50
51
# Check psutil version
52
psutil_min_version = (5, 3, 0)
53
psutil_version_info = tuple([int(num) for num in psutil_version.split('.')])
54
if psutil_version_info < psutil_min_version:
55
    print('psutil 5.3.0 or higher is needed. Glances cannot start.')
56
    sys.exit(1)
57
58
# Trac malloc is only available on Python 3.4 or higher
59
if PY3:
60
    import tracemalloc
61
62
63
def __signal_handler(signal, frame):
64
    logger.debug("Signal {} catched".format(signal))
65
    end()
66
67
68
def end():
69
    """Stop Glances."""
70
    try:
71
        mode.end()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable mode does not seem to be defined.
Loading history...
72
    except (NameError, KeyError):
73
        # NameError: name 'mode' is not defined in case of interrupt shortly...
74
        # ...after starting the server mode (issue #1175)
75
        pass
76
77
    logger.info("Glances stopped gracefully")
78
79
    # The end...
80
    sys.exit(0)
81
82
83
def start(config, args):
84
    """Start Glances."""
85
86
    # Load mode
87
    global mode
88
89
    if args.trace_malloc or args.memory_leak:
90
        tracemalloc.start()
0 ignored issues
show
The variable tracemalloc does not seem to be defined in case PY3 on line 59 is False. Are you sure this can never be the case?
Loading history...
91
92
    start_duration = Counter()
93
94
    if core.is_standalone():
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable core does not seem to be defined.
Loading history...
95
        from glances.standalone import GlancesStandalone as GlancesMode
96
    elif core.is_client():
97
        if core.is_client_browser():
98
            from glances.client_browser import GlancesClientBrowser as GlancesMode
99
        else:
100
            from glances.client import GlancesClient as GlancesMode
101
    elif core.is_server():
102
        from glances.server import GlancesServer as GlancesMode
103
    elif core.is_webserver():
104
        from glances.webserver import GlancesWebServer as GlancesMode
105
106
    # Init the mode
107
    logger.info("Start {} mode".format(GlancesMode.__name__))
0 ignored issues
show
The variable GlancesMode does not seem to be defined for all execution paths.
Loading history...
108
    mode = GlancesMode(config=config, args=args)
109
110
    # Start the main loop
111
    logger.debug("Glances started in {} seconds".format(start_duration.get()))
112
    if args.stop_after:
113
        logger.info('Glances will be stopped in ~{} seconds'.format(args.stop_after * args.time * args.memory_leak * 2))
114
115
    if args.memory_leak:
116
        print(
117
            'Memory leak detection, please wait ~{} seconds...'.format(
118
                args.stop_after * args.time * args.memory_leak * 2
119
            )
120
        )
121
        # First run without dump to fill the memory
122
        mode.serve_n(args.stop_after)
123
        # Then start the memory-leak loop
124
        snapshot_begin = tracemalloc.take_snapshot()
125
126
    if args.stdout_issue or args.stdout_apidoc:
127
        # Serve once for issue/test mode
128
        mode.serve_issue()
129
    else:
130
        # Serve forever
131
        mode.serve_forever()
132
133
    if args.memory_leak:
134
        snapshot_end = tracemalloc.take_snapshot()
135
        snapshot_diff = snapshot_end.compare_to(snapshot_begin, 'filename')
0 ignored issues
show
The variable snapshot_begin does not seem to be defined in case args.memory_leak on line 115 is False. Are you sure this can never be the case?
Loading history...
136
        memory_leak = sum([s.size_diff for s in snapshot_diff])
137
        print("Memory consumption: {0:.1f}KB (see log for details)".format(memory_leak / 1000))
138
        logger.info("Memory consumption (top 5):")
139
        for stat in snapshot_diff[:5]:
140
            logger.info(stat)
141
    elif args.trace_malloc:
142
        # See more options here: https://docs.python.org/3/library/tracemalloc.html
143
        snapshot = tracemalloc.take_snapshot()
144
        top_stats = snapshot.statistics("filename")
145
        print("[ Trace malloc - Top 10 ]")
146
        for stat in top_stats[:10]:
147
            print(stat)
148
149
    # Shutdown
150
    mode.end()
151
152
153
def main():
154
    """Main entry point for Glances.
155
156
    Select the mode (standalone, client or server)
157
    Run it...
158
    """
159
    # SIGHUP not available on Windows (see issue #2408)
160
    if sys.platform.startswith('win'):
161
        signal_list = (signal.SIGTERM, signal.SIGINT)
162
    else:
163
        signal_list = (signal.SIGTERM, signal.SIGINT, signal.SIGHUP)
164
    # Catch the kill signal
165
    for sig in signal_list:
166
        signal.signal(sig, __signal_handler)
167
168
    # Log Glances and psutil version
169
    logger.info('Start Glances {}'.format(__version__))
170
    logger.info(
171
        '{} {} ({}) and psutil {} detected'.format(
172
            platform.python_implementation(), platform.python_version(), sys.executable, psutil_version
173
        )
174
    )
175
176
    # Share global var
177
    global core
178
179
    # Create the Glances main instance
180
    # Glances options from the command line are read first (in __init__)
181
    # then the options from the config file (in parse_args)
182
    core = GlancesMain()
183
184
    # Glances can be ran in standalone, client or server mode
185
    start(config=core.get_config(), args=core.get_args())
186