@cryptotaxi247 / netdata-1 / commits / 236d3a165

beanstalk module initial version

lgz committed Nov 3, 2017 at 00:23 UTC 236d3a1651bb88c9e932433fcd1b42561eb7cb53
1 file changed +162
python.d/beanstalk.chart.py new
+162
@@ -0,0 +1,162 @@
1 +# -*- coding: utf-8 -*-
2 +# Description: beanstalk netdata python.d module
3 +# Author: l2isbad
4 +
5 +from collections import defaultdict
6 +from sys import version_info
7 +
8 +try:
9 + import beanstalkc
10 + BEANSTALKC = True
11 +except ImportError:
12 + BEANSTALKC = False
13 +
14 +
15 +if version_info[:2] > (3, 1):
16 + import pyyaml3 as yaml
17 +else:
18 + import pyyaml2 as yaml
19 +
20 +
21 +from bases.FrameworkServices.SimpleService import SimpleService
22 +
23 +# default module values (can be overridden per job in `config`)
24 +# update_every = 2
25 +priority = 60000
26 +retries = 60
27 +
28 +
29 +def chart_template(name):
30 + order = ['{0}_jobs_rate'.format(name),
31 + '{0}_jobs'.format(name),
32 + '{0}_connections'.format(name),
33 + '{0}_commands'.format(name),
34 + '{0}_pause'.format(name)
35 + ]
36 + family = 'tube {0}'.format(name)
37 +
38 + charts = {
39 + order[0]: {
40 + 'options': [None, 'Job Rate', 'jobs/s', family, 'beanstalk.jobs_rate', 'area'],
41 + 'lines': [
42 + ['_'.join([name, 'total-jobs']), 'jobs', 'incremental']
43 + ]},
44 + order[1]: {
45 + 'options': [None, 'Jobs', 'jobs', family, 'beanstalk.jobs', 'stacked'],
46 + 'lines': [
47 + ['_'.join([name, 'current-jobs-urgent']), 'urgent'],
48 + ['_'.join([name, 'current-jobs-ready']), 'ready'],
49 + ['_'.join([name, 'current-jobs-reserved']), 'reserved'],
50 + ['_'.join([name, 'current-jobs-delayed']), 'delayed'],
51 + ['_'.join([name, 'current-jobs-buried']), 'buried']
52 + ]},
53 + order[2]: {
54 + 'options': [None, 'Connections', 'connections', family, 'beanstalk.connections', 'stacked'],
55 + 'lines': [
56 + ['_'.join([name, 'current-using']), 'using'],
57 + ['_'.join([name, 'current-waiting']), 'waiting'],
58 + ['_'.join([name, 'current-watching']), 'watching']
59 + ]},
60 + order[3]: {
61 + 'options': [None, 'Commands', 'command/s', family, 'beanstalk.commands', 'stacked'],
62 + 'lines': [
63 + ['_'.join([name, 'cmd-delete']), 'deletes', 'incremental'],
64 + ['_'.join([name, 'cmd-pause-tube']), 'pauses', 'incremental']
65 + ]},
66 + order[4]: {
67 + 'options': [None, 'Pause', 'seconds', family, 'beanstalk.pause', 'stacked'],
68 + 'lines': [
69 + ['_'.join([name, 'pause']), 'since'],
70 + ['_'.join([name, 'pause-time-left']), 'left']
71 + ]}
72 +
73 + }
74 +
75 + return order, charts
76 +
77 +
78 +class Service(SimpleService):
79 + def __init__(self, configuration=None, name=None):
80 + SimpleService.__init__(self, configuration=configuration, name=name)
81 + self.configuration = configuration
82 + self.conn = self.connect()
83 + self.order = list()
84 + self.definitions = dict()
85 + self.alive = True
86 +
87 + def check(self):
88 + if not BEANSTALKC:
89 + self.error("'beanstalkc' module is needed to use beanstalk.chart.py")
90 + return False
91 +
92 + if not self.conn:
93 + return False
94 +
95 + for tube in self.conn.tubes():
96 + order, charts = chart_template(tube)
97 + self.order.extend(order)
98 + self.definitions.update(charts)
99 +
100 + return bool(self.order)
101 +
102 + def get_data(self):
103 + """
104 + Format data received from shell command
105 + :return: dict
106 + """
107 + if not self.is_alive():
108 + return None
109 + else:
110 + self.alive = True
111 +
112 + tubes_stats, data = defaultdict(dict), dict()
113 + try:
114 + for tube in self.conn.tubes():
115 + stats = self.conn.stats_tube(tube)
116 + for stat in stats:
117 + dimension, value = '_'.join([tube, stat]), stats[stat]
118 + tubes_stats[tube][dimension] = value
119 + except beanstalkc.SocketError:
120 + self.alive = False
121 + return None
122 +
123 + for tube in tubes_stats:
124 + if tube + '_jobs' not in self.charts.active_charts():
125 + self.create_new_tube_charts(tube)
126 +
127 + data.update(tubes_stats[tube])
128 +
129 + return data or None
130 +
131 + def create_new_tube_charts(self, tube):
132 + order, charts = chart_template(tube)
133 +
134 + for chart_name in order:
135 + params = [chart_name] + charts[chart_name]['options']
136 + dimensions = charts[chart_name]['lines']
137 +
138 + new_chart = self.charts.add_chart(params)
139 + for dimension in dimensions:
140 + new_chart.add_dimension(dimension)
141 +
142 + def connect(self):
143 + host = self.configuration.get('host', '127.0.0.1')
144 + port = self.configuration.get('port', 11300)
145 + try:
146 + return beanstalkc.Connection(host=host,
147 + port=port)
148 + except beanstalkc.SocketError as error:
149 + self.error('Connection to {0}:{1} failed: {2}'.format(host, port, error))
150 + return None
151 +
152 + def reconnect(self):
153 + try:
154 + self.conn.reconnect()
155 + return True
156 + except beanstalkc.SocketError:
157 + return False
158 +
159 + def is_alive(self):
160 + if not self.alive:
161 + return self.reconnect()
162 + return True