madzak / python-json-logger

Json Formatter for the standard python logger
BSD 2-Clause "Simplified" License
1.7k stars 231 forks source link

Dictionaries passed to format as the log message are modified #114

Closed gps035 closed 1 year ago

gps035 commented 3 years ago

When a dictionary is passed as a message to logger.exception, it can be modified unexpectedly, and this can cause issues if the dict is reused. For instance, this code will result in exc_info being added to the flask JSON response when an error occurs.

    try:
        foos = get_foos_for_bar(bar)
        return flask.jsonify(foos)
    except Exception:
        message = {"message": "Error getting foos for bar", "bar": bar}
        logger.exception(message)
        return flask.jsonify(message), HTTPStatus.INTERNAL_SERVER_ERROR

Upon finding the cause, the fix was pretty clear and we defined the dict inline in both call sites:

        message = "Error getting foos for bar"
        logger.exception({"message": message, "bar": bar})
        return flask.jsonify({"message": message, "bar": bar}), HTTPStatus.INTERNAL_SERVER_ERROR

That said, this isn't something I would expect the library to do, and it took a bit of time to trace this to the library's format method. It seems to me that this could be fixed by modifying line 188 https://github.com/madzak/python-json-logger/blob/e2287881d01e276744dfd85d74944c72954d38aa/src/pythonjsonlogger/jsonlogger.py#L188 from

message_dict = record.msg

to

message_dict = message_dict.update(**record.msg)

But I am not aware of all of the use cases so I can't be sure if this would be the correct approach.