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

glances.outputs.glances_stdout_apidoc   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 162
dl 0
loc 251
rs 9.76
c 0
b 0
f 0
wmc 33

9 Functions

Rating   Name   Duplication   Size   Complexity  
A indent_stat() 0 7 4
A print_api_status() 0 13 1
A print_plugin_export() 0 11 1
A print_history() 0 29 1
A print_plugin_description() 0 18 4
A print_all() 0 10 1
A print_limits() 0 15 1
D print_plugin_item_value() 0 28 12
A print_plugins_list() 0 10 1

3 Methods

Rating   Name   Duplication   Size   Complexity  
A GlancesStdoutApiDoc.__init__() 0 4 1
A GlancesStdoutApiDoc.end() 0 2 1
A GlancesStdoutApiDoc.update() 0 33 5
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2022 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
"""Fields description interface class."""
21
22
from pprint import pformat
23
import json
24
import time
25
26
from glances.logger import logger
27
from glances.compat import iteritems
28
29
API_URL = "http://localhost:61208/api/3"
30
31
APIDOC_HEADER = """\
32
.. _api:
33
34
API (Restfull/JSON) documentation
35
=================================
36
37
The Glances Restfull/API server could be ran using the following command line:
38
39
.. code-block:: bash
40
41
    # glances -w --disable-webui
42
43
Note: Change request URL api/3 by api/2 if you use Glances 2.x.
44
"""
45
46
47
def indent_stat(stat, indent='    '):
48
    # Indent stats to pretty print it
49
    if isinstance(stat, list) and len(stat) > 1 and isinstance(stat[0], dict):
50
        # Only display two first items
51
        return indent + pformat(stat[0:2]).replace('\n', '\n' + indent)
52
    else:
53
        return indent + pformat(stat).replace('\n', '\n' + indent)
54
55
56
def print_api_status():
57
    sub_title = 'GET API status'
58
    print(sub_title)
59
    print('-' * len(sub_title))
60
    print('')
61
    print('This entry point should be used to check the API status.')
62
    print('It will return nothing but a 200 return code if everythin is OK.')
63
    print('')
64
    print('Get the Rest API status::')
65
    print('')
66
    print('    # curl -I {}/status'.format(API_URL))
67
    print(indent_stat('HTTP/1.0 200 OK'))
68
    print('')
69
70
71
def print_plugins_list(stat):
72
    sub_title = 'GET plugins list'
73
    print(sub_title)
74
    print('-' * len(sub_title))
75
    print('')
76
    print('Get the plugins list::')
77
    print('')
78
    print('    # curl {}/pluginslist'.format(API_URL))
79
    print(indent_stat(stat))
80
    print('')
81
82
83
def print_plugin_export(plugin, stat_export):
84
    sub_title = 'GET {}'.format(plugin)
85
    print(sub_title)
86
    print('-' * len(sub_title))
87
    print('')
88
89
    print('Get plugin stats::')
90
    print('')
91
    print('    # curl {}/{}'.format(API_URL, plugin))
92
    print(indent_stat(stat_export))
93
    print('')
94
95
96
def print_plugin_description(plugin, stat):
97
    if stat.fields_description:
98
        # For each plugins with a description
99
        print('Fields descriptions:')
100
        print('')
101
        for field, description in iteritems(stat.fields_description):
102
            print(
103
                '* **{}**: {} (unit is *{}*)'.format(
104
                    field,
105
                    description['description'][:-1]
106
                    if description['description'].endswith('.')
107
                    else description['description'],
108
                    description['unit'],
109
                )
110
            )
111
        print('')
112
    else:
113
        logger.error('No fields_description variable defined for plugin {}'.format(plugin))
114
115
116
def print_plugin_item_value(plugin, stat, stat_export):
117
    item = None
118
    value = None
119
    if isinstance(stat_export, dict):
120
        item = list(stat_export.keys())[0]
121
        value = None
122
    elif isinstance(stat_export, list) and len(stat_export) > 0 and isinstance(stat_export[0], dict):
123
        if 'key' in stat_export[0]:
