Estoy usando Python Requests . Necesito depurar alguna OAuth
actividad, y para eso me gustaría registrar todas las solicitudes que se realizan. Podría obtener esta información ngrep
, pero desafortunadamente no es posible grep conexiones https (que son necesarias para OAuth
)
¿Cómo puedo activar el registro de todas las URL (+ parámetros) a las que Requests
está accediendo?
python
logging
python-requests
blueFast
fuente
fuente
Respuestas:
La
urllib3
biblioteca subyacente registra todas las nuevas conexiones y URL con ellogging
módulo , pero no losPOST
cuerpos. ParaGET
solicitudes esto debería ser suficiente:que le brinda la opción de registro más detallada; ver el COMO de registro para obtener más detalles sobre cómo configurar los niveles y destinos de registro.
Demostración corta:
Dependiendo de la versión exacta de urllib3, se registran los siguientes mensajes:
INFO
: RedireccionamientosWARN
: Grupo de conexiones lleno (si esto sucede, a menudo aumente el tamaño del grupo de conexiones)WARN
: Error al analizar los encabezados (encabezados de respuesta con formato no válido)WARN
: Reintentando la conexiónWARN
: El certificado no coincide con el nombre de host esperadoWARN
: Respuesta recibida con Content-Length y Transfer-Encoding, al procesar una respuesta fragmentadaDEBUG
: Nuevas conexiones (HTTP o HTTPS)DEBUG
: Conexiones perdidasDEBUG
: Detalles de la conexión: método, ruta, versión HTTP, código de estado y longitud de la respuestaDEBUG
: Incrementos de recuento de reintentosEsto no incluye encabezados ni cuerpos.
urllib3
usa lahttp.client.HTTPConnection
clase para hacer el trabajo pesado, pero esa clase no admite el registro, normalmente solo se puede configurar para imprimir en stdout. Sin embargo, puede manipularlo para enviar toda la información de depuración al registro introduciendo unprint
nombre alternativo en ese módulo:La llamada
httpclient_logging_patch()
hace que lashttp.client
conexiones envíen toda la información de depuración a un registrador estándar, por lo que son recogidas porlogging.basicConfig()
:fuente
access_token
en la solicitud de OAuth. Linkedin se queja de una solicitud no autorizada, y quiero verificar si la biblioteca que estoy usando (rauth
además derequests
) envía ese token con la solicitud. Esperaba ver eso como un parámetro de consulta, pero ¿tal vez esté en los encabezados de la solicitud? ¿Cómo puedo obligarurllib3
a que muestre los encabezados también? ¿Y el cuerpo de la solicitud? Para simplificarlo: ¿cómo puedo ver la solicitud COMPLETA ?httplib
. Deseo que se use esa biblioteca en sulogging
lugar; la salida de depuración se escribe directamente en stdout en lugar de permitirle redirigirla a un destino de registro de su elección.Debe habilitar la depuración en el
httplib
nivel (requests
→urllib3
→httplib
).Aquí hay algunas funciones para alternar (
..._on()
y..._off()
) o activarlas temporalmente:Uso de demostración:
Verá la SOLICITUD, incluidos los ENCABEZADOS y DATOS, y la RESPUESTA con ENCABEZADOS pero sin DATOS. Lo único que falta será el response.body que no está registrado.
Fuente
fuente
httplib.HTTPConnection.debuglevel = 1
para obtener los encabezados. ¡Excelente! Pero creo que obtengo los mismos resultados usando solologging.basicConfig(level=logging.DEBUG)
en lugar de sus otras 5 líneas. ¿Me estoy perdiendo de algo? Supongo que podría ser una forma de establecer diferentes niveles de registro para la raíz frente a urllib3, si lo desea.httplib.HTTPConnection.debuglevel = 2
permitirá la impresión del cuerpo POST también.httplib.HTTPConnection.debuglevel = 1
es suficiente @ Mandible79$ curl https://raw.githubusercontent.com/python/cpython/master/Lib/http/client.py |grep debuglevel
es siempredebuglevel > 0
Para aquellos que usan Python 3+
fuente
stdout
. Ejemplo de problema aquí: stackoverflow.com/q/58738195/1090360Al intentar que el sistema de registro de Python (
import logging
) emita mensajes de registro de depuración de bajo nivel, me sorprendió descubrir que dado:que solo
urllib3
usa realmente ellogging
sistema Python :requests
Nohttp.client.HTTPConnection
Nourllib3
siClaro, puede extraer mensajes de depuración
HTTPConnection
configurando:pero estas salidas se emiten simplemente a través de la
print
declaración. Para probar esto, simplemente grep elclient.py
código fuente de Python 3.7 y vea las declaraciones de impresión usted mismo (gracias @Yohann):Es de suponer que redirigir stdout de alguna manera podría funcionar a shoe-horn stdout en el sistema de registro y potencialmente capturarlo, por ejemplo, en un archivo de registro.
Elija el '
urllib3
' registrador no 'requests.packages.urllib3
'Para capturar
urllib3
información de depuración a través dellogging
sistema Python 3 , contrariamente a muchos consejos en Internet, y como señala @MikeSmith, no tendrá mucha suerte interceptando:en su lugar necesitas:
Depurar
urllib3
a un archivo de registroAquí hay un código que registra el
urllib3
funcionamiento en un archivo de registro usando ellogging
sistema Python :el resultado:
Habilitar las
HTTPConnection.debuglevel
declaraciones print ()Si pones
HTTPConnection.debuglevel = 1
obtendrá la impresión de salida de la sentencia de la información adicional bajo nivel jugosa:
Recuerde que esta salida usa
print
y no ellogging
sistema Python , y por lo tanto no se puede capturar usando unalogging
secuencia tradicional o un controlador de archivos (aunque es posible capturar la salida en un archivo redirigiendo stdout) .Combine los dos anteriores: maximice todos los registros posibles en la consola
Para maximizar todos los registros posibles, debe conformarse con la salida de consola / salida estándar con esto:
dando la gama completa de salida:
fuente
Estoy usando Python 3.4, solicitudes 2.19.1:
'urllib3' es el registrador que se obtiene ahora (ya no 'request.packages.urllib3'). El registro básico seguirá ocurriendo sin configurar http.client.HTTPConnection.debuglevel
fuente
Al tener un script o incluso un subsistema de una aplicación para la depuración de un protocolo de red, se desea ver qué pares de solicitud-respuesta son exactamente, incluidas las URL efectivas, los encabezados, las cargas útiles y el estado. Y normalmente no es práctico instrumentar solicitudes individuales en todo el lugar. Al mismo tiempo, existen consideraciones de desempeño que sugieren el uso de una sola (o pocas especializadas)
requests.Session
, por lo que lo siguiente supone que se sigue la sugerencia .requests
admite los llamados ganchos de eventos (a partir de 2.23 en realidad solo hayresponse
enganches). Es básicamente un detector de eventos y el evento se emite antes de devolver el controlrequests.request
. En este momento, tanto la solicitud como la respuesta están completamente definidas, por lo que se pueden registrar.Así es básicamente cómo registrar todos los viajes de ida y vuelta HTTP de una sesión.
Formateo de registros de registro de ida y vuelta HTTP
Para que el registro anterior sea útil, puede haber un formateador de registro especializado que comprenda
req
yres
haga extras en los registros de registro. Puede verse así:Ahora, si haces algunas solicitudes usando el
session
, como:La salida
stderr
se verá de la siguiente manera.Una forma de GUI
Cuando tienes muchas consultas, tener una interfaz de usuario simple y una forma de filtrar registros resulta útil. Mostraré el uso de Chronologer para eso (del cual soy autor).
Primero, el gancho se ha reescrito para producir registros que
logging
puedan serializarse cuando se envían por cable. Puede verse así:En segundo lugar, la configuración de registro debe adaptarse para su uso
logging.handlers.HTTPHandler
(lo que Chronologer entiende).Finalmente, ejecute la instancia de Chronologer. por ejemplo, usando Docker:
Y vuelva a ejecutar las solicitudes:
El controlador de flujo producirá:
Ahora, si abre http: // localhost: 8080 / (use "logger" para el nombre de usuario y la contraseña vacía para la ventana emergente de autenticación básica) y hace clic en el botón "Abrir", debería ver algo como:
fuente
Estoy usando un
logger_config.yaml
archivo para configurar mi registro, y para que aparezcan esos registros, todo lo que tenía que hacer era agregar undisable_existing_loggers: False
al final.Mi configuración de registro es bastante extensa y confusa, por lo que ni siquiera conozco una buena manera de explicarlo aquí, pero si alguien también está usando un archivo YAML para configurar su registro, esto podría ayudar.
https://docs.python.org/3/howto/logging.html#configuring-logging
fuente