For the life of me, I can't figure out where my errors are coming from in my Flask app when I run it through gunicorn, as I can't figure out how to get a stack trace displayed.
For example, let's say I have a very simple "Hello, World!" app written in Flask.
import logging
import os
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route('/')
def hello():
raise Exception('Exception raised!')
return 'Hello World!'
if __name__ == '__main__':
app.run()
If I run this with python hello.py
, then all is well, as I get a very useful stack trace:
(venv)142:helloflask $ python hello.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader
127.0.0.1 - - [30/Jun/2014 18:52:42] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/grautur/code/helloflask/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/grautur/code/helloflask/hello.py", line 10, in hello
raise Exception('Exception raised!')
Exception: Exception raised!
However, if I create a Procfile with
web: gunicorn hello:app
and then start the app with foreman start -p 8000
, then I see nothing at all. Just an "Internal Server Error" webpage.
$ foreman start -p 8000
18:56:10 web.1 | started with pid 36850
(...nothing else is ever displayed...)
How do I get my Flask+gunicorn app to show more useful debugging messages? I tried setting app.debug = True
(and various iterations thereof), as it seemed like other StackOverflow posts suggested, but it doesn't seem to change anything.
Step 1 — Using The Flask Debugger. In this step, you'll create an application that has a few errors and run it without debug mode to see how the application responds. Then you'll run it with debug mode on and use the debugger to troubleshoot application errors.
If you click on the “Run and Debug” icon on the left hand side of the IDE or alternatively type Ctrl+Shift+D you will see the “RUN AND DEBUG” window. Now click on the “create a launch. json file” link and when prompted to “Select a debug configuration” choose “Python File Debug the currently active Python file”.
I'm not familiar with Foreman, so not sure if it needs to be configured in any way, but for Gunicorn to log anything, first you need to set up logging for your Flask app.
The simple way to do it would be like the following:
import logging
# Log only in production mode.
if not app.debug:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
StreamHandler
logs to stderr by default. If you want to log to a file, Gunicorn has --access-logfile
and --error-logfile
options.
For more detailed explanations and a few good ideas about Flask error handling see the docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With