Python Tracebacker

1.3-dev 新版功能.

通常,如果你想要获取你的app的实时回溯,那么你必须修改你的代码,为其添加一个hook或者入口,正如:doc:`TipsAndTricks`页面上描述的。

从1.3-dev开始,uWSGI包括了一个类似的技术,允许你通过一个UNIX socket获取实时回溯。

要启用这个回溯器,你需要添加选项py-tracebacker=&lt;socket&gt;,,其中,``<socket>``是已创建UNIX socket的basename

如果你有4个uWSGI worker,并且添加了py-tracebacker=/tmp/tbsocket,那么将会创建名字从/tmp/tbsocket1/tmp/tbsocket4的4个socket。

连接到其中任意一个都将会返回worker中运行的线程的当前回溯。你可以使用你最喜欢的应用或方法来连接到那些socket,但是uWSGI有一个供你使用的方便的选项connect-and-read

uwsgi –connect-and-read /tmp/tbsocket1

一个例子

让我们写一个名为slow.py的蠢蠢的测试应用:

  1. import time
  2.  
  3. def dormi():
  4. time.sleep(60)
  5.  
  6. def dormi2():
  7. dormi()
  8.  
  9. def dormi3():
  10. dormi2()
  11.  
  12. def dormi4():
  13. dormi3()
  14.  
  15. def dormi5():
  16. dormi4()
  17.  
  18. def application(e, start_response):
  19. start_response('200 OK', [('Content-Type', 'text/html')])
  20. dormi5()
  21. return "hello"

然后运行它:

  1. uwsgi --http :8080 -w slow --master --processes 2 --threads 4 --py-tracebacker /tmp/tbsocket.

然后创建一堆到它的请求:

  1. curl http://localhost:8080 &
  2. curl http://localhost:8080 &
  3. curl http://localhost:8080 &
  4. curl http://localhost:8080 &

现在,当这些请求运行的时候 (每个都会花费几乎一分钟来完成),你就可以检索回溯,比方说,前两个worker:

  1. ./uwsgi --connect-and-read /tmp/tbsocket.1
  2. ./uwsgi --connect-and-read /tmp/tbsocket.2

回溯器的输出将会是这样的:

  1. *** uWSGI Python tracebacker output ***
  2.  
  3. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 22 function = application line = dormi5()
  4. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4()
  5. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3()
  6. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2()
  7. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi()
  8. thread_id = uWSGIWorker1Core1 filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60)
  9.  
  10. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 22 function = application line = dormi5()
  11. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4()
  12. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3()
  13. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2()
  14. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi()
  15. thread_id = uWSGIWorker1Core3 filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60)
  16.  
  17. thread_id = MainThread filename = ./slow.py lineno = 22 function = application line = dormi5()
  18. thread_id = MainThread filename = ./slow.py lineno = 14 function = dormi5 line = def dormi5(): dormi4()
  19. thread_id = MainThread filename = ./slow.py lineno = 13 function = dormi4 line = def dormi4(): dormi3()
  20. thread_id = MainThread filename = ./slow.py lineno = 12 function = dormi3 line = def dormi3(): dormi2()
  21. thread_id = MainThread filename = ./slow.py lineno = 11 function = dormi2 line = def dormi2(): dormi()
  22. thread_id = MainThread filename = ./slow.py lineno = 9 function = dormi line = time.sleep(60)

将回溯器与Harakiri组合在一起

如果一个请求由于:term:`harakiri<Harakiri>`特性而被杀掉,那么在Harakiri阶段,会自动记录回溯。