Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting Flask app logs in json

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?

like image 708
wizeowl Avatar asked Jun 19 '15 19:06

wizeowl


1 Answers

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
like image 98
Martijn Pieters Avatar answered Sep 27 '22 20:09

Martijn Pieters