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.")