Flask logging with Foreman
Asked Answered
C

1

7

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
Corazoncorban answered 8/12, 2013 at 18:59 Comment(0)
D
12

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
Downcomer answered 8/12, 2013 at 19:20 Comment(5)
@Miguel- thanks, but this is only working for warning-level logging. debug-level logging is still not showing up. How do I run the app in debug mode with Foreman?Corazoncorban
@Yarin: I have updated the code, I had the logging level set in the handler, not in the parent logger. I've also added a snippet that shows you how to set debug mode without calling app.run().Downcomer
@Miguel- Perfect- the single line app.debug = True was really all I needed.Corazoncorban
@Miguel- I've ran into one problem with this- The app doesn't reload changes when setting debug like this. When running the app in debug mode without foreman I don't need to restart the app to see changes, but for some reason I do with this. Any ideas?Corazoncorban
@Yarin: the reloader is a feature offered by Werkzeug, which you are replacing with Gunicorn when you run under Foreman, so you don't have that. If you set your Procfile to use Werkzeug then you can start the app by calling app.run(debug = True) and then you get the reloader.Downcomer

© 2022 - 2024 — McMap. All rights reserved.