У меня есть приложение 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 и использовал трассировку, чтобы выяснить, из какой строки возникла ошибка, и вывести красивое сообщение об ошибке:
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')
), но оно печатает только это одно сообщение. Попытка зарегистрировать другую ошибку сразу после этой просто игнорируется.