Why is Flask application not creating any logs when hosted by Gunicorn?

后端 未结 3 647
独厮守ぢ
独厮守ぢ 2020-12-24 02:00

I\'m trying to add logging to a web application which uses Flask.

When hosted using the built-in server (i.e. python3 server.py), logging works. When ho

相关标签:
3条回答
  • 2020-12-24 02:32

    There are a couple of reasons behind this: Gunicorn has its own loggers, and it’s controlling log level through that mechanism. A fix for this would be to add app.logger.setLevel(logging.DEBUG).
    But what’s the problem with this approach? Well, first off, that’s hard-coded into the application itself. Yes, we could refactor that out into an environment variable, but then we have two different log levels: one for the Flask application, but a totally separate one for Gunicorn, which is set through the --log-level parameter (values like “debug”, “info”, “warning”, “error”, and “critical”).

    A great solution to solve this problem is the following snippet:

    import logging
    from flask import Flask, jsonify
    
    app = Flask(__name__)
    
    @app.route('/')
    def default_route():
        """Default route"""
        app.logger.debug('this is a DEBUG message')
        app.logger.info('this is an INFO message')
        app.logger.warning('this is a WARNING message')
        app.logger.error('this is an ERROR message')
        app.logger.critical('this is a CRITICAL message')
        return jsonify('hello world')
    
    if __name__ == '__main__':
        app.run(host=0.0.0.0, port=8000, debug=True)
    
    else:
        gunicorn_logger = logging.getLogger('gunicorn.error')
        app.logger.handlers = gunicorn_logger.handlers
        app.logger.setLevel(gunicorn_logger.level)
    

    Refrence: Code and Explanation is taken from here

    0 讨论(0)
  • 2020-12-24 02:33

    When you use python3 server.py you are running the server3.py script.

    When you use gunicorn server:flaskApp ... you are running the gunicorn startup script which then imports the module server and looks for the variable flaskApp in that module.

    Since server.py is being imported the __name__ var will contain "server", not "__main__" and therefore you log handler setup code is not being run.

    You could simply move the log handler setup code outside of the if __name__ == "__main__": stanza. But ensure that you keep flaskApp.run() in there since you do not want that to be run when gunicorn imports server.

    More about what does if __name__ == “__main__”: do?

    0 讨论(0)
  • 2020-12-24 02:41

    This approach works for me: Import the Python logging module and add gunicorn's error handlers to it. Then your logger will log into the gunicorn error log file:

    import logging
    
    app = Flask(__name__)
    
    gunicorn_error_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers.extend(gunicorn_error_logger.handlers)
    app.logger.setLevel(logging.DEBUG)
    app.logger.debug('this will show in the log')
    

    My Gunicorn startup script is configured to output log entries to a file like so:

    gunicorn main:app \
        --workers 4 \
        --bind 0.0.0.0:9000 \
        --log-file /app/logs/gunicorn.log \
        --log-level DEBUG \
        --reload
    
    0 讨论(0)
提交回复
热议问题