Test Failed
Push — develop ( 9add1f...5c0540 )
by Nicolas
02:01 queued 11s
created

print_plugin_description()   A

Complexity

Conditions 4

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nop 2
dl 0
loc 12
rs 9.9
c 0
b 0
f 0
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
"""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_plugins_list(stat):
57
    sub_title = 'GET plugins list'
58
    print(sub_title)
59
    print('-' * len(sub_title))
60
    print('')
61
    print('Get the plugins list::')
62
    print('')
63
    print('    # curl {}/pluginslist'.format(API_URL))
64
    print(indent_stat(stat))
65
    print('')
66
67
68
def print_plugin_export(plugin, stat_export):
69
    sub_title = 'GET {}'.format(plugin)
70
    print(sub_title)
71
    print('-' * len(sub_title))
72
    print('')
73
74
    print('Get plugin stats::')
75
    print('')
76
    print('    # curl {}/{}'.format(API_URL, plugin))
77
    print(indent_stat(stat_export))
78
    print('')
79
80
81
def print_plugin_description(plugin, stat):
82
    if stat.fields_description:
83
        # For each plugins with a description
84
        print('Fields descriptions:')
85
        print('')
86
        for field, description in iteritems(stat.fields_description):
87
            print('* **{}**: {} (unit is *{}*)'.format(field,
88
                    description['description'][:-1] if description['description'].endswith('.') else description['description'],
89
                    description['unit']))
90
        print('')
91
    else:
92
        logger.error('No fields_description variable defined for plugin {}'.format(plugin))
93
94
95
def print_plugin_item_value(plugin, stat, stat_export):
96
    item = None
97
    value = None
98
    if isinstance(stat_export, dict):
99
        item = list(stat_export.keys())[0]
100
        value = None
101
    elif isinstance(stat_export, list) and len(stat_export) > 0 and isinstance(stat_export[0], dict):
102
        if 'key' in stat_export[0]:
103
            item = stat_export[0]['key']
104
        else:
105
            item = list(stat_export[0].keys())[0]
106
    if item and stat.get_stats_item(item):
107
        stat_item = json.loads(stat.get_stats_item(item))
108
        if isinstance(stat_item[item], list):
109
            value = stat_item[item][0]
110
        else:
111
            value = stat_item[item]
112
        print('Get a specific field::')
113
        print('')
114
        print('    # curl {}/{}/{}'.format(API_URL, plugin, item))
115
        print(indent_stat(stat_item))
116
        print('')
117
    if item and value and stat.get_stats_value(item, value):
118
        print('Get a specific item when field matchs the given value::')
119
        print('')
120
        print('    # curl {}/{}/{}/{}'.format(API_URL, plugin, item, value))
121
        print(indent_stat(json.loads(stat.get_stats_value(item, value))))
122
        print('')
123
124
125
def print_all():
126
    sub_title = 'GET all stats'
127
    print(sub_title)
128
    print('-' * len(sub_title))
129
    print('')
130
    print('Get all Glances stats::')
131
    print('')
132
    print('    # curl {}/all'.format(API_URL))
133
    print('    Return a very big dictionnary (avoid using this request, performances will be poor)...')
134
    print('')
135
136
137
def print_history(stats):
138
    time.sleep(1)
139
    stats.update()
140
    time.sleep(1)
141
    stats.update()
142
    sub_title = 'GET stats history'
143
    print(sub_title)
144
    print('-' * len(sub_title))
145
    print('')
146
    print('History of a plugin::')
147
    print('')
148
    print('    # curl {}/cpu/history'.format(API_URL))
149
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=3))))
150
    print('')
151
    print('Limit history to last 2 values::')
152
    print('')
153
    print('    # curl {}/cpu/history/2'.format(API_URL))
154
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=2))))
155
    print('')
156
    print('History for a specific field::')
157
    print('')
158
    print('    # curl {}/cpu/system/history'.format(API_URL))
159
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system'))))
160
    print('')
161
    print('Limit history for a specific field to last 2 values::')
162
    print('')
163
    print('    # curl {}/cpu/system/history'.format(API_URL))
164
    print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system', nb=2))))
165
    print('')
166
167
168
def print_limits(stats):
169
    sub_title = 'GET limits (used for thresholds)'
170
    print(sub_title)
171
    print('-' * len(sub_title))
172
    print('')
173
    print('All limits/thresholds::')
174
    print('')
175
    print('    # curl {}/all/limits'.format(API_URL))
176
    print(indent_stat(stats.getAllLimitsAsDict()))
177
    print('')
178
    print('Limits/thresholds for the cpu plugin::')
179
    print('')
180
    print('    # curl {}/cpu/limits'.format(API_URL))
181
    print(indent_stat(stats.get_plugin('cpu').limits))
182
    print('')
183
184
185
class GlancesStdoutApiDoc(object):
186
187
    """
188
    This class manages the fields description display.
189
    """
190
191
    def __init__(self, config=None, args=None):
192
        # Init
193
        self.config = config
194
        self.args = args
195
196
    def end(self):
197
        pass
198
199
    def update(self,
200
               stats,
201
               duration=1):
202
        """Display issue
203
        """
204
205
        # Display header
206
        print(APIDOC_HEADER)
207
208
        # Display plugins list
209
        print_plugins_list(sorted(stats._plugins))
210
211
        # Loop over plugins
212
        for plugin in sorted(stats._plugins):
213
            stat = stats.get_plugin(plugin)
214
            stat_export = stat.get_export()
215
            if stat_export is None or stat_export == [] or stat_export == {}:
216
                continue
217
            print_plugin_export(plugin, stat_export)
218
            print_plugin_description(plugin, stat)
219
            print_plugin_item_value(plugin, stat, stat_export)
220
221
        # Get all stats
222
        print_all()
223
224
        # History
225
        print_history(stats)
226
227
        # Limits
228
        print_limits(stats)
229
230
        # Return True to exit directly (no refresh)
231
        return True
232