124
            item = stat_export[0]['key']
125
        else:
126
            item = list(stat_export[0].keys())[0]
127
    if item and stat.get_stats_item(item):
128
        stat_item = json.loads(stat.get_stats_item(item))
129
        if isinstance(stat_item[item], list):
130
            value = stat_item[item][0]
131
        else:
132
            value = stat_item[item]
133
        print('Get a specific field::')
134
        print('')
135
        print('    # curl {}/{}/{}'.format(API_URL, plugin, item))
136
        print(indent_stat(stat_item))
137
        print('')
138
    if item and value and stat.get_stats_value(item, value):
139
        print('Get a specific item when field matchs the given value::')
140
        print('')
141
        print('    # curl {}/{}/{}/{}'.format(API_URL, plugin, item, value))
142
        print(indent_stat(json.loads(stat.get_stats_value(item, value))))
143
        print('')
144
145
146
def print_all():
147
    sub_title = 'GET all stats'
148
    print(sub_title)
149
    print('-' * len(sub_title))
150
    print('')
151
    print('Get all Glances stats::')
152
    print('')
153
    print('    # curl {}/all'.format(API_URL))
154
    print('    Return a very big dictionnary (avoid using this request, performances will be poor)...')
155
    print('')
156
157
158
def print_history(stats):
159
    time.sleep(1)
160
    stats.update()
161
    time.sleep(1)
162
    stats.update()
163
    sub_title = 'GET stats history'
164
    print(sub_title)
165
    print('-' * len(sub_title))
166
    print('')
167
    print('History of a plugin::')
168
    print('')
169
    print('    # curl {}/cpu/history'.format(API_URL))
170
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=3))))
171
    print('')
172
    print('Limit history to last 2 values::')
173
    print('')
174
    print('    # curl {}/cpu/history/2'.format(API_URL))
175
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=2))))
176
    print('')
177
    print('History for a specific field::')
178
    print('')
179
    print('    # curl {}/cpu/system/history'.format(API_URL))
180
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system'))))
181
    print('')
182
    print('Limit history for a specific field to last 2 values::')
183
    print('')
184
    print('    # curl {}/cpu/system/history'.format(API_URL))
185
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system', nb=2))))
186
    print('')
187
188
189
def print_limits(stats):
190
    sub_title = 'GET limits (used for thresholds)'
191
    print(sub_title)
192
    print('-' * len(sub_title))
193
    print('')
194
    print('All limits/thresholds::')
195
    print('')
196
    print('    # curl {}/all/limits'.format(API_URL))
197
    print(indent_stat(stats.getAllLimitsAsDict()))
198
    print('')
199
    print('Limits/thresholds for the cpu plugin::')
200
    print('')
201
    print('    # curl {}/cpu/limits'.format(API_URL))
202
    print(indent_stat(stats.get_plugin('cpu').limits))
203
    print('')
204
205
206
class GlancesStdoutApiDoc(object):
207
208
    """This class manages the fields description display."""
209
210
    def __init__(self, config=None, args=None):
211
        # Init
212
        self.config = config
213
        self.args = args
214
215
    def end(self):
216
        pass
217
218
    def update(self, stats, duration=1):
219
        """Display issue"""
220
221
        # Display header
222
        print(APIDOC_HEADER)
223
224
        # Display API status
225
        print_api_status()
226
227
        # Display plugins list
228
        print_plugins_list(sorted(stats._plugins))
229
230
        # Loop over plugins
231
        for plugin in sorted(stats._plugins):
232
            stat = stats.get_plugin(plugin)
233
            stat_export = stat.get_export()
234
            if stat_export is None or stat_export == [] or stat_export == {}:
235
                continue
236
            print_plugin_export(plugin, stat_export)
237
            print_plugin_description(plugin, stat)
238
            print_plugin_item_value(plugin, stat, stat_export)
239
240
        # Get all stats
241
        print_all()
242
243
        # History
244
        print_history(stats)
245
246
        # Limits
247
        print_limits(stats)
248
249
        # Return True to exit directly (no refresh)
250
        return True
251