Created
August 14, 2014 16:17
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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