Skip to content

Instantly share code, notes, and snippets.

@pfigue
Created August 14, 2014 16:17
Show Gist options
  • Save pfigue/e9b29f151c520322f3f2 to your computer and use it in GitHub Desktop.
Save pfigue/e9b29f151c520322f3f2 to your computer and use it in GitHub Desktop.
Python script to parse the output Redis INFO command and convert it into a JSON dictionary.
#!/usr/bin env python
#coding: utf-8
import re
from json import dumps
from sys import (stdin, exit)
DEBUG_LEVEL = 0x0
PARSER = 0x01
POSTPROCESSER = 0x02
PARSER_COMMAS = 0x04
ALL_DICT = 0x08
def debug(level, message):
if not (level & DEBUG_LEVEL):
return
if level & ALL_DICT:
from pprint import pprint
pprint(message)
else:
prefix = '> ' if level & PARSER else \
'% ' if level & POSTPROCESSER else \
'$ ' if level & PARSER_COMMAS else ''
print '%s%s' % (prefix, message)
EMPTY_LINE = re.compile(r'^\s*$')
#In [25]: k = re.match(r'^# (\w+(\s+\w+)*).*$', '# Melon'); k.group(1)
#Out[25]: 'Melon'
#
#In [26]: k = re.match(r'^# (\w+(\s+\w+)*).*$', '# Melon Andador'); k.group(1)
#Out[26]: 'Melon Andador'
#
#In [27]: k = re.match(r'^# (\w+(\s+\w+)*).*$', '# Melon Andador '); k.group(1)
#Out[27]: 'Melon Andador'
SECTION_LINE = re.compile(r'^# (\w+)\W*$')
#In [29]: k = re.match(r'^(.*):(.*)$', 'cute_key:120.0'); k.group(2)
#Out[29]: '120.0'
#
#In [30]: k = re.match(r'^(.*):(.*)$', 'cute_key:120.0.6'); k.group(2)
#Out[30]: '120.0.6'
KEY_VALUE_LINE = re.compile(r'^(\w+)[=:](\S+)$')
def parse_comma_separated_key_values(string):
'''Convert something like 'ip=172.31.2.6,port=7011,state=online,offset=490698,lag=1' into something like {"ip": "172.31.2.6", "state": "online", "lag": "1", "port": "7011", "offset": "490698"}
'''
new_dict = {}
for pair in string.split(','):
result = KEY_VALUE_LINE.match(pair)
key, value = result.group(1), result.group(2)
new_dict.update({key: value})
return new_dict
#print parse_comma_separated_key_values('ip=172.31.2.6,port=7011,state=online,offset=490698,lag=1')
#exit(0)
def postprocess(main_dict, regexp, keys_list):
this_dict = main_dict
# Climb the dict's tree till the right level
for key in keys_list:
try:
this_dict = this_dict[key]
debug(POSTPROCESSER, 'kd: %s' % this_dict)
except KeyError:
debug(POSTPROCESSER, 'the key "%s" was not found in the dict "%s"' % (key, this_dict))
return #fail silently
# Find the keys which match the regexp
for key in this_dict.keys():
if re.match(regexp, key):
value = this_dict[key]
debug(POSTPROCESSER, 'key:"%s", value:"%s"' % (key, value))
this_dict[key] = parse_comma_separated_key_values(value)
# Read all the Redis INFO data from stdin
# convert it into a dictionary
main_dict = {}
this_dict = main_dict
for line in stdin:
line = line.rstrip('\n').rstrip('\r') # remove endliners
debug(PARSER, 'line: \'%s\'' % line)
# empty lines
if EMPTY_LINE.match(line):
debug(PARSER, '> empty line')
continue
# NewSection lines
result = SECTION_LINE.match(line)
if result:
section_name = result.group(1).lower()
this_dict = {}
main_dict[section_name] = this_dict
debug(PARSER, '> new section: %s' % section_name)
# key:value lines
result = KEY_VALUE_LINE.match(line)
if result:
key = result.group(1)
value = result.group(2)
this_dict.update({key: value})
debug(PARSER, '> key_value: \'%s\' and \'%s\'' % (key, value))
# Do some postprocessing for very specific fields
postprocess(main_dict, r'^db\d+$', ['keyspace'])
postprocess(main_dict, r'^slave\d+$', ['replication'])
debug(ALL_DICT, main_dict)
print dumps(main_dict)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment