如何将Flask出色的调试日志消息写入生产中的文件? [英] How do I write Flask's excellent debug log message to a file in production?

查看:995
本文介绍了如何将Flask出色的调试日志消息写入生产中的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Flask应用程序运行良好,并产生偶尔的错误。当我的应用程序在调试模式下使用:

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

我收到了有用的错误消息,例如:

$ $ p $ code $ traceback最近一次调用最后一次
在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__)

如果app.debug不是True:
从logging.handlers导入日志
导入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来计算错误来自哪条线,并打印一个好的错误信息:

pre $ def some_route():
尝试:
#此处的路由代码(包括返回语句)

除外:
exc_type,exc_value,exc_traceback = sys。 exc_info()
app.logger.error(traceback.print_excepti on(exc_type,exc_value,exc_traceback,limit = 2))
return render_template('error.html')

然后在文件的最后删除debug = True语句。虽然我不认为我需要这样做,因为应用程序在生产环境中运行时由fastcgi服务器(?)运行。我的应用程序代码的最后两行看起来像这样:

pre $如果__name__ =='__main__':
app。 run()

我正在努力工作。我认为我所管理的最好的方法是使用(app.logger.error('test message'))来获取单个错误日志消息,但它只打印该消息。试图在这之后直接记录另一个错误简单地被忽略。

解决方案

我不知道为什么它不工作,但我可以告诉我如何做到这一点。



首先,您不需要设置app.logger的级别。所以删除这行 app.logger.setLevel()



你想保存异常并返回错误页面每一个观点。编写这些代码到处都是很多工作。 Flask提供了一个方法来做到这一点。定义一个像这样的错误处理方法。

  @ app.errorhandler(500)
def internal_error(异常):
app.logger.error(例外)
返回render_template('500.html'),500

每当一个视图产生一个异常时,这个方法将被调用,并将这个异常作为参数传递。 Python日志记录提供了异常方法,用于保存异常的完整追踪。



由于这处理所有的异常,所以你甚至不需要把代码放在try / except块。虽然,如果你想在调用错误处理程序(例如回滚会话或事务)之前做一些事情,那么执行以下操作:

  try: 
#code
除了:
#code
raise

如果您希望为日志文件中的每个条目添加日期和时间,则可以使用以下代码(代替问题中的类似代码)。

 如果app.debug不是True:
从logging.handlers导入日志
导入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)


I have a Flask application that works well and produces the occasional error. When my application is in debug mode using:

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

I get useful error messages such as:

Traceback (most recent call last):
  File "./main.py", line 871, in index_route

KeyError: 'stateIIIII'

I would like to get error messages like these saved to a file when I run the application in production (using Lighttpd + fastcgi).

After looking at various StackOverflow questions, http://flask.pocoo.org/docs/errorhandling/, http://docs.python.org/2/library/logging.html, the Flask mailing list, and a few blogs, it seems there is no "easy" way just to send all the great error messages to a file - I need to use the Python logging module to customise things. So I came up with the following code.

At the top of my application file I have various imports followed by:

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)

I have then put the code for each route in a try/except statement and use traceback to work out which line the error came from and print a nice error message:

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

And then right at the end of the file I remove the debug=True statement. Though I don't think I need to do that as the application is being run by a fastcgi server(?) when it is run in production. The last two lines of my application code look like this:

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

I am struggling to get this working. I think the best I have managed is to get a single error log message to be saved in the file using (app.logger.error('test message') ), but it only prints that one message. An attempt to log another error directly after that one is simply ignored.

解决方案

I don't know why it's not working but I can tell how am doing this.

First of all, you don't need to set the level of app.logger. So remove this line app.logger.setLevel().

You want to save exception and return error page for every view. It is a lot of work to write this code everywhere. Flask provides a method to do this. Define an errorhandler method like this.

    @app.errorhandler(500)
    def internal_error(exception):
        app.logger.error(exception)
        return render_template('500.html'), 500

Whenever a view raises an exception, this method will be called and passed the exception as argument. Python logging provides exception method that is used to save full traceback of the exception.

Since this handles all exception, you don't even need to put code in try/except block. Though, if you want to do something before calling the errorhandler(for e.g. rollback session or transaction) then do this:

    try:
        #code
    except:
        #code
        raise

If you would like the date and time added for each entry in your log file, the following code can be used (in place of the similar code featured in the question).

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)

这篇关于如何将Flask出色的调试日志消息写入生产中的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