Last active
April 10, 2020 18:09
-
-
Save mschuett/c9c76f175dd76eb3611f to your computer and use it in GitHub Desktop.
convert JSON to Key-Value
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 python3 | |
# | |
# script to convert JSON documents into plain key-value lines, | |
# formatted to be piped to zabbix_sender | |
# | |
# 20130927, martin.schuette@deck36.de | |
# 20200409, info@mschuette.name, change to Python 3 | |
# | |
import json | |
import sys | |
import types | |
import os | |
import argparse | |
import re | |
# some formatting | |
def format_string(s): | |
if s is None: | |
return "0" | |
elif isinstance(s, str) and " " in s: | |
return '"%s"' % ("\\n".join(s.splitlines()),) | |
elif isinstance(s, str) and s == "": | |
return '""' | |
elif isinstance(s, bool) and s: | |
return 1 | |
elif isinstance(s, bool) and not s: | |
return 0 | |
else: | |
return s | |
# recursively flatten the document keys: | |
def flatten_level(doc): | |
# start with some aux. functions: | |
def is_leaf(doc): | |
return not (isinstance(doc, list) or isinstance(doc, dict)) | |
def flatten_list(l): | |
outlist = [] | |
for (num, sub) in enumerate(l): | |
if is_leaf(sub): | |
line = "%s %s" % (num, format_string(sub)) | |
outlist.append(line) | |
else: | |
for subitem in flatten_level(sub): | |
line = "%s.%s" % (num, subitem) | |
outlist.append(line) | |
return outlist | |
def flatten_dict(d): | |
outlist = [] | |
for (key, sub) in list(d.items()): | |
if is_leaf(sub): | |
line = "%s %s" % (key, format_string(sub)) | |
outlist.append(line) | |
else: | |
for subitem in flatten_level(sub): | |
line = "%s.%s" % (key, subitem) | |
outlist.append(line) | |
return outlist | |
if is_leaf(doc): | |
return format_string(doc) | |
elif isinstance(doc, list): | |
return flatten_list(doc) | |
elif isinstance(doc, dict): | |
return flatten_dict(doc) | |
# parse command line arguments: | |
parser = argparse.ArgumentParser( | |
description="flatten a JSON document into key-value lines, suitable for Zabbix" | |
) | |
parser.add_argument("-p", "--prefix", help="prefix for zabbix keys") | |
parser.add_argument( | |
"-a", "--attribute", help="attribute for zabbix keys (e.g. key[attribute])" | |
) | |
parser.add_argument( | |
"-d", | |
"--dash", | |
help="prepend every line with a dash, useful to pipe data into zabbix_sender", | |
action="store_true", | |
) | |
parser.add_argument("-f", "--filter", help="field name(s) to filter", action="append") | |
parser.add_argument( | |
"-i", "--infile", help="input file", type=argparse.FileType("r"), default=sys.stdin | |
) | |
args = parser.parse_args() | |
# read JSON: | |
try: | |
doc = json.load(args.infile) | |
except ValueError: | |
# silently fail if input is no valid JSON | |
sys.exit(1) | |
# do work: | |
l = flatten_level(doc) | |
# filter output: | |
if args.filter: | |
for f in args.filter: | |
l = [x for x in l if not re.search(r"\b" + f, x)] | |
if args.prefix: | |
l = [".".join([args.prefix, x]) for x in l] | |
if args.attribute: | |
l = [x.replace(" ", "[%s] " % (args.attribute,), 1) for x in l] | |
if args.dash: | |
l = ["- " + x for x in l] | |
print((os.linesep.join(l))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment