¿Cómo deshabilito los mensajes de registro de la biblioteca de solicitudes?

367

Por defecto, la biblioteca de Python Solicitudes escribe mensajes de registro en la consola, en la línea de:

Starting new HTTP connection (1): example.com
http://example.com:80 "GET / HTTP/1.1" 200 606

Por lo general, no estoy interesado en estos mensajes y me gustaría deshabilitarlos. ¿Cuál sería la mejor manera de silenciar esos mensajes o disminuir la verbosidad de las solicitudes?

aknuds1
fuente
Relacionado: nginx y gunicorn
Martin Thoma

Respuestas:

574

Descubrí cómo configurar el nivel de registro de las solicitudes , se realiza a través del módulo de registro estándar . Decidí configurarlo para no registrar mensajes a menos que sean al menos advertencias:

import logging

logging.getLogger("requests").setLevel(logging.WARNING)

Si también desea aplicar esta configuración para la biblioteca urllib3 (normalmente utilizada por solicitudes), agregue lo siguiente:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
fuente
44
Tengo el mismo problema con pysimplesoap, y esta respuesta me ayuda a salvar mi día
Janith Chinthana
2
Puede combinar las dos líneas de esta manera: logging.getLogger ('peticiones'). SetLevel (logging.WARNING)
jpoppe
77
Tuve que agregar esta línea para el registrador "urllib3" para suprimir los mensajes de registro de solicitudes.
dgassaway
99
Tenía que importar el registro; logging.getLogger ("urllib3"). setLevel (logging.WARNING), también. El registrador para "solicitudes" no impide estos mensajes.
m_messiah
44
Por alguna razón al usar la biblioteca de solicitudes en python3, debe hacer getLogger("urllib3")para suprimir los mensajes.
robru
104

En caso de que haya venido buscando una forma de modificar el registro de cualquier módulo (posiblemente profundamente anidado), use logging.Logger.manager.loggerDict para obtener un diccionario de todos los objetos del registrador. Los nombres devueltos se pueden usar como argumento para logging.getLogger:

import requests
import logging
for key in logging.Logger.manager.loggerDict:
    print(key)
# requests.packages.urllib3.connectionpool
# requests.packages.urllib3.util
# requests.packages
# requests.packages.urllib3
# requests.packages.urllib3.util.retry
# PYREADLINE
# requests
# requests.packages.urllib3.poolmanager

logging.getLogger('requests').setLevel(logging.CRITICAL)
# Could also use the dictionary directly:
# logging.Logger.manager.loggerDict['requests'].setLevel(logging.CRITICAL)

Por usuario136036 en un comentario, tenga en cuenta que este método solo le muestra los registradores que existen en el momento en que ejecuta el fragmento anterior. Si, por ejemplo, un módulo crea un nuevo registrador cuando crea una instancia de una clase, debe colocar este fragmento después de crear la clase para imprimir su nombre.

kbrose
fuente
3
Gracias, esto me ayudó a silenciar los urllib3mensajes de registro al usar boto3. El registrador en tal caso es botocore.vendored.requests.packages.urllib3, así que usé esto: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)y finalmente me deshice de los mensajes.
Bob Dem
Muchas gracias por esto! La alteración de los criterios de impresión me permitió aislar que python-elasticsearch era el culpable en mi caso.
Robert Townley
2
Tenga en cuenta que esto no funcionará cuando los módulos creen sus registradores dentro de su clase a la que llamaría más tarde, como lo APSchedulerhace cuando llama BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: los objetos de registro son singletons, no importa si usted o la biblioteca pueden crearlos primero. Si usa exactamente el mismo nombre que usa la biblioteca, funcionará .
Martijn Pieters
1
Creo que dicen que si enumera los registradores antes de que una biblioteca haya creado su registrador, entonces no aparecerá en la lista. Cual es correcta.
kbrose
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

De esta forma, todos los mensajes de level = INFO de urllib3 no estarán presentes en el archivo de registro.

Para que pueda seguir usando el nivel = INFO para sus mensajes de registro ... simplemente modifique esto para la biblioteca que está utilizando.

Shaolin
fuente
44
Sugiero usar setLevel(logging.WARNING)para registrar también posibles mensajes de advertencia y error.
razz0
14

Permítame copiar / pegar la sección de documentación sobre la que escribí hace una o dos semanas, después de tener un problema similar al suyo:

import requests
import logging

# these two lines enable debugging at httplib level (requests->urllib3->httplib)
# you will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# the only thing missing will be the response.body which is not logged.
import httplib
httplib.HTTPConnection.debuglevel = 1

logging.basicConfig() # you need to initialize logging, otherwise you will not see anything from requests
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

requests.get('http://httpbin.org/headers')
sorin
fuente
Sin embargo, ¿qué sentido tiene ser más específico que solo "solicitudes", desde un punto de vista práctico?
aknuds1
Pero, ¿qué gana llamando a logging.getLogger ("peticiones.packages.urllib3") en lugar de logging.getLogger ("solicitudes"), considerando que desea afectar el registro de la biblioteca de solicitudes?
aknuds1
¿Quiere decir que desea habilitar el registro dentro de request.packages.urllib3? Si es así, estás respondiendo la pregunta equivocada.
aknuds1
@ aknuds1 Depende de usted si desea deshabilitarlos o habilitarlos, solo pongo el código que controla completamente esto :)
sorin
3
Creo que has entendido mal el alcance de la pregunta.
aknuds1
14

Para cualquiera que lo use logging.config.dictConfig, puede modificar el nivel de registro de la biblioteca de solicitudes en el diccionario de esta manera:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
fuente
@SebastianWagner Django usa dictConfigbajo el capó.
uhbif19
Muchas gracias! Esto es bastante bueno ¡Un lugar para gobernar todos los registros de la biblioteca! :)
MehmedB
5

Establecer el nombre del registrador como requestso requests.urllib3no funcionó para mí. Tuve que especificar el nombre exacto del registrador para cambiar el nivel de registro.

Primero vea qué registradores ha definido, para ver cuáles desea eliminar

print(logging.Logger.manager.loggerDict)

Y verás algo como esto:

{...'urllib3.poolmanager': <logging.Logger object at 0x1070a6e10>, 'django.request': <logging.Logger object at 0x106d61290>, 'django.template': <logging.Logger object at 0x10630dcd0>, 'django.server': <logging.Logger object at 0x106dd6a50>, 'urllib3.connection': <logging.Logger object at 0x10710a350>,'urllib3.connectionpool': <logging.Logger object at 0x106e09690> ...}

Luego configure el nivel para el registrador exacto:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
fuente
¿Dónde se establecen estos niveles?
javadba
Los tengo en la configuración de Django, en base.py. Dónde colocarlos, por supuesto, depende de la configuración de su proyecto.
Mikko
2

Si tiene un archivo de configuración, puede configurarlo.

Agregue urllib3 en la sección de registradores:

[loggers]
keys = root, urllib3

Añadir logger_urllib3 sección:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Se hundió
fuente
Esta es una respuesta perfectamente válida para las personas que usan el archivo de configuración. ¿No está seguro de por qué obtuvo tantos votos negativos?
Patrick
1

Esta respuesta está aquí: Python: ¿cómo suprimir las declaraciones de registro de bibliotecas de terceros?

Puede dejar el nivel de registro predeterminado para basicConfig, y luego establecer el nivel de DEPURACIÓN cuando obtiene el registrador para su módulo.

logging.basicConfig(format='%(asctime)s %(module)s %(filename)s:%(lineno)s - %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

logger.debug("my debug message")
Geoffrey Ritchey
fuente
1
import logging

# Only show warnings
logging.getLogger("urllib3").setLevel(logging.WARNING)

# Disable all child loggers of urllib3, e.g. urllib3.connectionpool
logging.getLogger("urllib3").propagate = False
Martin Thoma
fuente
0

La guía de Kbrose para encontrar qué registrador estaba generando mensajes de registro fue inmensamente útil. Para mi proyecto Django, tuve que clasificar 120 registradores diferentes hasta que descubrí que era la elasticsearchbiblioteca Python la que me causaba problemas. Según la guía en la mayoría de las preguntas, lo desactivé agregando esto a mis registradores:

      ...
      'elasticsearch': {
          'handlers': ['console'],
          'level': logging.WARNING,
      },     
      ...

Publicar aquí en caso de que alguien más vea que aparecen mensajes de registro inútiles cada vez que ejecutan una consulta Elasticsearch.

Robert Townley
fuente
-1

simple: solo agregue requests.packages.urllib3.disable_warnings()despuésimport requests

evandrix
fuente
2
No encontré este método en mi versión. Deshabilitar las advertencias es excesivo, ya que los mensajes molestos están nivelados INFO.
tripleee
-1

No estoy seguro de si los enfoques anteriores han dejado de funcionar, pero en cualquier caso, aquí hay otra forma de eliminar las advertencias:

PYTHONWARNINGS="ignore:Unverified HTTPS request" ./do-insecure-request.py

Básicamente, agregar una variable de entorno en el contexto de la ejecución del script.

De la documentación: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

newlog
fuente