Отладка приложения Flask, запущенного в Gunicorn

Я работаю над новой платформой разработчиков, используя nginx/gunicorn и Flask для своего приложения.

По-разному, все работает отлично - проблема, с которой я столкнулась, - это отладка слоя Flask. Когда в моем коде появляется ошибка, я просто получаю прямую ошибку 500, возвращенную в браузер, и ничего не отображается на консоли или в моих журналах.

Я пробовал много разных конфигураций/опций. Я предполагаю, что я должен пропустить что-то очевидное.

Мой 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'

Пример некоторого кода флэшки, который 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!"

И, наконец, команда запускать флеш-приложение в gunicorn:

gunicorn -c gunicorn.conf.py testserver:app

Спасибо y'all

Ответы

Ответ 1

Конфигурация Flask полностью отделена от пушки. Следуя документации Flask в файлах конфигурации, хорошим решением будет изменение моего источника:

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

И в config.py:

DEBUG = True

Ответ 2

Решение для принятия не работает для меня.

Gunicorn - это предварительная инфраструктура и, по-видимому, отладочная программа Flask не работает в среде forking.

Внимание

Несмотря на то, что интерактивный отладчик не работает в (что делает практически невозможным использование производственных серверов) [...]

Даже если вы установите app.debug = True, вы все равно получите только пустую страницу с сообщением Internal Server Error, если вы используете gunicorn testserver:app. Лучшее, что вы можете сделать с помощью пушки, - запустить его с помощью gunicorn --debug testserver:app. Это дает вам след в дополнение к сообщению внутренней ошибки сервера. Однако это только те же трассировки текста, которые вы видите в терминале, а не отладчик Flask.

Добавление раздела if __name__ ... в testerver.py и запуск python testserver.py, чтобы запустить сервер в разработке, вы получите отладчик Flask. Другими словами, не используйте gunicorn в разработке, если вы хотите отладчик Flask.

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

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


Совет для пользователей Heroku:

Лично мне все же нравится использовать foreman start вместо python testserver.py, поскольку устанавливает для меня все переменные env. Чтобы это получилось:

Содержание Procfile

web: bin/web

Содержимое bin/web, файл относится к корню проекта

#!/bin/sh

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

В разработке создайте файл .env относительно корня проекта со следующим содержимым (docs здесь)

FLASK_ENV=development
DEBUG=True

Кроме того, не забудьте изменить строку app.config['DEBUG']... в testserver.py на то, что не будет запускать флажок в режиме отладки в процессе производства.

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

Ответ 3

Для пользователей Heroku существует более простое решение, чем создание bin/web script, как это было предложено Ником.

Вместо foreman start просто используйте foreman run python app.py, если вы хотите отлаживать ваше приложение в процессе разработки.

Ответ 4

Попробуйте установить флаг отладки в команде запуска так:

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

и сохраните DEBUG = True в вашем приложении Flask. Должна быть причина, по которой ваша опция отладки не применяется из файла конфигурации, но на данный момент вы должны перейти к указанной выше заметке.

Ответ 5

У меня была аналогичная проблема при запуске колбы под стрельбой. Я не видел стеков в браузере (приходилось каждый раз смотреть на журналы). Установка DEBUG, FLASK_DEBUG или что-либо, упомянутое на этой странице, не работает. Наконец я сделал это:

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

Примечание. evalex отключен, поскольку интерактивная debbugging не будет работать с forking (gunicorn).