一个django中间件,记录慢请求的回溯。
dogslow的Python项目详细描述
安装
安装dogslow:
$ pip install dogslow
然后将dogslow.WatchdogMiddleware添加到 您的django settings.py文件:
MIDDLEWARE_CLASSES = ( 'dogslow.WatchdogMiddleware', ... )
它还可以用作django 2.0风格的中间件功能:
MIDDLEWARE = ( 'dogslow.WatchdogMiddleware', ... )
为了获得最佳效果,请将其作为第一批运行的中间产品之一。
配置
您可以在^{tt2}中使用以下配置属性$ 要调谐监视程序的文件:
# Watchdog is enabled by default, to temporarily disable, set to False: DOGSLOW = True # By default, Watchdog will create log files with the backtraces. # You can also set the location of where it stores them: DOGSLOW_LOG_TO_FILE = True DOGSLOW_OUTPUT = '/tmp' # Log requests taking longer than 25 seconds: DOGSLOW_TIMER = 25 # When both specified, emails backtraces: # (DOGSLOW_EMAIL_TO can also be a list of addresses) DOGSLOW_EMAIL_TO = 'errors@atlassian.com' DOGSLOW_EMAIL_FROM = 'no-reply@atlassian.com' # Also log to this logger (defaults to none): DOGSLOW_LOGGER = 'syslog_logger' DOGSLOW_LOG_LEVEL = 'WARNING' # Tuple of url pattern names that should not be monitored: # (defaults to none -- everything monitored) # Note: this option is not compatible with Django < 1.3 DOGSLOW_IGNORE_URLS = ('some_view', 'other_view') # Print (potentially huge!) local stack variables (off by default, use # True for more detailed, but less manageable reports) DOGSLOW_STACK_VARS = True
用法
每个传入的http请求都会在监视程序中获得25秒的超时。如果 请求在该时间内未返回,监视程序将激活并获取 查看请求线程的堆栈并写入回溯(包括所有 本地堆栈变量–django样式)到日志文件。
每个慢速请求都记录在一个单独的文件中,该文件如下所示:
Undead request intercepted at: 16-05-2011 02:10:12 UTC GET http://localhost:8000/?delay=2 Thread ID: 140539485042432 Process ID: 18010 Started: 16-05-2011 02:10:10 UTC File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 107, in inner_run run(self.addr, int(self.port), handler, ipv6=self.use_ipv6) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 696, in run httpd.serve_forever() File "/usr/lib/python2.7/SocketServer.py", line 227, in serve_forever self._handle_request_noblock() File "/usr/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock self.process_request(request, client_address) File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request self.finish_request(request, client_address) File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request self.RequestHandlerClass(request, client_address, self) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 570, in __init__ BaseHTTPRequestHandler.__init__(self, *args, **kwargs) File "/usr/lib/python2.7/SocketServer.py", line 639, in __init__ self.handle() File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 615, in handle handler.run(self.server.get_app()) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 283, in run self.result = application(self.environ, self.start_response) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__ return self.application(environ, start_response) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 273, in __call__ response = self.get_response(request) File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/home/erik/work/middleware/middleware/sleep/views.py", line 6, in sleep time.sleep(float(request.GET.get('delay', 1))) Full backtrace with local variables: File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 107, in inner_run run(self.addr, int(self.port), handler, ipv6=self.use_ipv6) ...loads more...
上面的示例显示请求线程在 time.sleep()在dogslow拍摄快照时。
在dogslow超时过期之前返回的请求不会被记录。
注意dogslow只查看线程的堆栈。它没有 中断请求,或以任何其他方式影响请求。使用dogslow是 因此在生产中使用是安全的。
岗哨整合
多格斯洛天生就和哨兵结合在一起。您可以通过配置 dogslow使用DOGSLOW_LOGGER和DOGSLOW_LOG_TO_SENTRY和 configuring Raven收集Dogslow的报告。
DOGSLOW_LOGGER = 'dogslow' # can be anything, but must match `logger` below DOGSLOW_LOG_TO_SENTRY = True DOGSLOW_LOG_LEVEL = 'WARNING' # optional, defaults to 'WARNING' # Add a new sentry handler to handle WARNINGs. It's not recommended to # modify the existing sentry handler, as you'll probably start seeing # other warnings unnecessarily sent to Sentry. LOGGING = { ... 'handlers': { ... 'dogslow': { 'level': 'WARNING', 'class': 'raven.contrib.django.handlers.SentryHandler', } ... } 'loggers': { ... 'dogslow': { 'level': 'WARNING', 'handlers': ['dogslow'], # or whatever you named your handler } ... } ... }
注意事项
dogslow使用多线程。它有一个单独的后台线程来处理 监视程序超时并接受回溯,以便原始请求 线程不会中断。这有一些后果。
多线程和gil
在cpython中,gil(全局解释器锁)防止多个线程 同时执行python代码。只有当线程显式释放 它的锁在gil上,可以有第二个线程运行。
每当python程序 阻止解释器外部的调用,例如在执行IO时。
对于dogslow,这意味着它只能可靠地拦截 很慢,因为他们正在进行IO、呼叫睡眠或忙着等待获取 自锁。
在大多数情况下这是好的。Django请求缓慢的一个重要原因是 昂贵的数据库查询。因为这是io,dogslow可以截获那些 好的。cpython的gil有问题的场景是 线程在python代码(或合法的python,即 非常昂贵,需要很长时间来执行),从不释放 吉尔。尽管dogslow的看门狗计时器线程确实可以运行,但是 无法记录堆栈。
联合程序和greenlet
Dogslow用于同步工作机配置。一个 使用专用线程(或单线程专用工作线程)的Web服务器 处理)以满足请求。django的内置wsgi服务器这样做,就像 在默认同步工作模式下,Gunicorn。
当使用“共同例程框架”运行时,其中提供多个请求 同时由一条线,回溯可能会变得毫无意义。