python-json-logger
python-json-logger copied to clipboard
Use ujson instead of standard library json
I've been trying to use ujson to serialize the records to string but I can't get it to work, I always get an error on line 172 in jsonlogger.py: ensure_ascii=self.json_ensure_ascii)
TypeError: an integer is required (got type NoneType)
In my logging handler I'm doing this:
self.formatter = CustomJsonFormatter( '(timestamp) (level) (name) (message)', json_serializer='ujson.dumps', )
I've tried passing json_ensure_ascii=True
as well but that doesn't seem to have any effect
The error is misleading due to the way Python renders type errors: because the TypeError was assigned to the function call it renders the last line of the function call, however the trouble is the entire
return self.json_serializer(log_record,
default=self.json_default,
cls=self.json_encoder,
indent=self.json_indent,
ensure_ascii=self.json_ensure_ascii)
call: one of the parameter is a None
where ujson.dumps requires an integer (if the parameter is passed in at all).
Given the listed parameters, I would assume "indent" is the issue: the standard library's json uses None
as default value and placeholder for "compact representation". According to is readme, ujson uses 0 instead, and it does blow up with the exact error message you list when given a None
:
>>> import json, ujson
>>> json.dumps({}, indent=None)
'{}'
>>> json.dumps({}, indent=0)
'{}'
>>> ujson.dumps({}, indent=None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type NoneType)
>>> ujson.dumps({}, indent=0)
'{}'
JsonFormatter's json_indent
defaults to None
. If you provide an explicit value of 0
instead, things should work properly.
Alternatively, you can pass a function (lambda) as your json_serializer
and call ujson.dumps
with whatever parameters you need:
Formatter(..., json_serializer=lambda obj, *args, **kwargs: usjon.dumps(obj))
though beware that you won't get the formatting & stringification jsonlogger performs by default.