У меня есть приложение Flask, которое работает хорошо и создает случайную ошибку, которая видна, когда она работает с debug=True
:
if __name__ == '__main__':
app.run(debug=True)
Я получаю полезные сообщения об ошибках, такие как:
Traceback (most recent call last):
File "./main.py", line 871, in index_route
KeyError: 'stateIIIII'
Я хотел бы получить сообщения об ошибках, подобные сохраненным в файл, когда я запускаю приложение в процессе производства (используя Lighttpd + fastcgi).
Изучив различные вопросы StackOverflow (http://flask.pocoo.org/docs/errorhandling/, http://docs.python.org/2/library/logging.html и т.д.); список рассылки Flask; и несколько блогов, похоже, нет простого способа отправить все большие сообщения об ошибках в файл - мне нужно использовать модуль протоколов Python для настройки вещей. Поэтому я придумал следующий код.
В верхней части моего файла приложения у меня есть различные импортные товары, за которыми следуют:
app = Flask(__name__)
if app.debug is not True:
import logging
from logging.handlers import RotatingFileHandler
file_handler = RotatingFileHandler('python.log', maxBytes=1024 * 1024 * 100, backupCount=20)
file_handler.setLevel(logging.ERROR)
app.logger.setLevel(logging.ERROR)
app.logger.addHandler(file_handler)
Затем я поместил код для каждого маршрута в оператор try/except и использовал traceback, чтобы выяснить, из какой строки возникла ошибка, и напечатать приятное сообщение об ошибке:
def some_route():
try:
# code for route in here (including a return statement)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
app.logger.error(traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2))
return render_template('error.html')
И затем прямо в конце файла я удаляю debug=True
. Хотя я не думаю, что мне нужно это сделать, поскольку приложение запускается сервером fastcgi (?), Когда он запускается на производстве. Последние две строки моего кода приложения выглядят следующим образом:
if __name__ == '__main__':
app.run()
Я изо всех сил пытаюсь заставить это работать. Я думаю, что лучше всего мне удалось получить одно сообщение журнала ошибок, которое будет сохранено в файле, используя (app.logger.error('test message')
), но оно печатает только одно сообщение. Попытка зарегистрировать другую ошибку сразу после этого просто игнорируется.