watchtower
watchtower copied to clipboard
CloudWatchLogFormatter mutates logged dicts
Summary
When using the CloudWatchLogFormatter with its add_log_record_attrs functionality, it mutates dictionary objects that are passed to logging calls.
Reproducible Example
import logging
import watchtower
logger = logging.getLogger() # root logger
logger.setLevel(logging.DEBUG)
added_attrs = ('lineno', 'funcName', 'levelname', 'created', 'module')
formatter = watchtower.CloudWatchLogFormatter(add_log_record_attrs=added_attrs)
stream = logging.StreamHandler()
stream.setFormatter(formatter)
logger.addHandler(stream)
logged_value = {"key": "value"}
print(logged_value) # unchanged
logger.info(logged_value)
print(logged_value) # mutated
Suggested Mitigation
It would be a performance hit but we could deepcopy the dict before adding all the attributes. This is what I'm doing on my custom implementation of a JsonFormatter.