@@ -69,7 +69,6 @@ def fetch_info(conf):
69
69
70
70
log_verbose ('Sending info command' )
71
71
s .sendall ('info\r \n ' )
72
-
73
72
status_line = fp .readline ()
74
73
75
74
if status_line .startswith ('-' ):
@@ -82,10 +81,46 @@ def fetch_info(conf):
82
81
content_length = int (status_line [1 :- 1 ])
83
82
data = fp .read (content_length )
84
83
log_verbose ('Received data: %s' % data )
85
- s .close ()
86
84
87
85
linesep = '\r \n ' if '\r \n ' in data else '\n '
88
- return parse_info (data .split (linesep ))
86
+ info_dict = parse_info (data .split (linesep ))
87
+ fp .close ()
88
+
89
+ # monitoring lengths of custom keys
90
+ key_dict = get_llen_keys (s , conf )
91
+ info_dict .update (key_dict )
92
+
93
+ s .close ()
94
+
95
+ return info_dict
96
+
97
+
98
+ def get_llen_keys (socket , conf ):
99
+ """
100
+ for each llen_key specified in the config file,
101
+ grab the length of that key from the corresponding
102
+ database index. return a dictionary of the
103
+ keys
104
+ """
105
+ llen_fp = socket .makefile ('r' )
106
+ key_dict = {}
107
+ if len (conf ['llen_keys' ]) > 0 :
108
+ for db , keys in conf ['llen_keys' ].items ():
109
+ socket .sendall ('select %d\r \n ' % db )
110
+ status_line = llen_fp .readline () # +OK
111
+ for key in keys :
112
+ socket .sendall ('llen %s\r \n ' % key )
113
+ status_line = llen_fp .readline () # :VALUE
114
+ try :
115
+ val = int (filter (str .isdigit , status_line ))
116
+ except ValueError :
117
+ collectd .warning ('redis_info plugin: key %s is not of type list, cannot get length' % key )
118
+
119
+ subkey = "db{0}_llen_{1}" .format (db , key )
120
+ key_dict .update ({subkey : val })
121
+
122
+ llen_fp .close ()
123
+ return key_dict
89
124
90
125
91
126
def parse_info (info_lines ):
@@ -130,6 +165,7 @@ def configure_callback(conf):
130
165
port = None
131
166
auth = None
132
167
instance = None
168
+ llen_keys = {}
133
169
134
170
for node in conf .children :
135
171
key = node .key .lower ()
@@ -148,10 +184,17 @@ def configure_callback(conf):
148
184
VERBOSE_LOGGING = bool (node .values [0 ]) or VERBOSE_LOGGING
149
185
elif key == 'instance' :
150
186
instance = val
187
+ elif key == 'llen_key' :
188
+ if (len (node .values )) == 2 :
189
+ llen_keys .setdefault (node .values [0 ], []).append (node .values [1 ])
190
+ else :
191
+ collectd .warning ("redis_info plugin: monitoring length of keys requires both \
192
+ database index and key value" )
193
+
151
194
elif searchObj :
195
+ global REDIS_INFO
152
196
log_verbose ('Matching expression found: key: %s - value: %s' %
153
197
(searchObj .group (1 ), val ))
154
- global REDIS_INFO
155
198
REDIS_INFO [searchObj .group (1 ), val ] = True
156
199
else :
157
200
collectd .warning ('redis_info plugin: Unknown config key: %s.' %
@@ -165,7 +208,8 @@ def configure_callback(conf):
165
208
CONFIGS .append ({'host' : host ,
166
209
'port' : port ,
167
210
'auth' : auth ,
168
- 'instance' : instance })
211
+ 'instance' : instance ,
212
+ 'llen_keys' : llen_keys })
169
213
170
214
171
215
def dispatch_value (info , key , type , plugin_instance = None , type_instance = None ):
@@ -202,10 +246,26 @@ def dispatch_value(info, key, type, plugin_instance=None, type_instance=None):
202
246
# write_http plugin. See
203
247
# https://github.com/collectd/collectd/issues/716
204
248
val .meta = {'0' : True }
205
-
206
249
val .dispatch ()
207
250
208
251
252
+ def _format_dimensions (dimensions ):
253
+ """
254
+ Formats a dictionary of dimensions to a format that enables them to be
255
+ specified as key, value pairs in plugin_instance to signalfx. E.g.
256
+ >>> dimensions = {'a': 'foo', 'b': 'bar'}
257
+ >>> _format_dimensions(dimensions)
258
+ "[a=foo,b=bar]"
259
+ Args:
260
+ dimensions (dict): Mapping of {dimension_name: value, ...}
261
+ Returns:
262
+ str: Comma-separated list of dimensions
263
+ """
264
+
265
+ dim_pairs = ["%s=%s" % (k , v ) for k , v in dimensions .iteritems ()]
266
+ return "[%s]" % ("," .join (dim_pairs ))
267
+
268
+
209
269
def read_callback ():
210
270
for conf in CONFIGS :
211
271
get_metrics (conf )
@@ -241,6 +301,14 @@ def get_metrics(conf):
241
301
else :
242
302
dispatch_value (info , key , val , plugin_instance )
243
303
304
+ for db , keys in conf ['llen_keys' ].items ():
305
+ for key in keys :
306
+ subkey = "db{0}_llen_{1}" .format (db , key )
307
+ val = info .get (subkey )
308
+ dimensions = _format_dimensions ({'key_name' : key , 'db_index' : db })
309
+ plugin_dimensions = "{0}{1}" .format (plugin_instance , dimensions )
310
+ dispatch_value (info , subkey , 'gauge' , plugin_dimensions , 'key_llen' )
311
+
244
312
245
313
def log_verbose (msg ):
246
314
if not VERBOSE_LOGGING :
0 commit comments