Description
JSON string parsing error
Problem
When creating a custom logger and providing the new logger with a custom formatter function, Loguru throws a KeyError
if the string it's trying to format contains a JSON formatted string.
Environment
Python 3.13.2
loguru==0.7.3
How to reproduce
#! /usr/bin/env python3
import sys
from loguru import logger
def console_format(record: dict) -> str:
level = record["level"].name.lower()
timestamp = record["time"].strftime("%Y-%m-%d %H:%M:%S.%f %:z")
message = record["message"]
log_message = f"[{timestamp}] [{level}] {message}\n"
return log_message
if __name__ == "__main__":
logger.remove()
logger.add(sys.stderr,
format=console_format,
level="DEBUG",
colorize=False,
catch=False)
logger.info("This is an info message")
# 1. Try with variable substituations
name = "Alice"
age = 30
logger.info(f"Hello {name}, you are {age} years old")
# 2. Try with json string as variable
json_str = '{"name": "Bob", "age": 25}'
logger.info(f"Hello {json_str} world!")
# 3. Try with dumped json object
json_obj = {"name": "Bob", "age": 25}
logger.info(f"Hello {json.dumps(json_obj)} world!")
Error Trace
[2025-03-17 07:19:46.976159 -07:00] [info] This is an info message
[2025-03-17 07:19:46.976263 -07:00] [info] Hello Alice, you are 30 years old
Traceback (most recent call last):
File "./test.py", line 39, in
logger.info(f"Hello {json_str} world!")
File ".venv/lib/python3.13/site-packages/loguru/_logger.py", line 2078, in info
__self._log("INFO", False, __self._options, __message, args, kwargs)
File ".venv/lib/python3.13/site-packages/loguru/_logger.py", line 2066, in _log
handler.emit(log_record, level_id, from_decorator, raw, colored_message)
File ".venv/lib/python3.13/site-packages/loguru/_handler.py", line 161, in emit
formatted = precomputed_format.format_map(formatter_record)
KeyError: '"name"'
Workaround
The only workaround I found to make this work is by changing the following:
# message = record["message"]
message = record["message"].replace("{", "{{").replace("}", "}}")
Output after the workaround
[2025-03-17 08:10:04.773069 -07:00] [info] This is an info message
[2025-03-17 08:10:04.773193 -07:00] [info] Hello Alice, you are 30 years old
[2025-03-17 08:10:04.773231 -07:00] [info] Hello {"name": "Bob", "age": 25} world!
[2025-03-17 08:10:04.773267 -07:00] [info] Hello {"name": "John", "age": 99} world!
Observation
- This behaviour/limitation is not documented anywhere (AFAIK).
- The workaround is messy
Maybe it could be a good idea to:
- Document this limitation
- Update loguru for a more intuitive use where one can simply log a message with an f-string without worrying of what's happening under the hood of the logger. (ideally keeping
message = record["message"]
even if there is a json string in there