Add custom logfmt parser based off python-logfmt

This specifically doesn't add quotes where they're not necessary
This commit is contained in:
Jake Howard 2018-12-21 15:37:42 +00:00
parent 9362be50b9
commit af45867376
Signed by: jake
GPG key ID: 57AFB45680EDD477
2 changed files with 89 additions and 0 deletions

31
catfish/utils/logfmt.py Normal file
View file

@ -0,0 +1,31 @@
# Adapted from https://github.com/jkakar/logfmt-python/blob/master/logfmt/formatter.py
from typing import Any, Dict
CHARS_TO_ESCAPE = [" ", "=", "\\", '"', "'"]
def bool_to_str(i: bool) -> str:
return str(i).lower()
def escape_value(value: str):
value = value.replace('"', '\\"')
if any([char in value for char in CHARS_TO_ESCAPE]):
value = '"{}"'.format(value)
return value
def logfmt(data: Dict[str, Any]):
out = []
for k, v in data.items():
if not k.isidentifier():
continue
if v is None:
v = ""
elif isinstance(v, bool):
v = bool_to_str(v)
elif isinstance(v, str):
v = escape_value(v)
out.append("{}={}".format(k, v))
return " ".join(out)

View file

@ -0,0 +1,58 @@
from catfish.utils.logfmt import logfmt
from tests import BaseTestCase
class LogFmtTestCase(BaseTestCase):
def test_simple_logfmt(self):
self.assertEqual(
logfmt({"key1": "value1", "key2": "value2"}), "key1=value1 key2=value2"
)
def test_quotes_space(self):
self.assertEqual(
logfmt({"key1": "value1 valuea", "key2": "value2 valueb"}),
'key1="value1 valuea" key2="value2 valueb"',
)
def test_quotes_equals(self):
self.assertEqual(
logfmt({"key1": "value1=valuea", "key2": "value2=valueb"}),
'key1="value1=valuea" key2="value2=valueb"',
)
def test_quotes_quotes(self):
self.assertEqual(
logfmt({"key1": '"value1"', "key2": '"value2"'}),
'key1="\\"value1\\"" key2="\\"value2\\""',
)
self.assertEqual(
logfmt({"key1": "'value1'", "key2": "'value2'"}),
"key1=\"'value1'\" key2=\"'value2'\"",
)
def test_empty(self):
self.assertEqual(logfmt({}), "")
def test_boolean_values(self):
self.assertEqual(logfmt({"key1": True, "key2": False}), "key1=true key2=false")
def test_none_values(self):
self.assertEqual(logfmt({"key1": None, "key2": None}), "key1= key2=")
def test_numbers(self):
self.assertEqual(
logfmt({"key1": 12345, "key2": -12345}), "key1=12345 key2=-12345"
)
self.assertEqual(
logfmt({"key1": "12345", "key2": "-12345"}), "key1=12345 key2=-12345"
)
def test_float(self):
self.assertEqual(
logfmt({"key1": 12345.67, "key2": -12345.67}),
"key1=12345.67 key2=-12345.67",
)
self.assertEqual(
logfmt({"key1": "12345.67", "key2": "-12345.67"}),
"key1=12345.67 key2=-12345.67",
)