将所有错误记录到Django站点上的控制台或文件中

时间:2009-03-27 17:30:45

标签: python django facebook

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

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

How do you log server errors on django sites

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

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

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

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

谢谢, 杰夫

5 个答案:

答案 0 :(得分:13)

这有点极端,但出于调试目的,您可以打开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作为装饰器,它将自动处理其中发生的任何错误。

  

为某些异常调用进程_异常函数(例如:views.py中的assert(False))但是没有调用进程_异常等其他错误,例如ImportErrors(例如:import) urs.py中的thisclassdoesnotexist)。我是Django / Python的新手。这是因为运行时和编译时错误之间存在某些区别吗?

在Python中,所有错误都是运行时错误。导致问题的原因是因为在调用视图之前导入模块时会立即发生这些错误。我发布的第一个方法会捕获这些错误以进行调试。你可能能够为生产找到一些东西,但是如果你在生产应用程序中获得ImportErrors(并且你没有进行任何动态导入),我认为你会遇到更糟糕的问题。

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

答案 1 :(得分:6)

  

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

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

我认为DEBUG_PROPAGATE_EXCEPTIONS(正如杰森贝克首先提到的)就是你在这里所需要的,但我不认为你不需要做任何额外的事情(即sys.excepthook等)如果你只是希望将回溯转储到控制台。

如果你想对错误做更复杂的事情(即将其转储到文件或数据库),最简单的方法是got_request_exception signal,Django为任何与请求相关的异常发送,无论是否被引发在视图中与否。

django.core.handlers.BaseHandler的get_responsehandle_uncaught_exception方法在这个领域是有启发性的(和简短的)阅读。

  

无需添加任何其他内容   对代码的异常处理。我有   从来没有见过异常处理   进口报表。

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

答案 2 :(得分:2)

首先,您将通过异常日志看到很少的编译时错误。如果您的Python代码没有有效的语法,那么在打开日志进行写入之前很久就会死掉。

在Django runserver模式下,“print”语句写入stdout,您可以看到。然而,这不是一个好的长期解决方案,所以不要指望它。

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

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

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

确保您所做的每个Web服务调用都有一个try / except块,并且您将日志写入日志。

答案 3 :(得分:1)

答案 4 :(得分:-1)

如果您使用的是* nix系统,那么

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

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