If the add_log_record_attrs is set string messages are not formatted before being shoved into the "msg" in the CloudWatch JSON.
Here's a minimal reproduction:
import logging
import watchtower
logger = logging.getLogger("foo")
handler = watchtower.CloudWatchLogHandler()
handler.formatter.add_log_record_attrs=["levelname", "filename", "process", "thread"]
logger.addHandler(handler)
logger.critical("hello %s world %s", 5, 10)
This produces a JSON in CloudWatch like so:
{
"msg": "hello %s world %s",
"levelname": "CRITICAL",
"filename": "test.py",
"process": 9155,
"thread": 4545472000
}
If you comment out the handler.formatter.add_log_record_attrs you get the plain string logged to CloudWatch with formatting done, e.g. just hello 5 world 10.