Issues (48)

glances/__init__.py (4 issues)

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