Flask logging with Foreman

3.2k views Asked by At

I'm trying to set up a Heroku-ready Flask app, but I can't figure out how to turn on logging.

Without Foreman, I could create a helloworld app as described in the Flask tutorial:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    app.logger.debug('A value for debugging')
    app.logger.warning('A value for warning')
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True)

start it like so:

python hello.py

and have logging in stdout.

When I follow the Heroku tutorial, however, there's no app.run line:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    app.logger.debug('A value for debugging')
    app.logger.warning('A value for warning')
    return 'Hello World!'

And so I can't figure out how to run in debug mode and/or get logging output:

foreman start -p 5000

Procfile:

web: gunicorn hello:app
1

There are 1 answers

5
Miguel Grinberg On BEST ANSWER

The default logging configuration for Flask apps is different in debug vs. production mode.

In your first example you are in debug mode. In this case Flask defines a logging handlers that logs all messages with level logging.DEBUG or higher to stderr.

The second example is not in debug mode. When debug mode is not enabled Flask creates a logger object but does not add any handlers to it, so nothing is printed.

For Foreman and Heroku you need logs to be sent to stdout or stderr, so all you need to do is add a StreamHandler with the logging level of your choice:

import os
from flask import Flask

app = Flask(__name__)

# log to stderr
import logging
from logging import StreamHandler
file_handler = StreamHandler()
app.logger.setLevel(logging.DEBUG)  # set the desired logging level here
app.logger.addHandler(file_handler)

@app.route('/')
def hello():
    app.logger.debug('A value for debugging')
    app.logger.warning('A value for warning')
    return 'Hello World!'

Alternatively, if you prefer you can do none of this and just enable debug mode for the Foreman/Heroku controlled application, though this would not be something I'd recommend for a production app:

from flask import Flask
app = Flask(__name__)
app.debug = True