web-dev-qa-db-de.com

Debuggen einer in Gunicorn laufenden Flaschen-App

Ich habe an einer neuen Entwicklerplattform mit Nginx/gunicorn und Flask für meine Anwendung gearbeitet.

Alles in allem funktioniert alles gut - das Problem, das ich habe, ist das Debuggen der Flask-Ebene. Wenn in meinem Code ein Fehler auftritt, wird ein 500-Fehler direkt an den Browser zurückgegeben, und auf der Konsole oder in meinen Protokollen wird nichts angezeigt.

Ich habe viele verschiedene Konfigurationen/Optionen ausprobiert .. Ich schätze, ich muss fehlt offensichtlich.

Meine 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'

Ein Beispiel für einen Flask-Code, der borks- testserver.py enthält:

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!"

Und schließlich der Befehl, die Flaschen-App in Gunicorn auszuführen:

gunicorn -c gunicorn.conf.py testserver:app

Danke dir allen

56
mafrosis

Die Flask-Konfiguration ist von der von Gunicorn völlig getrennt. Nach der Flask-Dokumentation zu Konfigurationsdateien , wäre eine gute Lösung meine Quelle zu ändern:

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

Und in config.py:

DEBUG = True
44
mafrosis

Die Akzeptanzlösung funktioniert für mich nicht.

Gunicorn ist eine Umgebung vor der Gabelung und anscheinend funktioniert der Flask-Debugger in einer Umgebung mit Gabelung nicht

Beachtung

Obwohl der interaktive Debugger in .__ nicht funktioniert. Forking-Umgebungen (was die Verwendung auf Produktionsservern nahezu unmöglich macht) [...]

Selbst wenn Sie app.debug = True einstellen, erhalten Sie nur eine leere Seite mit der Meldung Internal Server Error, wenn Sie mit gunicorn testserver:app ausführen. Das Beste, was Sie mit gunicorn machen können, ist, es mit gunicorn --debug testserver:app auszuführen. Dadurch erhalten Sie die Ablaufverfolgung zusätzlich zur Meldung Internal Server Error. Dies ist jedoch genau die gleiche Ablaufverfolgung, die Sie im Terminal und nicht im Flask-Debugger sehen.

Durch Hinzufügen des if __...-Abschnitts zu testserver.py und Ausführen von python testserver.py zum Starten des Servers in der Entwicklung wird der Flask-Debugger angezeigt. Mit anderen Worten, gunicorn sollte nicht in der Entwicklung verwendet werden, wenn Sie den Flask-Debugger möchten.

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

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


Tipp für Heroku-Benutzer:

Ich persönlich benutze immer noch gerne foreman start, statt python testserver.py, da alle env-Variablen für mich eingerichtet werden . Damit das funktioniert,

Inhalte von Procfile

web: bin/web

Der Inhalt von bin/web, Datei ist relativ zum Projektstamm

#!/bin/sh

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

Erstellen Sie in der Entwicklung eine .env-Datei relativ zum Projektstamm mit folgendem Inhalt (docs here )

FLASK_ENV=development
DEBUG=True

Vergessen Sie nicht, die app.config['DEBUG']...-Zeile in testserver.py so zu ändern, dass Flask nicht im Debug-Modus in der Produktion ausgeführt wird.

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

Für Heroku-Benutzer gibt es eine einfachere Lösung als das Erstellen eines bin/web-Skripts wie von Nick vorgeschlagen.

Verwenden Sie statt foreman start einfach foreman run python app.py, wenn Sie Ihre Anwendung in der Entwicklung debuggen möchten.

23
aristidesfl

Setzen Sie das Debug-Flag wie folgt auf den Ausführungsbefehl 

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

und bewahren Sie den DEBUG = True in Ihrer Flask-Anwendung auf. Es muss einen Grund dafür geben, dass Ihre Debug-Option nicht aus der Konfigurationsdatei übernommen wird, aber für den Moment sollte der obige Hinweis Sie weiterbringen.

0
Fuchida

Ich hatte ein ähnliches Problem beim Laufen der Flasche unter Gunicorn. Ich habe keine Stacktraces im Browser gesehen (musste jedes Mal Protokolle anzeigen). Das Setzen von DEBUG, FLASK_DEBUG oder irgendetwas, das auf dieser Seite erwähnt wird, hat nicht funktioniert. Zum Schluss habe ich das gemacht:

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

Beachten Sie, dass evalex deaktiviert ist, da interaktives Debuggen nicht mit forking (gunicorn) funktioniert.

0
jazgot