Test Failed
Push — master ( 7e7379...128504 )
by Nicolas
03:31
created

glances.start()   F

Complexity

Conditions 16

Size

Total Lines 68
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 44
nop 2
dl 0
loc 68
rs 2.4
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like glances.start() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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