【问题标题】:Log all errors to console or file on Django site将所有错误记录到控制台或 Django 站点上的文件
【发布时间】:2010-10-15 23:58:15
【问题描述】:

在调试模式下运行 runserver 时,如何让 Django 1.0 将 all 错误写入控制台或日志文件?

我已尝试使用带有 process_exception 函数的中间件类,如该问题的已接受答案中所述:

How do you log server errors on django sites

process_exception 函数会针对某些异常调用(例如:views.py 中的 assert(False)),但不会针对 ImportErrors 等其他错误调用 process_exception(例如:在 urs.py 中导入 thisclassdoesnotexist)。我是 Django/Python 的新手。这是因为运行时错误和编译时错误之间存在一些区别吗?但是,如果它是编译时错误,我希望 runserver 会抱怨,而事实并非如此。

我看过 Simon Willison 关于 Django 调试 (http://simonwillison.net/2008/May/22/debugging/) 的精彩演示,但我没有看到适合我的选项。

如果它是相关的,我正在编写一个 Facebook 应用程序,Facebook 用他们自己的消息来掩盖 HTTP 500 错误,而不是显示 Django 信息丰富的 500 页面。所以我需要一种将所有类型的错误写入控制台或文件的方法。

编辑: 我想我的期望是如果 Django 可以在 urls.py 中有错误导入 (ImportError) 时返回包含大量详细信息的 500 错误页面,它应该能够编写控制台或文件的相同细节,而无需向代码添加任何额外的异常处理。我从未见过围绕 import 语句的异常处理。

谢谢, 杰夫

【问题讨论】:

    标签: python django facebook


    【解决方案1】:

    有点极端,不过为了调试,可以开启DEBUG_PROPAGATE_EXCEPTIONS设置。这将允许您设置自己的错误处理。设置上述错误处理的最简单方法是覆盖sys.excepthook。这将终止您的应用程序,但它会起作用。您可能可以采取一些措施来使其不会杀死您的应用程序,但这将取决于您为其部署的平台。无论如何,永远不要在生产中使用它!

    对于生产,您几乎必须进行大量的错误处理。我使用的一种技术是这样的:

    >>> def log_error(func):
    ...     def _call_func(*args, **argd):
    ...         try:
    ...             func(*args, **argd)
    ...         except:
    ...             print "error" #substitute your own error handling
    ...     return _call_func
    ...
    >>> @log_error
    ... def foo(a):
    ...     raise AttributeError
    ...
    >>> foo(1)
    error
    

    如果您在视图上使用 log_error 作为装饰器,它将自动处理其中发生的任何错误。

    process_exception 函数被调用来处理一些异常(例如:在views.py 中的assert(False))但是process_exception 没有被调用来处理像ImportErrors 这样的其他错误(例如:import thisclassdoesnotexist in urs. py)。我是 Django/Python 的新手。这是因为运行时错误和编译时错误之间的一些区别吗?

    在 Python 中,所有错误都是运行时错误。这导致问题的原因是因为在调用视图之前导入模块时会立即发生这些错误。我发布的第一种方法将捕获此类错误以进行调试。您可能能够为生产解决一些问题,但我认为如果您在生产应用程序中遇到 ImportErrors(并且您没有进行任何动态导入),那么您会遇到更严重的问题。

    pylint 这样的工具可以帮助您消除这些问题。

    【讨论】:

    • DEBUG_PROPOGATE_EXCEPTIONS = True 完全按照我的需要工作——它将堆栈转储到运行服务器控制台。它甚至没有终止应用程序!
    • 拼写为“DEBUG_PROPAGATE_EXCEPTIONS”。
    【解决方案2】:
    【解决方案3】:

    process_exception 函数是 要求一些例外(例如: 在views.py中断言(假))但是 process_exception 没有得到 要求其他错误,例如 ImportErrors(例如:导入 这个类在 urs.py 中不存在)。我是 Django/Python 的新手。这是因为 运行时之间的一些区别 和编译时错误?

    不,只是因为process_exception middleware is only called if an exception is raised in the view

    我认为DEBUG_PROPAGATE_EXCEPTIONS(正如 Jason Baker 首先提到的)是你需要的,但我认为你不需要做任何额外的事情(即 sys.excepthook 等),如果你只想要回溯转储到控制台。

    如果你想对错误做任何更复杂的事情(即将它转储到文件或数据库),最简单的方法是got_request_exception signal,Django 发送它来处理任何与请求相关的异常,无论它是在看还是不看。

    django.core.handlers.BaseHandler 的get_responsehandle_uncaught_exception 方法是该领域的指导性(和简短)阅读。

    无需添加任何额外的 代码的异常处理。我有 从未见过异常处理 导入语句。

    再看看周围,你会看到它完成了(通常在你想以某种特定方式处理缺少依赖的情况下)。也就是说,如果你不得不在你的代码中添加额外的 try-except 块来对异常的处理方式进行全局更改,那当然会非常难看!

    【讨论】:

      【解决方案4】:

      如果你在 *nix 系统上,你可以

      在 python 中写入日志(例如 mylog.txt) 然后在控制台中运行“tail -f mylog.txt”

      这是一种近乎实时查看任何类型日志的便捷方式

      【讨论】:

        【解决方案5】:

        首先,您可以通过异常日志看到的编译时错误非常少。如果你的 Python 代码没有有效的语法,它会在日志被打开写之前很久就死掉了。

        在 Django 运行服务器模式下,“打印”语句写入标准输出,您可以看到。但是,这不是一个好的长期解决方案,所以不要指望它。

        但是,当 Django 在 Apache 下运行时,这取决于您使用的插件。 mod_python 不容易处理。可以强制 mod_wsgi 将 stdout 和 stderr 发送到日志文件。

        不过,您最好的选择是logging 模块。将初始化放入您的顶级 urls.py 以配置日志记录。 (或者,也许,你的settings.py

        确保每个模块都有一个可用于写入日志消息的记录器。

        确保您进行的每个 Web 服务调用都有一个 try/except 块,并将异常写入日志。

        【讨论】:

        • 这很有帮助,但并不完全符合我的预期。请参阅有问题的“编辑”。
        猜你喜欢
        • 2012-07-07
        • 2018-03-10
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        • 2011-06-14
        • 1970-01-01
        • 2020-09-12
        • 1970-01-01
        相关资源
        最近更新 更多