Comment désactiver les messages de journal de la bibliothèque de demandes?

367

Par défaut, la bibliothèque python Requests écrit des messages de journal dans la console, sur le modèle de:

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

Je ne suis généralement pas intéressé par ces messages et je voudrais les désactiver. Quelle serait la meilleure façon de faire taire ces messages ou de réduire la verbosité des demandes?

aknuds1
la source
EN RELATION
Martin Thoma

Réponses:

574

J'ai découvert comment configurer le niveau de journalisation des requêtes , cela se fait via le module de journalisation standard . J'ai décidé de le configurer pour ne pas enregistrer les messages à moins qu'ils ne soient au moins des avertissements:

import logging

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

Si vous souhaitez également appliquer ce paramètre à la bibliothèque urllib3 (généralement utilisée par les requêtes), ajoutez ce qui suit:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
la source
4
J'ai le même problème pysimplesoap, et cette réponse m'aide à sauver ma journée
Janith Chinthana
2
Vous pouvez combiner les deux lignes comme ceci: logging.getLogger ('demandes'). SetLevel (logging.WARNING)
jpoppe
7
J'ai dû ajouter cette ligne pour que l'enregistreur "urllib3" supprime les messages du journal des demandes.
dgassaway
9
J'avais besoin d'importer la journalisation; logging.getLogger ("urllib3"). setLevel (logging.WARNING) également. L'enregistreur pour les "demandes" n'empêche pas ces messages.
m_messiah
4
Pour une raison quelconque, lorsque vous utilisez la bibliothèque de demandes en python3, vous devez faire getLogger("urllib3")pour supprimer les messages.
robru
104

Si vous êtes venu ici à la recherche d'un moyen de modifier la journalisation de n'importe quel module (éventuellement profondément imbriqué), utilisez logging.Logger.manager.loggerDictpour obtenir un dictionnaire de tous les objets de journalisation. Les noms retournés peuvent ensuite être utilisés comme argument pour 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)

Par utilisateur136036 dans un commentaire, sachez que cette méthode ne vous montre que les enregistreurs qui existent au moment où vous exécutez l'extrait ci-dessus. Si, par exemple, un module crée un nouvel enregistreur lorsque vous instanciez une classe, vous devez mettre cet extrait après avoir créé la classe afin d'imprimer son nom.

kbrose
la source
3
Merci, cela m'a aidé à faire taire urllib3les messages du journal lors de l'utilisation boto3. L'enregistreur dans ce cas est botocore.vendored.requests.packages.urllib3, donc j'ai utilisé ceci: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)et je me suis finalement débarrassé des messages.
Bob Dem
Merci beaucoup pour ça! La modification des critères d'impression m'a permis d'isoler que python-elasticsearch était le coupable dans mon cas.
Robert Townley
2
Sachez que cela ne fonctionnera pas lorsque les modules créeront leurs enregistreurs dans leur classe que vous appellerez plus tard, comme le APSchedulerfait lorsque vous appelez BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: les objets de journalisation sont des singletons, peu importe si vous ou la bibliothèque commencez par les créer. Si vous utilisez exactement le même nom que celui utilisé par la bibliothèque, cela fonctionnera .
Martijn Pieters
1
Je pense qu'ils disent que si vous répertoriez les enregistreurs avant qu'une bibliothèque ait créé son enregistreur, il ne sera pas répertorié. Qui est correct.
kbrose
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

De cette façon, tous les messages de level = INFO de urllib3 ne seront pas présents dans le fichier journal.

Vous pouvez donc continuer à utiliser le level = INFO pour vos messages de journal ... il suffit de le modifier pour la bibliothèque que vous utilisez.

shaolin
la source
4
Je suggère d'utiliser setLevel(logging.WARNING)pour enregistrer également les éventuels messages d'avertissement et d'erreur.
razz0
14

Permettez-moi de copier / coller la section de documentation que j'ai écrite il y a environ une semaine ou deux, après avoir rencontré un problème similaire au vôtre:

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
la source
Quel est l'intérêt d'être plus précis que de simples "demandes", à partir d'un PDV pratique?
aknuds1
Mais que gagnez-vous en appelant logging.getLogger ("requests.packages.urllib3") au lieu de logging.getLogger ("requests"), étant donné que vous voulez affecter la journalisation de la bibliothèque de requêtes?
aknuds1
Voulez-vous dire que vous souhaitez activer la journalisation dans requests.packages.urllib3? Si oui, vous répondez à la mauvaise question.
aknuds1
@ aknuds1 C'est à vous si vous voulez les désactiver ou les activer, je ne mets que le code qui contrôle complètement cela :)
sorin
3
Je pense que vous avez mal compris la portée de la question.
aknuds1
14

Pour toute personne utilisant, logging.config.dictConfigvous pouvez modifier le niveau de journal de la bibliothèque de demandes dans le dictionnaire comme ceci:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
la source
@SebastianWagner Django utilise dictConfigsous le capot.
uhbif19
Merci beaucoup! C'est plutôt bien. Un seul endroit pour contrôler tous les journaux de la bibliothèque !! :)
MehmedB
5

Définir le nom de l'enregistreur comme requestsou requests.urllib3ne fonctionnait pas pour moi. J'ai dû spécifier le nom exact de l'enregistreur pour changer le niveau d'enregistrement.

Tout d'abord, voyez quels enregistreurs vous avez définis, pour voir ceux que vous souhaitez supprimer

print(logging.Logger.manager.loggerDict)

Et vous verrez quelque chose comme ça:

{...'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> ...}

Configurez ensuite le niveau pour l'enregistreur exact:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
la source
où sont fixés ces niveaux?
javadba
Je les ai dans les paramètres de Django, dans base.py. Leur emplacement dépend bien sûr de la configuration de votre projet.
Mikko
2

Si vous avez un fichier de configuration, vous pouvez le configurer.

Ajoutez urllib3 dans la section des enregistreurs:

[loggers]
keys = root, urllib3

Ajouter la section logger_urllib3:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Coulé
la source
C'est une réponse parfaitement valable pour les personnes qui utilisent un fichier de configuration. Vous ne savez pas pourquoi il y a eu autant de votes négatifs?
Patrick
1

Cette réponse est ici: Python: comment supprimer les instructions de journalisation des bibliothèques tierces?

Vous pouvez laisser le niveau de journalisation par défaut pour basicConfig, puis vous définissez le niveau DEBUG lorsque vous obtenez l'enregistreur pour votre module.

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
la source
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
la source
0

Les conseils de Kbrose sur la recherche de l'enregistreur générant des messages de journal ont été extrêmement utiles. Pour mon projet Django, j'ai dû trier 120 journaux différents jusqu'à ce que je trouve que c'était la elasticsearchbibliothèque Python qui me posait des problèmes. Selon les conseils de la plupart des questions, je l'ai désactivé en ajoutant ceci à mes enregistreurs:

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

Publier ici au cas où quelqu'un d'autre verrait les messages de journal inutiles passer à chaque fois qu'ils exécutent une requête Elasticsearch.

Robert Townley
la source
-1

simple: il suffit d'ajouter requests.packages.urllib3.disable_warnings()aprèsimport requests

evandrix
la source
2
Je n'ai pas trouvé cette méthode dans ma version. La désactivation des avertissements est excessive, car les messages gênants sont de niveau INFO.
tripleee
-1

Je ne sais pas si les approches précédentes ont cessé de fonctionner, mais en tout cas, voici une autre façon de supprimer les avertissements:

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

Fondamentalement, l'ajout d'une variable d'environnement dans le contexte de l'exécution du script.

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

newlog
la source