如何在Django网站上记录服务器错误


175

因此,在进行开发时,我可以设置settings.DEBUGTrue,如果发生错误,我可以看到格式正确,具有良好的堆栈跟踪和请求信息。

但是在某种生产站点上,我更愿意使用DEBUG=False并向访问者展示一些标准错误500页,其中包含我目前正在修复此bug的信息;)
同时,我想以某种方式记录所有这些信息(堆栈跟踪和请求信息)存储到服务器上的文件中-因此我可以将其输出到控制台并观看错误滚动,每小时将日志发送给我或类似的东西。

您会为django站点推荐什么样的日志记录解决方案,这些解决方案可以满足那些简单的要求?我有作为fcgi服务器运行的应用程序,并且我使用apache Web服务器作为前端(尽管考虑使用lighttpd)。




Cherian共享的链接现在已死。如果您尝试搜索Sentry,则很可能会找到其付费官方实例的材料,但是这里是用于设置自托管实例的链接:docs.sentry.io/server 另外,这是当前维护的存储库:github .com / getsentry / sentry
lehiester

Answers:


103

好的,当时DEBUG = False,Django会自动将所有错误的完整回溯邮件发送给ADMINS设置中列出的每个人,这几乎可以免费为您提供通知。如果您想要更细粒度的控件,则可以编写一个中间件类并将其添加到设置中,该中间件类定义了一个名为的方法process_exception(),该方法可以访问所引发的异常:

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

process_exception()然后,您的方法可以执行您想要的任何类型的日志记录:写入控制台,写入文件等,等等。

编辑:尽管它的用处不大,但是您也可以侦听got_request_exception信号,该信号将在请求处理期间遇到异常时发送:

http://docs.djangoproject.com/en/dev/ref/signals/#got-request-exception

但是,这不能使您访问异常对象,因此中间件方法更容易使用。


7
请注意,logging.exception('Some message')与python的标准日志记录模块一起使用时got_request_exception,如果要查找的是注销堆栈跟踪,则可以在sginal处理程序中很好地工作。换句话说,仍可使用追溯got_request_exception
TM。

传递给process_exception的异常似乎没有堆栈跟踪,是否有办法获取?
尼克·

79

如前所述,Django Sentry是一个不错的选择,但是要正确设置它(作为一个单独的网站)需要进行一些工作。如果您只想将所有内容记录到一个简单的文本文件中,请在此处输入以下记录配置settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/django/myapp.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}

我同意,我爱哨兵!我想要一个.Net端口(最近在.Net项目上工作)。
Gromer '04

1
万一有人剪切和粘贴时的小错字:最后用“传播”代替“传播”。
user1228295 2012年

3
'include_html': True不仅使电子邮件变得“更黑”!它包括完整的追溯,包括设置和局部变量的值。根据文档,这是一个安全问题: docs.djangoproject.com/en/1.8/topics/logging / ...
Thomas,

1
我很好奇,是否有必要使用mail_admins处理程序(和django.request记录器),因为您有'disable_existing_loggers':False,并且只是使用此处理程序(和记录器)复制默认的django日志记录。我会在测试后更新。
DylanYoung '16

请更新此答案。从django1.9 change-log开始:Django的默认日志记录配置不再定义'django.request'和'django.security'记录器。
narendra-choudhary



15

自EMP提交最有用的代码以来,已经过去了一段时间。我刚刚实现了它,并在尝试使用一些manage.py选项进行尝试以查找错误时,我收到了弃用警告,以表明在当前版本的Django(1.5。?)中,现在需要require_debug_false过滤器mail_admins处理程序所需。

这是修改后的代码:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
         'require_debug_false': {
             '()': 'django.utils.log.RequireDebugFalse'
         }
     },
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
            'filters': ['require_debug_false'],
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/home/username/public_html/djangoprojectname/logfilename.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'DEBUG', # Or maybe INFO or WARNING
            'propagate': False
        },
    },
}

我很好奇,是否有必要使用mail_admins处理程序(和django.request记录器),因为您有'disable_existing_loggers':False,并且只是使用此处理程序(和记录器)复制默认的django日志记录。我会在测试后更新。
DylanYoung '16

1

我的fcgi脚本有一个烦人的问题。它发生在django开始之前。缺少伐木非常痛苦。无论如何,将stderr重定向到文件作为第一件事很有帮助:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.