@cryptotaxi247 / netdata-1 / commits / b3a8b3e0b

alpha python.d.plugin

paulfantom committed Jun 18, 2016 at 11:53 UTC b3a8b3e0be104f832129a8486256cdc98167b878
3 files changed +87 -74
plugins.d/python.d.plugin
+79 -67
@@ -3,15 +3,24 @@
3 import os
4 import sys
5 import time
6 -import json
6 try:
7 assert sys.version_info >= (3,1)
8 import importlib.machinery
9 except AssertionError:
11 - sys.stderr.write('Not supported python version. Needed python >= 3.1\n')
10 + sys.stderr.write('python.d.plugin: Not supported python version. Needed python >= 3.1\n')
11 + sys.stdout.write('DISABLE\n')
12 + sys.exit(1)
13 +try:
14 + import yaml
15 +except ImportError:
16 + sys.stderr.write('python.d.plugin: Cannot find yaml library\n')
17 sys.stdout.write('DISABLE\n')
18 sys.exit(1)
19
20 +BASE_CONFIG = {'update_every' : 10,
21 + 'priority': 12345,
22 + 'retries' : 0}
23 +
24
25 class PythonCharts(object):
26
@@ -29,13 +38,13 @@ class PythonCharts(object):
38 modules = self._load_modules(modules_path,modules)
39
40 # check if loaded modules are on disabled modules list
32 - self.modules = [ m for m in modules if m.__name__ not in modules_disabled ]
41 + loaded_modules = [ m for m in modules if m.__name__ not in modules_disabled ]
42
43 # load configuration files
35 - self._load_configs()
44 + confiured_modules = self._load_configs(loaded_modules)
45
46 # good economy and prosperity:
38 - self.jobs = self._create_jobs(self.modules)
47 + self.jobs = self._create_jobs(configured_modules)
48
49
50 def _create_jobs(self,modules):
@@ -46,50 +55,25 @@ class PythonCharts(object):
55 # iterate over list of modules and inside one loop iterate over configs
56 jobs = []
57 for module in modules:
49 - if type(module.config) is dict:
50 - jobs.append(self._job(module,module.config))
51 - elif type(module.config) is list:
52 - for conf in module.config:
53 - jobs.append(self._job(module,conf))
58 + for name in module.config:
59 + # register a new job
60 + conf = module.config[name]
61 + try:
62 + job = module.Service(configuration=conf, name=name)
63 + except Exception as e:
64 + debug(module.__name__ +
65 + ": Couldn't start job named " +
66 + str(name) +
67 + ": " +
68 + str(e))
69 + return None
70 + else:
71 + # set execution_name (needed to plot run time graphs)
72 + job.execution_name = module.__name__ + "_" + name
73 + jobs.append(job)
74
75 return [j for j in jobs if j is not None]
76
57 -
58 - def _job(self,module,conf):
59 - # register a new job
60 - # default job settings:
61 - settings = {'update_every' : 11,
62 - 'priority' : 12345,
63 - 'retries' : 0}
64 - # ensure job has basic variables
65 - # first check in job config
66 - # next check in module
67 - # at last assign defaults
68 - for key in settings:
69 - try:
70 - settings[key] = int(conf[key])
71 - except (KeyError,ValueError):
72 - try:
73 - settings[key] = int(getattr(module, key))
74 - except (AttributeError,ValueError):
75 - pass
76 -
77 - try:
78 - job = module.Service(configuration=conf)
79 - except Exception as e:
80 - sys.stderr.write(module.__name__ +
81 - ": Couldn't start one of jobs " +
82 - str(e))
83 - return None
84 - else:
85 - # set execution_name (needed to plot run time graphs)
86 - try:
87 - job.execution_name = module.__name__ + \
88 - "_" + \
89 - str(conf['name'])
90 - except KeyError:
91 - job.execution_name = module.__name__
92 -
77 def _import_module(self, path, name=None):
78 # try to import module using only its path
79 if name is None:
@@ -127,22 +111,51 @@ class PythonCharts(object):
111 loaded.append(m)
112 return loaded
113
130 - def _load_configs(self):
131 - # function modifies every loaded module in self.modules
132 - for m in self.modules:
133 - configfile = self.configs + m.__name__ + ".conf"
114 + def _load_configs(self,modules):
115 + # function loads configuration files to modules
116 + for mod in modules:
117 + configfile = self.configs + mod.__name__ + ".conf"
118 if os.path.isfile(configfile):
119 debug("loading chart options: '" + configfile + "'")
136 - for k, v in read_config(configfile).items():
137 - try:
138 - setattr(m, k, v)
139 - except AttributeError:
140 - self._disable_module(m,"misbehaving having bad configuration")
120 + try:
121 + setattr(mod,
122 + 'config',
123 + self._parse_config(mod,read_config(config_file))
124 + except Exception as e:
125 + debug("something went wrong while loading configuration",e)
126 else:
142 - debug(m.__name__ +
127 + debug(mod.__name__ +
128 ": configuration file '" +
129 configfile +
130 "' not found. Using defaults.")
131 + return modules
132 +
133 + def _parse_config(self,module,config):
134 + # get default values
135 + defaults = {}
136 + for key in BASE_CONFIG:
137 + try:
138 + # get defaults from module config
139 + defaults[key] = int(config.pop(key))
140 + except (KeyError,ValueError):
141 + try:
142 + # get defaults from module source code
143 + defaults[key] = getattr(module, key)
144 + except (KeyError,ValueError):
145 + # if above failed, get defaults from global dict
146 + defaults[key] = BASE_CONFIG[key]
147 +
148 + # assign variables needed by supervisor to every job configuration
149 + out = {}
150 + for name in config:
151 + out[name] = {}
152 + for key in BASE_CONFIG:
153 + if key not in config[name]:
154 + out[name][key] = defaults[key]
155 + except (KeyError,ValueError):
156 +
157 + # return dictionary of jobs where every job has BASE_CONFIG variables
158 + return out
159
160 def _stop(self, job, reason=None): #FIXME test if Service has __name__
161 # modifies self.jobs
@@ -257,17 +270,16 @@ class PythonCharts(object):
270
271
272 def read_config(path):
260 - # FIXME move to JSON configurations
261 -# try:
262 -# with open(path, 'r') as f:
263 -# config_str = '[config]\n' + f.read()
264 -# except IsADirectoryError:
265 -# debug(str(path), "is a directory")
266 -# return
267 -# try:
268 -# debug("Malformed configuration file: "+str(e))
269 -# return
270 - return None
273 + try:
274 + with open(path, 'r') as stream:
275 + config = yaml.load(stream)
276 + except IsADirectoryError:
277 + debug(str(path), "is a directory")
278 + return None
279 + except yaml.YAMLError as e:
280 + debug(str(path), "is malformed:", e)
281 + return None
282 + return config
283
284
285 def debug(*args):
python.d/mysql.chart.py
+7 -6
@@ -334,16 +334,17 @@ CHARTS = {
334
335
336 class Service(BaseService):
337 - def __init__(self,configuration=None):
337 + def __init__(self,configuration=None,name=None):
338 super().__init__(configuration)
339 self.configuration = self._parse_config(configuration)
340 self.connection = None
341 self.defs = {}
342 + self.name = name
343
344 def _parse_config(self,configuration):
345 # parse configuration to collect data from mysql server
345 - if 'name' not in configuration:
346 - configuration['name'] = 'local'
346 + if self.name is None:
347 + self.name = 'local'
348 if 'user' not in configuration:
349 configuration['user'] = 'root'
350 if 'password' not in configuration:
@@ -413,7 +414,7 @@ class Service(BaseService):
414 data = self._get_data()
415 for name in ORDER:
416 header = "CHART mysql_" + \
416 - str(self.configuration['name']) + "." + \
417 + str(self.name) + "." + \
418 name + " " + \
419 CHARTS[name][0] + " " + \
420 str(self.priority + idx) + " " + \
@@ -441,7 +442,7 @@ class Service(BaseService):
442 except Exception:
443 pass
444 for chart, dimensions in self.defs.items():
444 - header = "BEGIN mysql_" + str(self.configuration['name']) + "." + chart + " " + str(interval) + '\n'
445 + header = "BEGIN mysql_" + str(self.name) + "." + chart + " " + str(interval) + '\n'
446 lines = ""
447 for d in dimensions:
448 try:
@@ -455,7 +456,7 @@ class Service(BaseService):
456
457 #FIXME debug only:
458 if __name__ == "__main__":
458 - my = Service(config[0])
459 + my = Service(config[0],'loc')
460 my.check()
461 my.create()
462 my.update(1)
python.d/python_modules/base.py
+1 -1
@@ -5,7 +5,7 @@ from time import time
5
6
7 class BaseService(object):
8 - def __init__(self,configuration=None):
8 + def __init__(self,name=None,configuration=None):
9 if configuration is None:
10 # use defaults
11 self.error("BaseService: no configuration parameters supplied. Cannot create Service.")