Skip to content

Commit 3f4dd02

Browse files
authored
Merge pull request #5 from signalfx/redis-update
add support for reporting length of keys
2 parents 1e7f115 + 32bdfd3 commit 3f4dd02

File tree

1 file changed

+74
-6
lines changed

1 file changed

+74
-6
lines changed

redis_info.py

+74-6
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ def fetch_info(conf):
6969

7070
log_verbose('Sending info command')
7171
s.sendall('info\r\n')
72-
7372
status_line = fp.readline()
7473

7574
if status_line.startswith('-'):
@@ -82,10 +81,46 @@ def fetch_info(conf):
8281
content_length = int(status_line[1:-1])
8382
data = fp.read(content_length)
8483
log_verbose('Received data: %s' % data)
85-
s.close()
8684

8785
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
89124

90125

91126
def parse_info(info_lines):
@@ -130,6 +165,7 @@ def configure_callback(conf):
130165
port = None
131166
auth = None
132167
instance = None
168+
llen_keys = {}
133169

134170
for node in conf.children:
135171
key = node.key.lower()
@@ -148,10 +184,17 @@ def configure_callback(conf):
148184
VERBOSE_LOGGING = bool(node.values[0]) or VERBOSE_LOGGING
149185
elif key == 'instance':
150186
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+
151194
elif searchObj:
195+
global REDIS_INFO
152196
log_verbose('Matching expression found: key: %s - value: %s' %
153197
(searchObj.group(1), val))
154-
global REDIS_INFO
155198
REDIS_INFO[searchObj.group(1), val] = True
156199
else:
157200
collectd.warning('redis_info plugin: Unknown config key: %s.' %
@@ -165,7 +208,8 @@ def configure_callback(conf):
165208
CONFIGS.append({'host': host,
166209
'port': port,
167210
'auth': auth,
168-
'instance': instance})
211+
'instance': instance,
212+
'llen_keys': llen_keys})
169213

170214

171215
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):
202246
# write_http plugin. See
203247
# https://github.com/collectd/collectd/issues/716
204248
val.meta = {'0': True}
205-
206249
val.dispatch()
207250

208251

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+
209269
def read_callback():
210270
for conf in CONFIGS:
211271
get_metrics(conf)
@@ -241,6 +301,14 @@ def get_metrics(conf):
241301
else:
242302
dispatch_value(info, key, val, plugin_instance)
243303

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+
244312

245313
def log_verbose(msg):
246314
if not VERBOSE_LOGGING:

0 commit comments

Comments
 (0)