How to enrich logging messages with request information in flask?
<p>I have a small Flask app that's used like a REST API that implements many methods like this:</p>

<pre><code>@route('/do/something', methods=['POST'])
def something():
    app.logger.debug("got request to /do/something")
    result = something_implementation(request.json())
    app.logger.debug("result was %s", str(result))
    return flask.Response(result)
</code></pre>

<p>I would like to enrich these log messages automatically with information from the request object such as header information, parts of the body and whatever else is convenient. </p>

<p>How do I do that in an elegant and pythonic way?</p>

<p>Of course I could just wrap app.logger in my own function and pass the request object and the message along, but there's got to be a nicer and easier way I'm missing.</p>

<p>I have solved this by subclassing <code>logging.Filter</code> and adding it to my handler.</p>

<p>Something like this:</p>

<pre><code>class ContextFilter(logging.Filter):
    '''Enhances log messages with contextual information'''
    def filter(self, record):
        try:
            record.rid = request.rid
        except RuntimeError as exc:
            if str(exc.message) == 'working outside of request context':
                record.rid = ''
            else:
                raise exc
        return True
</code></pre>

<p>The try/except clause is necessary for log messages outside of a request context to work. 
And then use it like this:</p>

<pre><code>fileHandler = RotatingFileHandler(app.config['LOGFILE'], maxBytes=20971520,
                                  backupCount=5, encoding='utf-8')
fileHandler.setLevel(logging.DEBUG)
fileHandler.addFilter(ContextFilter())
filefmt = '%(asctime)s [%(filename)s:%(lineno)d] %(rid)s: %(message)s'
fileFormatter = logging.Formatter(filefmt)
fileHandler.setFormatter(fileFormatter)
app.logger.addHandler(fileHandler)
</code></pre>

<p>In the future I can add more fields in the <code>ContextFilter.filter()</code> method and use them however I please in the formatter configuration.</p>

python logging flask