Formatting Flask app logs in json
Question: I'm working with a Python/Flask application and trying to get the logs to be
formatted (by line) in json.

Using the python-json-logger package, I've modified the formatter for the
app.logger as follows:

    
    
    from pythonjsonlogger import jsonlogger
    formatter = jsonlogger.JsonFormatter(
        '%(asctime) %(levelname) %(module) %(funcName) %(lineno) %(message)')
    app.logger.handlers[0].setFormatter(formatter)
    

This works as expected. Any messages passed to `app.logger` are correctly
formatted in json.

However the application is also automatically logging all requests. This
information shows up in stdout as follows:

    
    
    127.0.0.1 - - [19/Jun/2015 12:22:03] "GET /portal/ HTTP/1.1" 200 -
    

I want this information to be formatted in json as well. I've been looking for
the logger/code that is responsible for creating this output with no success.

Where is this output generated? Are the mechanisms to change the formatting of
this logged information?


Answer: When you use the `app.logger` attribute for the first time, Flask sets up some
log handlers:

  * a debug logger that is set to log level `DEBUG` and that filters on `app.debug` being true.
  * a production logger that is set to `ERROR`.

You can remove those handlers again yourself, by running:

    
    
    app.logger.handlers[:] = []
    

However, the log line you see is not logged by Flask, but by the WSGI server.
Both the built-in Werkzeug server (used when you use `app.run()`) and various
other WSGI servers do this. Gunicorn for example uses the default Python
logger to record access.

The built-in WSGI server should never be used in production (it won't scale
well, and is not battle-hardened against malicious attackers).

For Gunicorn, you can disable _log propagation_ to keep the logging separate:

    
    
    logging.getLogger('gunicorn').propagate = False
    

