内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
我有一个能正常工作并偶尔产生错误的烧瓶应用程序。当我的应用程序处于调试模式时,使用:
if __name__ == '__main__': app.run(debug=True)
我收到有用的错误消息,例如:
Traceback (most recent call last): File "./main.py", line 871, in index_route KeyError: 'stateIIIII'
在生产中运行应用程序时,我希望获得这样的错误消息,保存到文件中(使用Lightttpd+Quickcgi)。
在我的应用程序文件的顶部,有各种导入,后面跟着:
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/EXT语句中,并使用回溯来计算错误来自哪一行,并打印一条很好的错误消息:
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语句。虽然我不认为我需要这样做,因为当该应用程序在生产中运行时,该应用程序是由快速cgi服务器(?)运行的。我的应用程序代码的最后两行如下所示:
if __name__ == '__main__': app.run()
我正努力让这件事起作用。我认为我管理的最佳方法是使用(app.logger.Error(‘test Message“))将单个错误日志消息保存在文件中,但它只输出这一条消息。在该错误被忽略之后,直接记录另一个错误的尝试。
我不知道为什么不行,但我知道我是怎么做到的。
首先,不需要设置app.logger级别。所以移除这一行app.logger.setLevel()
...
希望保存每个视图的异常并返回错误页。在任何地方编写这段代码都是一项很大的工作。定义这样的错误处理程序方法。
@app.errorhandler(500) def internal_error(exception): app.logger.error(exception) return render_template('500.html'), 500
每当视图引发异常时,都会调用此方法并将其作为参数传递。PythonLogging提供了用于保存异常的完整跟踪的异常方法。
因为这样可以处理所有异常,所以甚至不需要将代码放入try/EXT块中。但是,如果想在调用错误处理程序之前执行一些操作,那么执行以下操作:
try: #code except: #code raise
如果希望为日志文件中的每个条目添加日期和时间,可以使用以下代码(代替问题中的类似代码)。
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) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") file_handler.setFormatter(formatter) app.logger.addHandler(file_handler)
我认为最好将更多有用的信息放入错误信息中。URL、客户端IP、用户代理等.。记录异常(在app.debug==False
(模式)与Flask.log_exception
功能。所以,与其手动登录到@app.errorhandler
我做了这样的事:
class MoarFlask(Flask): def log_exception(self, exc_info): """...description omitted...""" self.logger.error( """ Request: {method} {path} IP: {ip} User: {user} Agent: {agent_platform} | {agent_browser} {agent_browser_version} Raw Agent: {agent} """.format( method = request.method, path = request.path, ip = request.remote_addr, agent_platform = request.user_agent.platform, agent_browser = request.user_agent.browser, agent_browser_version = request.user_agent.version, agent = request.user_agent.string, user=user ), exc_info=exc_info )
然后,在配置时绑定FileHandler
到app.logger
然后继续。我不用StreamHandler
因为许多服务器(例如uWSGI)喜欢用自己的专有的、冗长的、无用的、不可关闭的消息来污染它。