1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | |
---|
4 | import os |
---|
5 | import json |
---|
6 | import re |
---|
7 | import sys |
---|
8 | import time |
---|
9 | |
---|
10 | STAT_VALIDITY = 300 # 5min limit on reporting stats |
---|
11 | |
---|
12 | PLUGINS = { |
---|
13 | # LOAD AVERAGE |
---|
14 | 'tahoe_runtime_load_avg': |
---|
15 | { 'statid': 'load_monitor.avg_load', |
---|
16 | 'category': 'stats', |
---|
17 | 'configheader': '\n'.join(['graph_title Tahoe Runtime Load Average', |
---|
18 | 'graph_vlabel load', |
---|
19 | 'graph_category tahoe', |
---|
20 | 'graph_info This graph shows average reactor delay', |
---|
21 | ]), |
---|
22 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
23 | '%(name)s.draw LINE1', |
---|
24 | ]), |
---|
25 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
26 | ]), |
---|
27 | }, |
---|
28 | |
---|
29 | 'tahoe_runtime_load_peak': |
---|
30 | { 'statid': 'load_monitor.max_load', |
---|
31 | 'category': 'stats', |
---|
32 | 'configheader': '\n'.join(['graph_title Tahoe Runtime Load Peak', |
---|
33 | 'graph_vlabel load', |
---|
34 | 'graph_category tahoe', |
---|
35 | 'graph_info This graph shows peak reactor delay', |
---|
36 | ]), |
---|
37 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
38 | '%(name)s.draw LINE1', |
---|
39 | ]), |
---|
40 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
41 | ]), |
---|
42 | }, |
---|
43 | |
---|
44 | # STORAGE ALLOCATION (BYTES) |
---|
45 | 'tahoe_storage_consumed': |
---|
46 | { 'statid': 'storage_server.consumed', |
---|
47 | 'category': 'stats', |
---|
48 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server Space Consumed', |
---|
49 | 'graph_vlabel bytes', |
---|
50 | 'graph_category tahoe_storage_server', |
---|
51 | 'graph_info This graph shows space consumed', |
---|
52 | 'graph_args --base 1024', |
---|
53 | ]), |
---|
54 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
55 | '%(name)s.draw LINE1', |
---|
56 | ]), |
---|
57 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
58 | ]), |
---|
59 | }, |
---|
60 | |
---|
61 | 'tahoe_storage_allocated': |
---|
62 | { 'statid': 'storage_server.allocated', |
---|
63 | 'category': 'stats', |
---|
64 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server Space Allocated', |
---|
65 | 'graph_vlabel bytes', |
---|
66 | 'graph_category tahoe_storage_server', |
---|
67 | 'graph_info This graph shows space allocated', |
---|
68 | 'graph_args --base 1024', |
---|
69 | ]), |
---|
70 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
71 | '%(name)s.draw LINE1', |
---|
72 | ]), |
---|
73 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
74 | ]), |
---|
75 | }, |
---|
76 | |
---|
77 | 'tahoe_storage_bytes_added': |
---|
78 | { 'statid': 'storage_server.bytes_added', |
---|
79 | 'category': 'counters', |
---|
80 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server Bytes Added', |
---|
81 | 'graph_vlabel bytes', |
---|
82 | 'graph_category tahoe_storage_server', |
---|
83 | 'graph_info This graph shows cummulative bytes added', |
---|
84 | ]), |
---|
85 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
86 | '%(name)s.draw LINE1', |
---|
87 | ]), |
---|
88 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
89 | ]), |
---|
90 | }, |
---|
91 | |
---|
92 | 'tahoe_storage_bytes_freed': |
---|
93 | { 'statid': 'storage_server.bytes_freed', |
---|
94 | 'category': 'counters', |
---|
95 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server Bytes Removed', |
---|
96 | 'graph_vlabel bytes', |
---|
97 | 'graph_category tahoe_storage_server', |
---|
98 | 'graph_info This graph shows cummulative bytes removed', |
---|
99 | ]), |
---|
100 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
101 | '%(name)s.draw LINE1', |
---|
102 | ]), |
---|
103 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
104 | ]), |
---|
105 | }, |
---|
106 | |
---|
107 | 'tahoe_storage_operations_allocate': |
---|
108 | { 'statid': 'storage_server.allocate', |
---|
109 | 'category': 'counters', |
---|
110 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server Allocate_Bucket Operations', |
---|
111 | 'graph_vlabel operations per second', |
---|
112 | 'graph_category tahoe_storage_server', |
---|
113 | 'graph_info This graph shows how many allocate_buckets operations occured per second. Each immutable file upload causes one such operation per server.', |
---|
114 | ]), |
---|
115 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
116 | '%(name)s.type DERIVE', |
---|
117 | '%(name)s.min 0', |
---|
118 | '%(name)s.draw LINE1', |
---|
119 | ]), |
---|
120 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
121 | ]), |
---|
122 | }, |
---|
123 | |
---|
124 | 'tahoe_storage_operations_get': |
---|
125 | { 'statid': 'storage_server.get', |
---|
126 | 'category': 'counters', |
---|
127 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server get_bucket Operations', |
---|
128 | 'graph_vlabel operations per second', |
---|
129 | 'graph_category tahoe_storage_server', |
---|
130 | 'graph_info This graph shows how many get_bucket operations occured per second. Each immutable file download/check causes one such operation per server.', |
---|
131 | ]), |
---|
132 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
133 | '%(name)s.type DERIVE', |
---|
134 | '%(name)s.min 0', |
---|
135 | '%(name)s.draw LINE1', |
---|
136 | ]), |
---|
137 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
138 | ]), |
---|
139 | }, |
---|
140 | |
---|
141 | 'tahoe_storage_operations_writev': |
---|
142 | { 'statid': 'storage_server.writev', |
---|
143 | 'category': 'counters', |
---|
144 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server writev Operations', |
---|
145 | 'graph_vlabel operations per second', |
---|
146 | 'graph_category tahoe_storage_server', |
---|
147 | 'graph_info This graph shows how many writev operations occured per second. Each mutable file / dirnode write causes one such operation per server.', |
---|
148 | ]), |
---|
149 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
150 | '%(name)s.type DERIVE', |
---|
151 | '%(name)s.min 0', |
---|
152 | '%(name)s.draw LINE1', |
---|
153 | ]), |
---|
154 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
155 | ]), |
---|
156 | }, |
---|
157 | |
---|
158 | 'tahoe_storage_operations_readv': |
---|
159 | { 'statid': 'storage_server.readv', |
---|
160 | 'category': 'counters', |
---|
161 | 'configheader': '\n'.join(['graph_title Tahoe Storage Server readv Operations', |
---|
162 | 'graph_vlabel operations per second', |
---|
163 | 'graph_category tahoe_storage_server', |
---|
164 | 'graph_info This graph shows how many readv operations occured per second. Each dirnode read causes one such operation per server.', |
---|
165 | ]), |
---|
166 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
167 | '%(name)s.type DERIVE', |
---|
168 | '%(name)s.min 0', |
---|
169 | '%(name)s.draw LINE1', |
---|
170 | ]), |
---|
171 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
172 | ]), |
---|
173 | }, |
---|
174 | |
---|
175 | |
---|
176 | # HELPER |
---|
177 | 'tahoe_helper_incoming_files': |
---|
178 | { 'statid': 'chk_upload_helper.incoming_count', |
---|
179 | 'category': 'stats', |
---|
180 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Incoming File Count', |
---|
181 | 'graph_vlabel n files', |
---|
182 | 'graph_category tahoe_helper', |
---|
183 | 'graph_info This graph shows number of incoming files', |
---|
184 | ]), |
---|
185 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
186 | '%(name)s.draw LINE1', |
---|
187 | ]), |
---|
188 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
189 | ]), |
---|
190 | }, |
---|
191 | 'tahoe_helper_incoming_filesize': |
---|
192 | { 'statid': 'chk_upload_helper.incoming_size', |
---|
193 | 'category': 'stats', |
---|
194 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Incoming File Size', |
---|
195 | 'graph_vlabel bytes', |
---|
196 | 'graph_category tahoe_helper', |
---|
197 | 'graph_info This graph shows total size of incoming files', |
---|
198 | ]), |
---|
199 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
200 | '%(name)s.draw LINE1', |
---|
201 | ]), |
---|
202 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
203 | ]), |
---|
204 | }, |
---|
205 | 'tahoe_helper_incoming_files_old': |
---|
206 | { 'statid': 'chk_upload_helper.incoming_size_old', |
---|
207 | 'category': 'stats', |
---|
208 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Incoming Old Files', |
---|
209 | 'graph_vlabel bytes', |
---|
210 | 'graph_category tahoe_helper', |
---|
211 | 'graph_info This graph shows total size of old incoming files', |
---|
212 | ]), |
---|
213 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
214 | '%(name)s.draw LINE1', |
---|
215 | ]), |
---|
216 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
217 | ]), |
---|
218 | }, |
---|
219 | |
---|
220 | 'tahoe_helper_encoding_files': |
---|
221 | { 'statid': 'chk_upload_helper.encoding_count', |
---|
222 | 'category': 'stats', |
---|
223 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Encoding File Count', |
---|
224 | 'graph_vlabel n files', |
---|
225 | 'graph_category tahoe_helper', |
---|
226 | 'graph_info This graph shows number of encoding files', |
---|
227 | ]), |
---|
228 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
229 | '%(name)s.draw LINE1', |
---|
230 | ]), |
---|
231 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
232 | ]), |
---|
233 | }, |
---|
234 | 'tahoe_helper_encoding_filesize': |
---|
235 | { 'statid': 'chk_upload_helper.encoding_size', |
---|
236 | 'category': 'stats', |
---|
237 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Encoding File Size', |
---|
238 | 'graph_vlabel bytes', |
---|
239 | 'graph_category tahoe_helper', |
---|
240 | 'graph_info This graph shows total size of encoding files', |
---|
241 | ]), |
---|
242 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
243 | '%(name)s.draw LINE1', |
---|
244 | ]), |
---|
245 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
246 | ]), |
---|
247 | }, |
---|
248 | 'tahoe_helper_encoding_files_old': |
---|
249 | { 'statid': 'chk_upload_helper.encoding_size_old', |
---|
250 | 'category': 'stats', |
---|
251 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Encoding Old Files', |
---|
252 | 'graph_vlabel bytes', |
---|
253 | 'graph_category tahoe_helper', |
---|
254 | 'graph_info This graph shows total size of old encoding files', |
---|
255 | ]), |
---|
256 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
257 | '%(name)s.draw LINE1', |
---|
258 | ]), |
---|
259 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
260 | ]), |
---|
261 | }, |
---|
262 | |
---|
263 | 'tahoe_helper_active_uploads': |
---|
264 | { 'statid': 'chk_upload_helper.active_uploads', |
---|
265 | 'category': 'stats', |
---|
266 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Active Files', |
---|
267 | 'graph_vlabel n files', |
---|
268 | 'graph_category tahoe_helper', |
---|
269 | 'graph_info This graph shows number of files actively being processed by the helper', |
---|
270 | ]), |
---|
271 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
272 | '%(name)s.draw LINE1', |
---|
273 | ]), |
---|
274 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
275 | ]), |
---|
276 | }, |
---|
277 | |
---|
278 | 'tahoe_helper_upload_requests': |
---|
279 | { 'statid': 'chk_upload_helper.upload_requests', |
---|
280 | 'category': 'counters', |
---|
281 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Upload Requests', |
---|
282 | 'graph_vlabel requests', |
---|
283 | 'graph_category tahoe_helper', |
---|
284 | 'graph_info This graph shows the number of upload requests arriving at the helper', |
---|
285 | ]), |
---|
286 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
287 | '%(name)s.type DERIVE', |
---|
288 | '%(name)s.min 0', |
---|
289 | '%(name)s.draw LINE1', |
---|
290 | ]), |
---|
291 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
292 | ]), |
---|
293 | }, |
---|
294 | 'tahoe_helper_upload_already_present': |
---|
295 | { 'statid': 'chk_upload_helper.upload_already_present', |
---|
296 | 'category': 'counters', |
---|
297 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Uploads Already Present', |
---|
298 | 'graph_vlabel requests', |
---|
299 | 'graph_category tahoe_helper', |
---|
300 | 'graph_info This graph shows the number of uploads whose files are already present in the grid', |
---|
301 | ]), |
---|
302 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
303 | '%(name)s.type DERIVE', |
---|
304 | '%(name)s.min 0', |
---|
305 | '%(name)s.draw LINE1', |
---|
306 | ]), |
---|
307 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
308 | ]), |
---|
309 | }, |
---|
310 | 'tahoe_helper_upload_need_upload': |
---|
311 | { 'statid': 'chk_upload_helper.upload_need_upload', |
---|
312 | 'category': 'counters', |
---|
313 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Uploads Needing Upload', |
---|
314 | 'graph_vlabel requests', |
---|
315 | 'graph_category tahoe_helper', |
---|
316 | 'graph_info This graph shows the number of uploads whose files are not already present in the grid', |
---|
317 | ]), |
---|
318 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
319 | '%(name)s.type DERIVE', |
---|
320 | '%(name)s.min 0', |
---|
321 | '%(name)s.draw LINE1', |
---|
322 | ]), |
---|
323 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
324 | ]), |
---|
325 | }, |
---|
326 | 'tahoe_helper_encoded_bytes': |
---|
327 | { 'statid': 'chk_upload_helper.encoded_bytes', |
---|
328 | 'category': 'counters', |
---|
329 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Encoded Bytes', |
---|
330 | 'graph_vlabel bytes', |
---|
331 | 'graph_category tahoe_helper', |
---|
332 | 'graph_info This graph shows the number of bytes encoded by the helper', |
---|
333 | ]), |
---|
334 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
335 | '%(name)s.type DERIVE', |
---|
336 | '%(name)s.min 0', |
---|
337 | '%(name)s.draw LINE1', |
---|
338 | ]), |
---|
339 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
340 | ]), |
---|
341 | }, |
---|
342 | 'tahoe_helper_fetched_bytes': |
---|
343 | { 'statid': 'chk_upload_helper.fetched_bytes', |
---|
344 | 'category': 'counters', |
---|
345 | 'configheader': '\n'.join(['graph_title Tahoe Upload Helper Fetched Bytes', |
---|
346 | 'graph_vlabel bytes', |
---|
347 | 'graph_category tahoe_helper', |
---|
348 | 'graph_info This graph shows the number of bytes fetched by the helper', |
---|
349 | ]), |
---|
350 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
351 | '%(name)s.type DERIVE', |
---|
352 | '%(name)s.min 0', |
---|
353 | '%(name)s.draw LINE1', |
---|
354 | ]), |
---|
355 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
356 | ]), |
---|
357 | }, |
---|
358 | |
---|
359 | # WEBAPI |
---|
360 | 'tahoe_uploader_bytes_uploaded': |
---|
361 | { 'statid': 'uploader.bytes_uploaded', |
---|
362 | 'category': 'counters', |
---|
363 | 'configheader': '\n'.join(['graph_title Tahoe Uploader Bytes Uploaded', |
---|
364 | 'graph_vlabel bytes', |
---|
365 | 'graph_category tahoe_traffic', |
---|
366 | 'graph_info This graph shows the number of bytes uploaded', |
---|
367 | ]), |
---|
368 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
369 | '%(name)s.type DERIVE', |
---|
370 | '%(name)s.min 0', |
---|
371 | '%(name)s.draw LINE1', |
---|
372 | ]), |
---|
373 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
374 | ]), |
---|
375 | }, |
---|
376 | 'tahoe_uploader_files_uploaded': |
---|
377 | { 'statid': 'uploader.files_uploaded', |
---|
378 | 'category': 'counters', |
---|
379 | 'configheader': '\n'.join(['graph_title Tahoe Uploader Bytes Uploaded', |
---|
380 | 'graph_vlabel files', |
---|
381 | 'graph_category tahoe_traffic', |
---|
382 | 'graph_info This graph shows the number of files uploaded', |
---|
383 | ]), |
---|
384 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
385 | '%(name)s.type DERIVE', |
---|
386 | '%(name)s.min 0', |
---|
387 | '%(name)s.draw LINE1', |
---|
388 | ]), |
---|
389 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
390 | ]), |
---|
391 | }, |
---|
392 | 'tahoe_mutable_files_published': |
---|
393 | { 'statid': 'mutable.files_published', |
---|
394 | 'category': 'counters', |
---|
395 | 'configheader': '\n'.join(['graph_title Tahoe Mutable Files Published', |
---|
396 | 'graph_vlabel files', |
---|
397 | 'graph_category tahoe_traffic', |
---|
398 | 'graph_info This graph shows the number of mutable files published', |
---|
399 | ]), |
---|
400 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
401 | '%(name)s.type DERIVE', |
---|
402 | '%(name)s.min 0', |
---|
403 | '%(name)s.draw LINE1', |
---|
404 | ]), |
---|
405 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
406 | ]), |
---|
407 | }, |
---|
408 | 'tahoe_mutable_files_retrieved': |
---|
409 | { 'statid': 'mutable.files_retrieved', |
---|
410 | 'category': 'counters', |
---|
411 | 'configheader': '\n'.join(['graph_title Tahoe Mutable Files Retrieved', |
---|
412 | 'graph_vlabel files', |
---|
413 | 'graph_category tahoe_traffic', |
---|
414 | 'graph_info This graph shows the number of files retrieved', |
---|
415 | ]), |
---|
416 | 'graph_config': '\n'.join(['%(name)s.label %(name)s', |
---|
417 | '%(name)s.type DERIVE', |
---|
418 | '%(name)s.min 0', |
---|
419 | '%(name)s.draw LINE1', |
---|
420 | ]), |
---|
421 | 'graph_render': '\n'.join(['%(name)s.value %(value)s', |
---|
422 | ]), |
---|
423 | }, |
---|
424 | |
---|
425 | } |
---|
426 | |
---|
427 | def smash_name(name): |
---|
428 | return re.sub('[^a-zA-Z0-9]', '_', name) |
---|
429 | |
---|
430 | def open_stats(fname): |
---|
431 | f = open(fname, 'rb') |
---|
432 | stats = json.load(f) |
---|
433 | f.close() |
---|
434 | return stats |
---|
435 | |
---|
436 | def main(argv): |
---|
437 | graph_name = os.path.basename(argv[0]) |
---|
438 | if graph_name.endswith('.py'): |
---|
439 | graph_name = graph_name[:-3] |
---|
440 | |
---|
441 | plugin_conf = PLUGINS.get(graph_name) |
---|
442 | |
---|
443 | for k,v in os.environ.items(): |
---|
444 | if k.startswith('statsfile'): |
---|
445 | stats_file = v |
---|
446 | break |
---|
447 | else: |
---|
448 | raise RuntimeError("No 'statsfile' env var found") |
---|
449 | |
---|
450 | stats = open_stats(stats_file) |
---|
451 | |
---|
452 | now = time.time() |
---|
453 | def output_nodes(output_section, check_time): |
---|
454 | for tubid, nodestats in stats.items(): |
---|
455 | if check_time and (now - nodestats.get('timestamp', 0)) > STAT_VALIDITY: |
---|
456 | continue |
---|
457 | name = smash_name("%s_%s" % (nodestats['nickname'], tubid[:4])) |
---|
458 | #value = nodestats['stats'][plugin_conf['category']].get(plugin_conf['statid']) |
---|
459 | category = plugin_conf['category'] |
---|
460 | statid = plugin_conf['statid'] |
---|
461 | value = nodestats['stats'][category].get(statid) |
---|
462 | if value is not None: |
---|
463 | args = { 'name': name, 'value': value } |
---|
464 | print(plugin_conf[output_section] % args) |
---|
465 | |
---|
466 | if len(argv) > 1: |
---|
467 | if sys.argv[1] == 'config': |
---|
468 | print(plugin_conf['configheader']) |
---|
469 | output_nodes('graph_config', False) |
---|
470 | sys.exit(0) |
---|
471 | |
---|
472 | output_nodes('graph_render', True) |
---|
473 | |
---|
474 | if __name__ == '__main__': |
---|
475 | main(sys.argv) |
---|