master
py 99 lines 3.03 KB
Raw
1 # -*- coding: utf-8 -*-
2 # Description: pandas netdata python.d module
3 # Author: Andrew Maguire (andrewm4894)
4 # SPDX-License-Identifier: GPL-3.0-or-later
5
6 import os
7 import pandas as pd
8
9 try:
10 import requests
11 HAS_REQUESTS = True
12 except ImportError:
13 HAS_REQUESTS = False
14
15 try:
16 from sqlalchemy import create_engine
17 HAS_SQLALCHEMY = True
18 except ImportError:
19 HAS_SQLALCHEMY = False
20
21 from bases.FrameworkServices.SimpleService import SimpleService
22
23 ORDER = []
24
25 CHARTS = {}
26
27
28 class Service(SimpleService):
29 def __init__(self, configuration=None, name=None):
30 SimpleService.__init__(self, configuration=configuration, name=name)
31 self.order = ORDER
32 self.definitions = CHARTS
33 self.chart_configs = self.configuration.get('chart_configs', None)
34 self.line_sep = self.configuration.get('line_sep', ';')
35
36 def run_code(self, df_steps):
37 """eval() each line of code and ensure the result is a pandas dataframe"""
38
39 # process each line of code
40 lines = df_steps.split(self.line_sep)
41 for line in lines:
42 line_clean = line.strip('\n').strip(' ')
43 if line_clean != '' and line_clean[0] != '#':
44 df = eval(line_clean)
45 assert isinstance(df, pd.DataFrame), 'The result of each evaluated line of `df_steps` must be of type `pd.DataFrame`'
46
47 # take top row of final df as data to be collected by netdata
48 data = df.to_dict(orient='records')[0]
49
50 return data
51
52 def check(self):
53 """ensure charts and dims all configured and that we can get data"""
54
55 if not HAS_REQUESTS:
56 self.warning('requests library could not be imported')
57
58 if not HAS_SQLALCHEMY:
59 self.warning('sqlalchemy library could not be imported')
60
61 if not self.chart_configs:
62 self.error('chart_configs must be defined')
63
64 data = dict()
65
66 # add each chart as defined by the config
67 for chart_config in self.chart_configs:
68 if chart_config['name'] not in self.charts:
69 chart_template = {
70 'options': [
71 chart_config['name'],
72 chart_config['title'],
73 chart_config['units'],
74 chart_config['family'],
75 chart_config['context'],
76 chart_config['type']
77 ],
78 'lines': []
79 }
80 self.charts.add_chart([chart_config['name']] + chart_template['options'])
81
82 data_tmp = self.run_code(chart_config['df_steps'])
83 data.update(data_tmp)
84
85 for dim in data_tmp:
86 self.charts[chart_config['name']].add_dimension([dim, dim, 'absolute', 1, 1])
87
88 return True
89
90 def get_data(self):
91 """get data for each chart config"""
92
93 data = dict()
94
95 for chart_config in self.chart_configs:
96 data_tmp = self.run_code(chart_config['df_steps'])
97 data.update(data_tmp)
98
99 return data