【问题标题】:Print a stack trace to stdout on errors in Django while using manage.py runserver在使用 manage.py runserver 时将堆栈跟踪打印到标准输出上的 Django 错误
【发布时间】:2021-12-09 08:36:04
【问题描述】:

我做了一些搜索,但我想知道是否有人有一个日志配置的 sn-p 来让 Django 在遇到请求期间出错。这专门用于本地开发/调试,主要用于当我执行 AJAX 发布请求时,我必须查看 Firebug 中的 HTML 以确定错误发生在哪一行。

【问题讨论】:

  • “终端窗口”?你正在运行django-admin.py runserver
  • 是的,manage.py runserver 本地,但这对生产也有帮助,虽然我会收到电子邮件,所以问题不大。
  • “生产”方法取决于您与 Apache 的集成方式,因此您需要提供有关该配置的更多详细信息以确保我们理解。
  • @SLott 好点,现在我将编辑这个问题,专门针对本地开发。感谢您指出这一点。

标签: python django


【解决方案1】:

另一种方法是使用 LOGGING。具体来说,通过将以下内容添加到 settings.py 文件中,您可以在运行 ./manage.py runserver 时获得堆栈跟踪:

LOGGING = {
    'version': 1,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.request': {
            'handlers':['console'],
            'propagate': True,
            'level':'DEBUG',
        }
    },
}

此语法来自 Django 文档Configuring Logging,可以进一步修改以增加或减少控制台日志记录的数量。

此外,5XX 响应作为错误消息引发,4XX 响应作为警告消息引发。

请注意,此问题和答案在 2013 年有重复的 here

【讨论】:

  • 我认为这应该是首选方法。您可以更好地控制要使用的记录器、要记录的内容等。
  • 迄今为止最干净的解决方案。我建议将此答案标记为最终答案。
  • 终于找到了我想要的东西!
【解决方案2】:

奇怪的是没有人提到DEBUG_PROPAGATE_EXCEPTIONS 设置。它不适用于生产,但在测试/调试环境中非常容易使用。只需添加到settings.py

DEBUG_PROPAGATE_EXCEPTIONS = True

【讨论】:

  • 这似乎是最合适的答案:)
  • +1 值得,经过几个小时调试 DRF 问题并且没有更多的测试/选项可以尝试,你真的拯救了我的一天......
  • 这绝对应该是公认的答案,非常感谢!
  • 这与在其他答案中使用 LOGGING json 项有什么区别?
  • @Jay 使用 LOGGING 你可能会打开来自应用程序不同位置的大量日志消息。在生产环境中,这显然是最正确的方法。但是对于快速而肮脏的调试,应该只将异常打印到控制台。
【解决方案3】:

您可以创建一个中间件来执行此操作。这是我用于项目的修改后的 sn-p:

class ExceptionLoggingMiddleware(object):
    def process_exception(self, request, exception):
        import traceback
        print traceback.format_exc()

将此处理程序放在 Django 设置的中间件部分。

【讨论】:

    【解决方案4】:

    我遇到了类似的问题,但中间件选项对我没有帮助。原因是我正在使用 django-jsonview 0.4.3,它提供了一个装饰器,可以将字典转换为有效的 json http 响应,即使装饰函数失败,所以永远不会调用 process_exception 中间件方法。我检查了这个装饰器的代码,它似乎试图记录错误:

    ...
    except Exception as e:
        logger = logging.getLogger('django.request')
        logger.exception(unicode(e))
    

    但是,我不知道为什么,这不起作用,并且我的 bash 控制台中没有任何记录。我应该找出为什么会发生这种情况。同时,我正在使用一个额外的装饰器:

    def log_errors(func):
        if not settings.DEBUG:
            return func
    
        def wrapper(request, *args, **kwargs):
            try:
                return func(request, *args, **kwargs)
            except:
                print traceback.format_exc()
        return wrapper
    

    然后,在我所有的 json 视图中:

    @json_view
    @log_errors
    def my_view(request):
        ....
    

    【讨论】:

      【解决方案5】:

      我通常用这个:

          except Exception,e:
              # Get line
              trace=traceback.extract_tb(sys.exc_info()[2])
              # Add the event to the log
              output ="Error in the server: %s.\n" % (e)
              output+="\tTraceback is:\n"
              for (file,linenumber,affected,line)  in trace:
                  output+="\t> Error at function %s\n" % (affected)
                  output+="\t  At: %s:%s\n" % (file,linenumber)
                  output+="\t  Source: %s\n" % (line)
              output+="\t> Exception: %s\n" % (e)
      

      然后我将“输出”用于我需要的任何东西:打印到标准输出、发送电子邮件等......

      【讨论】:

      • 我认为这里有更好的答案,但也值得指出的是,您不妨直接调用import traceback; traceback.print_exc() 而不是这么多行。
      • 以你的方式你无法对异常做任何事情,所以我仍然更喜欢我的,因为它更灵活并且是使用的示例:文件名、行号和产生的代码行例外。
      【解决方案6】:

      子类 WSGI 处理程序,在定义的handle_uncaught_exception 中使用回溯做任何你想做的事情,并在部署时使用你的 WSGIHandler 而不是 django 提供的那个。

      import traceback
      from django.core.handlers.wsgi import WSGIHandler
      
      class MyWSGIHandler(WSGIHandler):
          """WSGI Handler which prints traceback to stderr"""
          def handle_uncaught_exception(self, request, resolver, exc_info):
              traceback.print_tb(exc_info[2], file=sys.stderr)
              return super(WSGIHandler, self).handle_uncaught_exception(request, resolver, exc_info)
      

      与 Apache/mod_wsgi 一起使用,这应该在 Apache 的错误日志中写回溯

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-29
        • 2012-09-05
        • 2015-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多