当前位置: 首页 > 面试题库 >

如何将Flask出色的调试日志消息写入生产环境中的文件?

马边浩
2023-03-14
问题内容

我有一个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’))将一条错误日志消息保存在文件中,但是它只会打印一条消息。直接忽略在该错误之后立即记录另一个错误的尝试。


问题答案:

我不知道为什么它不起作用,但是我可以说出它是怎么做的。

首先,你不需要设置app.logger的级别。因此删除此行app.logger.setLevel()

你想要保存异常并为每个视图返回错误页面。在任何地方编写此代码都是很多工作。Flask提供了一种执行此操作的方法。定义这样的错误处理程序方法。

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

每当视图引发异常时,都会调用此方法并将异常作为参数传递。Python日志记录提供了异常方法,该方法用于保存对异常的完整追溯。

由于这可以处理所有异常,因此你甚至无需将代码放在try / except块中。但是,如果你想在调用错误处理程序之前执行某些操作(例如,回滚会话或事务),请执行以下操作:

    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)


 类似资料:
  • 一个简单的ASP.NET Core2.0web应用程序,作为应用程序服务部署在azure中-编辑以确保对ASPNETCORE_ENVIRONMENT开发和生产的配置是相同的。 在Startup类的Configure方法中包含以下内容: 根据aspnetcore_environment的值,导致不同的行为。 使用基本的ASP.NET core日志记录并配置应用程序洞察,我会得到以下行为: LogDe

  • 我在我的项目中使用log4j。我想有标准输出、调试记录器和最终报告记录器。调试记录器几乎写调试/信息级别的消息。报告将是不同的记录器,只写信息消息。我尝试了不同的方法,阅读了很多示例,我仍然无法解决这个问题。要么我丢失了我的标准输出,要么我将所有调试写入两个记录器。 我的密码在这里 } 任何提示都将不胜感激

  • 问题内容: 此代码是否同时写入日志文件和控制台? 问题答案: 不,它不会同时写入两者。只会写入控制台。关于原始代码的简短说明。我想您在某处定义,但是代码仍然不正确。您需要在语句中使用引号,例如: 因为我认为您是要附加到文件中。否则,您的代码将抛出一个因为未定义的变量。 但是,正如其他人所说,您应该强烈考虑使用日志记录模块。这是一个如何同时写入控制台和日志文件的简单示例。该代码部分源自此处和此处:

  • 问题内容: 我正在尝试使用Go写入日志文件。 我尝试了几种方法,但都失败了。这是我尝试过的: 日志文件被创建,但是没有任何打印或附加到该文件。为什么? 问题答案: 过去的工作方式一定不同,但这对我有用: 基于Go文档,不能用于,因为它会打开文件“供阅读:” 打开命名文件以供读取。如果成功,则可以使用返回文件上的方法进行读取;关联的文件描述符具有mode 。如果有错误,它将是类型。 编辑 检查后移至

  • 我正在开发一个简单的桌面应用程序(不是webapp)。 它们有不同的模式。好像他们忽略了我的设置。 我也试着应用我在这里找到的建议: https://spring.io/blog/2009/12/04/logging-dependencies-in-spring