2013-05-02 9 views
47

Ich verwende Python Requests. Ich muss einige OAuth Aktivität debuggen, und dafür möchte ich, dass es alle Anforderungen protokolliert, die ausgeführt werden. Ich konnte diese Informationen mit ngrep, bekommen aber leider ist es nicht möglich, https-Verbindungen grep (die für OAuth benötigt werden)Protokollieren Sie alle Anfragen aus dem Python-Requests-Modul

Wie kann ich Protokollierung aller URLs aktivieren (+ Parameter), dass Requests zugreift?

+0

Die Antwort von @yohann zeigt, wie noch mehr Logging-Ausgabe erhalten, einschließlich der Header Sie senden. Es sollte die akzeptierte Antwort sein, nicht die von Martijn, die nicht die Header zeigt, die Sie über wireshark erhalten und stattdessen eine Anfrage manuell angepasst haben. – nealmcb

Antwort

40

Die zugrunde liegende Bibliothek urllib3 protokolliert alle neuen Verbindungen und URLs mit den logging module, aber nicht POST Körpern. Für GET Anfragen sollte dies ausreichen:

import logging 

logging.basicConfig(level=logging.DEBUG) 

, die Ihnen die ausführliche Protokollierung Option gibt; Weitere Informationen zum Konfigurieren von Protokollierstufen und Zielen finden Sie unter logging HOWTO.

Kurze Demo:

>>> import requests 
>>> import logging 
>>> logging.basicConfig(level=logging.DEBUG) 
>>> r = requests.get('http://httpbin.org/get?foo=bar&baz=python') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
DEBUG:requests.packages.urllib3.connectionpool:"GET /get?foo=bar&baz=python HTTP/1.1" 200 353 

Die folgenden Meldungen protokolliert werden:

  • INFO: Neue Verbindungen (HTTP oder HTTPS)
  • INFO: Dropped Verbindungen
  • INFO: Leitet
  • WARN: Anschluss Pool voll ist (wenn dies geschieht oft die Verbindung Pool-Größe erhöhen)
  • WARN: Neuer Versuch die Verbindung
  • DEBUG: Anschlussdetails: Methode, Pfad, HTTP-Version, Statuscode und Antwortlänge
+0

Seltsamerweise sehe ich das 'access_token' in der OAuth-Anfrage nicht.Linkedin beschwert sich über nicht autorisierte Anfragen, und ich möchte überprüfen, ob die Bibliothek, die ich benutze ('rauth' oben auf' Anfragen') dieses Token mit der Anfrage sendet. Ich habe erwartet, dass dies als Abfrageparameter angezeigt wird, aber möglicherweise in den Anforderungsheadern? Wie kann ich das 'urllib3' zwingen, die Überschriften auch zu zeigen? Und der Anfragekörper? Um es einfach zu machen: Wie kann ich die ** FULL ** Anfrage sehen? – dangonfast

+0

Sie können das nicht ohne Patchen tun, fürchte ich. Die gebräuchlichste Art solche Probleme zu diagnostizieren ist mit einem Proxy oder Paket Logger (Ich benutze wireshark, um vollständige Anfragen und Antworten selbst zu erfassen). Ich sehe, dass Sie eine neue Frage zu diesem Thema gestellt haben. –

+1

Sicher, ich debugge jetzt mit Wireshark, aber ich habe ein Problem: Wenn ich HTTP, sehe ich den vollen Paketinhalt, aber Linkedin gibt 401, was erwartet wird, da Linkedin sagt, https zu verwenden. Aber mit https funktioniert es auch nicht und ich kann es nicht debuggen, da ich die TLS Schicht mit wireshark nicht überprüfen kann. – dangonfast

63

Sie müssen das Debugging unter httplib (requestsurllib3httplib) aktivieren.

Hier einige Funktionen sowohl Knebel (..._on() und ..._off()) oder haben sie vorübergehend auf:

import logging 
import contextlib 
try: 
    from http.client import HTTPConnection # py3 
except ImportError: 
    from httplib import HTTPConnection # py2 

def debug_requests_on(): 
    '''Switches on logging of the requests module.''' 
    HTTPConnection.debuglevel = 1 

    logging.basicConfig() 
    logging.getLogger().setLevel(logging.DEBUG) 
    requests_log = logging.getLogger("requests.packages.urllib3") 
    requests_log.setLevel(logging.DEBUG) 
    requests_log.propagate = True 

def debug_requests_off(): 
    '''Switches off logging of the requests module, might be some side-effects''' 
    HTTPConnection.debuglevel = 0 

    root_logger = logging.getLogger() 
    root_logger.setLevel(logging.WARNING) 
    root_logger.handlers = [] 
    requests_log = logging.getLogger("requests.packages.urllib3") 
    requests_log.setLevel(logging.WARNING) 
    requests_log.propagate = False 

@contextlib.contextmanager 
def debug_requests(): 
    '''Use with 'with'!''' 
    debug_requests_on() 
    yield 
    debug_requests_off() 

Demo Verwendung:

>>> requests.get('http://httpbin.org/') 
<Response [200]> 

>>> debug_requests_on() 
>>> requests.get('http://httpbin.org/') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
DEBUG:requests.packages.urllib3.connectionpool:"GET/HTTP/1.1" 200 12150 
send: 'GET/HTTP/1.1\r\nHost: httpbin.org\r\nConnection: keep-alive\r\nAccept- 
Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.11.1\r\n\r\n' 
reply: 'HTTP/1.1 200 OK\r\n' 
header: Server: nginx 
... 
<Response [200]> 

>>> debug_requests_off() 
>>> requests.get('http://httpbin.org/') 
<Response [200]> 

>>> with debug_requests(): 
...  requests.get('http://httpbin.org/') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
... 
<Response [200]> 

Sie das REQUEST, einschließlich HEADERS und Daten, und RESPONSE mit HEADERS aber ohne DATA. Das einzige, was fehlt, ist der response.body, der nicht eingeloggt ist.

Source

+0

Vielen Dank für den Einblick über die Verwendung von 'httplib.HTTPConnection.debuglevel = 1' zu bekommen die Header - ausgezeichnet! Aber ich denke, ich bekomme die gleichen Ergebnisse mit nur 'logging.basicConfig (level = logging.DEBUG)' anstelle der anderen 5 Zeilen. Fehle ich etwas? Ich denke, es könnte eine Möglichkeit sein, verschiedene Protokollierungsstufen für den Stamm vs. urllib3 festzulegen, falls gewünscht. – nealmcb

+0

Sie haben nicht den Header mit Ihrer Lösung. – Yohann

+5

'httplib.HTTPConnection.debuglevel = 2' ermöglicht das Drucken von POST-Textstellen. – Mandible79

21

Für diejenigen Python mit 3+

import requests 
import logging 
import http.client 

http.client.HTTPConnection.debuglevel = 1 

logging.basicConfig() 
logging.getLogger().setLevel(logging.DEBUG) 
requests_log = logging.getLogger("requests.packages.urllib3") 
requests_log.setLevel(logging.DEBUG) 
requests_log.propagate = True 
Verwandte Themen