1 | # -*- coding: utf-8 -*- |
||
2 | # |
||
3 | # This file is part of Glances. |
||
4 | # |
||
5 | # Copyright (C) 2019 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 | """Graph exporter interface class.""" |
||
21 | |||
22 | from pygal import DateTimeLine |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
23 | import pygal.style |
||
0 ignored issues
–
show
|
|||
24 | import sys |
||
25 | import os |
||
26 | import tempfile |
||
27 | import errno |
||
28 | |||
29 | from glances.logger import logger |
||
30 | from glances.timer import Timer |
||
31 | from glances.compat import iteritems, time_serie_subsample |
||
32 | from glances.exports.glances_export import GlancesExport |
||
33 | |||
34 | |||
35 | class Export(GlancesExport): |
||
36 | |||
37 | """This class manages the Graph export module.""" |
||
38 | |||
39 | def __init__(self, config=None, args=None): |
||
40 | """Init the export IF.""" |
||
41 | super(Export, self).__init__(config=config, args=args) |
||
42 | |||
43 | # Load the Graph configuration file section (is exists) |
||
44 | self.export_enable = self.load_conf('graph', |
||
45 | options=['path', |
||
46 | 'generate_every', |
||
47 | 'width', |
||
48 | 'height', |
||
49 | 'style']) |
||
50 | |||
51 | # Manage options (command line arguments overwrite configuration file) |
||
52 | self.path = args.export_graph_path or self.path |
||
53 | self.generate_every = int(getattr(self, 'generate_every', 0)) |
||
54 | self.width = int(getattr(self, 'width', 800)) |
||
55 | self.height = int(getattr(self, 'height', 600)) |
||
56 | self.style = getattr(pygal.style, |
||
57 | getattr(self, 'style', 'DarkStyle'), |
||
58 | pygal.style.DarkStyle) |
||
59 | |||
60 | # Create export folder |
||
61 | try: |
||
62 | os.makedirs(self.path) |
||
63 | except OSError as e: |
||
64 | if e.errno != errno.EEXIST: |
||
65 | logger.critical("Cannot create the Graph output folder {} ({})".format(self.path, e)) |
||
66 | sys.exit(2) |
||
67 | |||
68 | # Check if output folder is writeable |
||
69 | try: |
||
70 | tempfile.TemporaryFile(dir=self.path) |
||
71 | except OSError as e: |
||
72 | logger.critical("Graph output folder {} is not writeable".format(self.path)) |
||
73 | sys.exit(2) |
||
74 | |||
75 | logger.info("Graphs will be created in the {} folder".format(self.path)) |
||
76 | logger.info("Graphs will be created when 'g' key is pressed (in the CLI interface)") |
||
77 | if self.generate_every != 0: |
||
78 | logger.info("Graphs will be created automatically every {} seconds".format(self.generate_every)) |
||
79 | # Start the timer |
||
80 | self._timer = Timer(self.generate_every) |
||
81 | else: |
||
82 | self._timer = None |
||
83 | |||
84 | def exit(self): |
||
85 | """Close the files.""" |
||
86 | logger.debug("Finalise export interface %s" % self.export_name) |
||
87 | |||
88 | def update(self, stats): |
||
89 | """Generate Graph file in the output folder.""" |
||
90 | |||
91 | if self.generate_every != 0 and self._timer.finished(): |
||
92 | self.args.generate_graph = True |
||
93 | self._timer.reset() |
||
94 | |||
95 | if not self.args.generate_graph: |
||
96 | return |
||
97 | |||
98 | plugins = stats.getPluginsList() |
||
99 | for plugin_name in plugins: |
||
100 | plugin = stats._plugins[plugin_name] |
||
0 ignored issues
–
show
It seems like
_plugins was declared protected and should not be accessed from this context.
Prefixing a member variable class MyParent:
def __init__(self):
self._x = 1;
self.y = 2;
class MyChild(MyParent):
def some_method(self):
return self._x # Ok, since accessed from a child class
class AnotherClass:
def some_method(self, instance_of_my_child):
return instance_of_my_child._x # Would be flagged as AnotherClass is not
# a child class of MyParent
Loading history...
|
|||
101 | if plugin_name in self.plugins_to_export(): |
||
102 | self.export(plugin_name, plugin.get_export_history()) |
||
103 | |||
104 | logger.info("Graphs created in the folder {}".format(self.path)) |
||
105 | self.args.generate_graph = False |
||
106 | |||
107 | def export(self, title, data): |
||
108 | """Generate graph from the data. |
||
109 | |||
110 | Example for the mem plugin: |
||
111 | {'percent': [ |
||
112 | (datetime.datetime(2018, 3, 24, 16, 27, 47, 282070), 51.8), |
||
113 | (datetime.datetime(2018, 3, 24, 16, 27, 47, 540999), 51.9), |
||
114 | (datetime.datetime(2018, 3, 24, 16, 27, 50, 653390), 52.0), |
||
115 | (datetime.datetime(2018, 3, 24, 16, 27, 53, 749702), 52.0), |
||
116 | (datetime.datetime(2018, 3, 24, 16, 27, 56, 825660), 52.0), |
||
117 | ... |
||
118 | ] |
||
119 | } |
||
120 | |||
121 | Return: |
||
122 | * True if the graph have been generated |
||
123 | * False if the graph have not been generated |
||
124 | """ |
||
125 | if data == {}: |
||
126 | return False |
||
127 | |||
128 | chart = DateTimeLine(title=title.capitalize(), |
||
129 | width=self.width, |
||
130 | height=self.height, |
||
131 | style=self.style, |
||
132 | show_dots=False, |
||
133 | legend_at_bottom=True, |
||
134 | x_label_rotation=20, |
||
135 | x_value_formatter=lambda dt: dt.strftime('%Y/%m/%d %H:%M:%S')) |
||
136 | for k, v in iteritems(time_serie_subsample(data, self.width)): |
||
137 | chart.add(k, v) |
||
138 | chart.render_to_file(os.path.join(self.path, |
||
139 | title + '.svg')) |
||
140 | return True |
||
141 |