Search code examples
pythonflaskpython-loggingconnexion

Connexion Flask logging formatting


I am struggling in setting the logging for a connexion flask rest api, with a gevent server. I would like to log only the message after each request like GET /health HTTP/1.1 or even better just the http status code, e.g. 200. I follow the flask docu and set up a dictConfig before creating the app. Like this:

import connexion
from logging.config import dictConfig


def main():
    app = connexion.App(__name__)
    app.app.logger.info('This is a check!')
    app.add_api('swagger.yaml')
    app.run(server='gevent')

if __name__ == '__main__':

    dictConfig({
        'version': 1,
        'formatters': {'default': {
            'format': 'Custom message: %(message)s',
        }},
        'handlers': {'wsgi': {
            'class': 'logging.StreamHandler',
            'stream': 'ext://flask.logging.wsgi_errors_stream',
            'formatter': 'default'
        }},
        'root': {
            'level': 'INFO',
            'handlers': ['wsgi']
        }
    })

    main()

Starting the app and after sending two requests (one 200 and one 405):

Custom message: This is a check!
127.0.0.1 - - [2021-03-15 12:42:35] "GET /health HTTP/1.1" 200 126 0.001714
127.0.0.1 - - [2021-03-15 12:42:35] "PUT /health HTTP/1.1" 405 275 0.000711

So, before the app.run() the app.app.logging() looks fine and send just the message Custom message: This is a check!, but after that the logs do not follow the dictionary anymore. Any idea what am I doing wrong?


Solution

  • As far as I can tell the dictConfig is not being used since you are not assigning it to anything.

    You would need something like

    logging.config.dictConfig(yourconfig)
    

    where yourconfig is your dictConfig. Move your dictConfig to main() to have it in the same scope, or import it from a file if you choose to keep it separate.

    See: Logging Cookbook