在Gunicorn超时转储Django堆栈跟踪

时间:2013-03-15 21:26:35

标签: django gunicorn

我正在尝试调试Django应用程序的罕见挂起。到目前为止,我没有找到问题所在,它每天都会在生产中发生一次,而Gunicorn会重新启动这个过程并发出一条消息:

[CRITICAL] WORKER TIMEOUT

有没有办法配置Django或Gunicorn来转储重启进程的堆栈跟踪?

3 个答案:

答案 0 :(得分:5)

尝试将您的Gunicorn日志设置为更详细,可以将其设置为INFODEBUG,这可能会在日志中显示更多亮光。

您还可以查看Dog Slow,它会记录缓慢的请求。 https://pypi.python.org/pypi/dogslow

对于一般日志记录获胜,请尝试使用Sentry:https://www.getsentry.com/welcome/

随机问题,当时正在运行的服务器上的任何crons,备份,那种事情?

答案 1 :(得分:0)

超时并不意味着请求超时。这意味着工人的生活检查。对于同步工作程序,这用作请求超时,因为除了处理请求之外,工作人员不能执行任何操作。异步工作者即使在处理长时间运行的请求时也会发出心跳,因此除非工作人员阻塞/冻结,否则它将不会被杀死。

Gunicorn有一个名为worker_abort的函数(参见下面的gunicorn文档)。

def worker_abort(worker):
    worker.log.info("worker received abort signal")
    import threading, sys, traceback
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
    code = []
    for threadId, stack in sys._current_frames().items():
        code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId))
        stack = traceback.extract_stack(stack)
        for filename, lineno, name, line in stack:
            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
            if line:
                code.append("  %s" % (line.strip()))
    worker.log.debug("\n".join(code))

当工人收到SIGABRT信号时调用。此调用通常在超时时发生。 callable需要为初始化的Worker接受一个实例变量。

来源:

http://docs.gunicorn.org/en/stable/settings.htmlhttps://github.com/benoitc/gunicorn/issues/1493https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py

答案 2 :(得分:0)

这将在工人被杀死时为其打印堆栈跟踪。您需要创建一个gunicorn config file,然后将以下函数粘贴到其中。

def worker_abort(worker):
    import traceback, io
    debug_info = io.StringIO()
    debug_info.write("Traceback at time of timeout:\n")
    traceback.print_stack(file=debug_info)
    worker.log.critical(debug_info.getvalue())

(我只在Python 3上进行过测试。如果您使用Python 2,则需要将io更改为StringIO。请参见StringIO in Python3