Dogslow ist Django Watchdog-Middleware-Klasse, die Rückverfolgungen von langsamen Anfragen protokolliert.
Installation:
Installieren dogslow:
pip dogslow installieren
Dann fügen Sie, wenn zu Ihrer Liste der Middleware-Klassen in Ihrem Django settings.py Datei:
MIDDLEWARE_CLASSES = (
& Nbsp; "dogslow.WatchdogMiddleware ',
& Nbsp; ...
)
Die besten Ergebnisse erzielen, machen es zu einem der ersten Middleware, die ausgeführt wird.
Konfiguration:
Sie können die folgenden Konfigurationsmerkmale in Ihrem settings.py Datei stimmen der Watchdog verwenden:
# Watchdog ist standardmäßig aktiviert, um vorübergehend zu deaktivieren, auf False festgelegt:
DOGSLOW = True
# Ort, wo Watchdog speichert die Protokolldateien:
DOGSLOW_OUTPUT = '/ tmp'
# Log-Anfragen, die länger als 25 Sekunden:
DOGSLOW_TIMER = 25
# Wenn beide angegeben, E-Mails Backtraces:
DOGSLOW_EMAIL_TO = 'errors@atlassian.com'
DOGSLOW_EMAIL_FROM = 'no-reply@atlassian.com'
Anwendung:
Jede eingehende HTTP-Anforderung erhält eine 25 Sekunden Zeitüberschreitung in der Watchdog. Wenn eine Anfrage nicht innerhalb dieser Zeit zurück, aktiviert und wirft einen Blick auf Antrag Thread Stapel der Watchdog und schreibt die Rückverfolgung (einschließlich aller lokalen Stack-Variablen - Django-Stil) in eine Protokolldatei.
Jeder Antrag wird langsam in einer separaten Datei, die folgendermaßen aussieht protokolliert:
16-05-2011 02.10.12 UTC: Undead Anfrage abgefangen
GET http: // localhost: 8000 / Verzögerung = 2
Themen-ID: 140539485042432
Prozess-ID: 18010
Eltern PID: 17.762
Schritte: 16-05-2011 02.10.10 UTC
& Nbsp; Datei "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/management/commands/runserver.py", Linie 107, in inner_run
& Nbsp; run (self.addr, int (self.port), Handler, ipv6 = self.use_ipv6)
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", Linie 696, in Lauf
& Nbsp; httpd.serve_forever ()
& Nbsp; Datei "/usr/lib/python2.7/SocketServer.py", Linie 227, in serve_forever
& Nbsp; self._handle_request_noblock ()
& Nbsp; Datei "/usr/lib/python2.7/SocketServer.py", Linie 284, in _handle_request_noblock
& Nbsp; self.process_request (Anfrage, Clientadresse)
& Nbsp; Datei "/usr/lib/python2.7/SocketServer.py", Linie 310, in process_request
& Nbsp; self.finish_request (Anfrage, Clientadresse)
& Nbsp; Datei "/usr/lib/python2.7/SocketServer.py", Linie 323, in finish_request
& Nbsp; self.RequestHandlerClass (Anfrage, Clientadresse, selbst)
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", Linie 570, in __init__
& Nbsp; BaseHTTPRequestHandler .__ init __ (self, * args, ** kwargs)
& Nbsp; Datei "/usr/lib/python2.7/SocketServer.py", Linie 639, in __init__
& Nbsp; self.handle ()
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", Linie 615, in Griff
& Nbsp; handler.run (self.server.get_app ())
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/servers/basehttp.py", Linie 283, in Lauf
& Nbsp; self.result = Anwendung (self.environ, self.start_response)
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", Zeile 68, in __call__
& Nbsp; Rück self.application (environ, start_response)
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/handlers/wsgi.py", Linie 273, in __call__
& Nbsp; response = self.get_response (Anfrage)
& Nbsp; File "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/handlers/base.py", Linie 111, in GET RESPONSE
& Nbsp; response = Rückruf (Anfrage, * callback_args, ** callback_kwargs)
& Nbsp; Datei "/home/erik/work/middleware/middleware/sleep/views.py", Zeile 6, im Schlaf
& Nbsp; time.sleep (float (request.GET.get ("Verspätung", 1)))
Vollständige Rückverfolgung mit lokalen Variablen:
& Nbsp; Datei "/home/erik/work/virtualenv/bit/lib/python2.7/site-packages/django/core/management/commands/runserver.py", Linie 107, in inner_run
& Nbsp; run (self.addr, int (self.port), Handler, ipv6 = self.use_ipv6)
& Nbsp; ... Lasten mehr ...
Das obige Beispiel zeigt, dass der Antrag Faden wurde in time.sleep () zum Zeitpunkt dogslow nahm seinen Schnappschuss blockiert.
Ersuchen, die vor dogslow der Timeout abgelaufen ist zurück nicht protokolliert werden.
Beachten Sie, dass dogslow dauert nur einen Blick auf der Thread-Stack. Es muss nicht die Anforderung unterbrechen oder beeinflussen in anderer Weise. Mit dogslow ist daher sicher in der Produktion zu verwenden.
Vorsichtsmaßnahmen
Dogslow nutzt Multithreading. Es hat einen einzigen Hintergrund Schrauben Sie die Griffe der Watchdog-Zeitüberschreitungen und nimmt die Tracebacks, so dass die ursprüngliche Anfrage Fäden werden nicht unterbrochen. Dies hat einige Konsequenzen.
Multithreading und die GIL
In CPython die GIL (Global Interpreter Lock) verhindert, dass mehrere Threads aus Python-Code gleichzeitig auszuführen. Nur wenn ein Thread explizit gibt seine Sperre auf der GIL, kann eine zweite Fadenlauf.
Loslassen der GIL erfolgt automatisch, wenn ein Python-Programm macht blockieren Anrufe außerhalb des Interpreten, zum Beispiel, wenn dabei IO.
Für dogslow bedeutet dies, dass es können nur zuverlässig abfangen Anfragen, die langsam sind, weil sie tun, IO, ruft schlafen oder beschäftigt warten auf Sperren selbst zu erwerben.
In den meisten Fällen ist dies in Ordnung. Eine wichtige Ursache für langsame Anfragen Django ist eine teure Datenbankabfrage. Da es sich um IO kann dogslow jene feinen abzufangen. Ein Szenario, in dem CPython der GIL ist problematisch ist, wenn der Anforderung Faden trifft eine Endlos-Schleife in Python-Code (oder legitime Python, die sehr teuer ist und dauert eine lange Zeit für die Ausführung), nicht die Freigabe der GIL. Obwohl dogslow der Watchdog-Timer ist lauffähig, kann es sich nicht anmelden den Stapel.
Co-Routinen und Greenlets
Dogslow ist für den Einsatz in einem synchronen Arbeiter Projektierung. Ein Webserver, der engagierten Themen (oder Single-Thread, engagierten Arbeitsprozesse) verwendet, um Anfragen zu bedienen. Djangos eingebaute wsgi Server tut dies, ebenso wie Gunicorn in der Standard Sync-worker-Modus.
Bei der Ausführung mit einer "Co-Routinen Rahmen", in dem mehrere Anfragen gleichzeitig von einem Thread bedient, könnte Backtraces werden unsinnig
Anforderungen .
- Python
- Django
Kommentare nicht gefunden