Test Failed
Push — master ( 894e04...8e9f07 )
by Nicolas
03:42 queued 13s
created

print_limits()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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