web-dev-qa-db-fra.com

Débogage d'une application Flask en cours d'exécution dans Gunicorn

Je travaille sur une nouvelle plate-forme de développement utilisant nginx/gunicorn et Flask pour mon application.

En ce qui concerne les opérations, tout fonctionne bien - le problème que je rencontre concerne le débogage de la couche Flask. Quand il y a une erreur dans mon code, je reçois simplement une erreur 500 directement renvoyée au navigateur et rien ne s'affiche sur la console ou dans mes journaux.

J'ai essayé de nombreuses configurations/options différentes .. Je suppose que je dois manquer quelque chose d'évident.

Mon gunicorn.conf:

import os

bind = '127.0.0.1:8002'
workers = 3
backlog = 2048
worker_class = "sync"
debug = True
proc_name = 'gunicorn.proc'
pidfile = '/tmp/gunicorn.pid'
logfile = '/var/log/gunicorn/debug.log'
loglevel = 'debug'

Un exemple de code Flask qui borks- testserver.py:

from flask import Flask
from flask import render_template_string
from werkzeug.contrib.fixers import ProxyFix

app = Flask(__name__)

@app.route('/')
def index():
    n = 1/0
    return "DIV/0 worked!"

Et enfin, la commande pour exécuter l'application du flacon dans gunicorn:

gunicorn -c gunicorn.conf.py testserver:app

Merci à vous tous

56
mafrosis

La configuration Flask est entièrement séparée de celle de gunicorn. Après la documentation de Flask sur les fichiers de configuration , une bonne solution serait de changer mon source en ceci:

app = Flask(__name__)
app.config.from_pyfile('config.py')

Et dans config.py:

DEBUG = True
44
mafrosis

La solution d'acception ne fonctionne pas pour moi.

Gunicorn est un environnement de pré-forking et apparemment le débogueur Flask ne fonctionne pas dans un environnement de forking

Attention

Même si le débogueur interactif ne fonctionne pas dans forking environnements (ce qui rend presque impossible à utiliser sur serveurs de production) [...]

Même si vous définissez app.debug = True, vous n'obtiendrez toujours qu'une page vide contenant le message Erreur interne du serveur si vous exécutez avec gunicorn testserver:app. Le mieux que vous puissiez faire avec gunicorn est de l'exécuter avec gunicorn --debug testserver:app. Cela vous donne la trace en plus du message Erreur interne du serveur. Cependant, il s’agit simplement de la même trace de texte que celle que vous voyez dans le terminal et non du débogueur Flask.

L'ajout de la section if __... au testserver.py et l'exécution de python testserver.py pour démarrer le serveur en développement procurent le débogueur Flask. En d'autres termes, n'utilisez pas gunicorn en développement si vous voulez le débogueur Flask.

app = Flask(__name__)
app.config['DEBUG'] = True

if __== '__main__':
    app.run()


Astuce pour les utilisateurs Heroku:

Personnellement, j'aime toujours utiliser foreman start, au lieu de python testserver.py puisque il configure toutes les variables env pour moi . Pour que cela fonctionne:

Contenu de Procfile

web: bin/web

Contenu de bin/web, le fichier est relatif à la racine du projet

#!/bin/sh

if [ "$FLASK_ENV" == "development" ]; then
        python app.py
else
        gunicorn app:app -w 3
fi

En développement, créez un fichier .env relatif à la racine du projet avec le contenu suivant (docs here )

FLASK_ENV=development
DEBUG=True

De plus, n'oubliez pas de changer la ligne app.config['DEBUG']... dans testserver.py pour quelque chose qui n'exécutera pas Flask en mode débogage en production.

app.config['DEBUG'] = os.environ.get('DEBUG', False)
71
Nick Zalutskiy

Pour les utilisateurs Heroku , il existe une solution plus simple que de créer un script bin/web comme suggéré par Nick.

Au lieu de foreman start, utilisez simplement foreman run python app.py si vous souhaitez déboguer votre application en développement.

23
aristidesfl

Essayez de définir le drapeau de débogage sur la commande d'exécution comme si 

gunicorn -c gunicorn.conf.py --debug testserver:app

et conservez le DEBUG = True dans votre application Flask. Il doit y avoir une raison pour laquelle votre option de débogage n'est pas appliquée à partir du fichier de configuration, mais pour le moment, la note ci-dessus devrait vous aider.

0
Fuchida

J'ai eu un problème similaire lors de l'exécution de flacon sous gunicorn je ne voyais pas stacktraces dans le navigateur (je devais consulter les journaux à chaque fois). La définition de DEBUG, FLASK_DEBUG ou de tout autre élément mentionné sur cette page ne fonctionnait pas. Finalement j'ai fait ça:

app = Flask(__name__)
app.config.from_object(settings_map[environment])
if environment == 'development':
    from werkzeug.debug import DebuggedApplication
    app_runtime = DebuggedApplication(app, evalex=False)
else:
    app_runtime = app

Remarque: evalex est désactivé car le débogage interactif ne fonctionne pas avec le forking (gunicorn).

0
jazgot