When message is a json object, serializer should parse the json and output it as an object other than a json string.
Unfortunately, this is not possible, as that would break the contract that as long as a sink accept a string message it will work.
If serialize would pass a object, you could not do logger.start("file.log", serialize=True).
You should proceed of the deserialization in your custom sink.
def sink(serialized_message):
obj = json.loads(serialized_message)
Also, note that you can access the log values without even needing serialization, it is available through the .record attribute of each logged message.
def sink(message):
record = message.record # This is just a dict
print(record["time"])
def serialize_record(text, record):
exc = record["exception"]
serializable = {
"text": text,
"record": {
"elapsed": dict(repr=record["elapsed"], seconds=record["elapsed"].total_seconds()),
"exception": exc
and dict(type=exc.type.__name__, value=exc.value, traceback=bool(exc.traceback)),
"extra": record["extra"],
"file": dict(name=record["file"].name, path=record["file"].path),
"function": record["function"],
"level": dict(
icon=record["level"].icon, name=record["level"].name, no=record["level"].no
),
"line": record["line"],
"message": record["message"],
"module": record["module"],
"name": record["name"],
"process": dict(id=record["process"].id, name=record["process"].name),
"thread": dict(id=record["thread"].id, name=record["thread"].name),
"time": dict(repr=record["time"], timestamp=record["time"].timestamp()),
},
}
Maybe we can try parse record["message"] as json object here.
What's your use case exactly please?
I have trouble understanding why the proposed solutions would not work.
As record["message"] is just the string passed to logger.debug("Message"), I don't see how it could be parsed as a JSON object.
like i want to log like logger.debug("\"message\": { \"source\": \"blabla\"}"). For example, the message can be an AWS sns message field, a json doc string generated by cloudwatch.
I see, thanks. I think you should perform the deserialization in your custom sink function.
def sink(message):
record = message.record
if "deserialize" in record["extra"]:
obj = json.loads(record["message"])
# Do whatever you want with the deserialized object
And call log function using bind() like this:
logger.bind(deserialize=True).debug(aws_message)
That way, you can still log non-serialized message like logger.debug("No JSON here"), and others sinks using string can still continue to work.
Most helpful comment
I see, thanks. I think you should perform the deserialization in your custom sink function.
And call log function using
bind()like this:That way, you can still log non-serialized message like
logger.debug("No JSON here"), and others sinks using string can still continue to work.