Wie deaktiviere ich Protokollnachrichten aus der Anforderungsbibliothek?

367

Standardmäßig schreibt die Python-Bibliothek " Requests" Protokollnachrichten wie folgt in die Konsole:

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

Ich bin normalerweise nicht an diesen Nachrichten interessiert und möchte sie deaktivieren. Was wäre der beste Weg, um diese Nachrichten zum Schweigen zu bringen oder die Ausführlichkeit von Anfragen zu verringern?

aknuds1
quelle
Verwandte: Nginx und Gunicorn
Martin Thoma

Antworten:

573

Ich fand heraus , wie man configure Anfragen ‚s Protokollebene, es über den Standard getan Logging - Modul. Ich habe beschlossen, es so zu konfigurieren, dass keine Nachrichten protokolliert werden, es sei denn, es handelt sich zumindest um Warnungen:

import logging

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

Wenn Sie diese Einstellung auch für die urllib3-Bibliothek anwenden möchten (normalerweise von Anforderungen verwendet), fügen Sie Folgendes hinzu:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
quelle
4
Ich habe das gleiche Problem mit pysimplesoap, und diese Antwort hilft mir, meinen Tag zu retten
Janith Chinthana
2
Sie können die beiden Zeilen folgendermaßen kombinieren: logging.getLogger ('Anfragen'). SetLevel (logging.WARNING)
jpoppe
7
Ich musste diese Zeile für den "urllib3" -Logger hinzufügen, um Anforderungsprotokollnachrichten zu unterdrücken.
Dgassaway
9
Ich musste die Protokollierung importieren. logging.getLogger ("urllib3"). setLevel (logging.WARNING) auch. Der Logger für "Anfragen" verhindert diese Nachrichten nicht.
m_messiah
4
Aus irgendeinem Grund müssen Sie bei Verwendung der Anforderungsbibliothek in Python3 getLogger("urllib3")die Nachrichten unterdrücken.
Robru
104

Wenn Sie hierher gekommen sind, um nach einer Möglichkeit zu suchen, die Protokollierung eines (möglicherweise tief verschachtelten) Moduls zu ändern, verwenden Sie logging.Logger.manager.loggerDict, um ein Wörterbuch aller Protokollierungsobjekte abzurufen. Die zurückgegebenen Namen können dann als Argument für Folgendes verwendet werden 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)

Beachten Sie, dass diese Methode gemäß user136036 in einem Kommentar nur die Logger anzeigt, die zum Zeitpunkt der Ausführung des obigen Snippets vorhanden sind. Wenn ein Modul beispielsweise beim Instanziieren einer Klasse einen neuen Logger erstellt, müssen Sie dieses Snippet nach dem Erstellen der Klasse einfügen, um ihren Namen zu drucken.

kbrose
quelle
3
Vielen Dank, dies hat mir geholfen, urllib3Protokollnachrichten bei der Verwendung zum Schweigen zu bringen boto3. Der Logger in einem solchen Fall ist botocore.vendored.requests.packages.urllib3, also habe ich diesen verwendet: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)und ich habe endlich die Nachrichten losgeworden.
Bob Dem
Vielen Dank dafür! Durch Ändern der Druckkriterien konnte ich isolieren, dass Python-Elasticsearch in meinem Fall der Schuldige war.
Robert Townley
2
Beachten Sie, dass dies nicht funktioniert, wenn Module ihre Logger in ihrer Klasse erstellen, die Sie später aufrufen würden, wie APSchedulerdies beim Aufrufen der Fall ist BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: Logger-Objekte sind Singletons. Es spielt keine Rolle, ob Sie oder die Bibliothek sie zuerst erstellen müssen. Wenn Sie genau den Namen verwenden, den die Bibliothek verwendet, funktioniert dies .
Martijn Pieters
1
Ich denke, sie sagen, wenn Sie die Logger auflisten, bevor eine Bibliothek ihren Logger erstellt hat, wird er nicht aufgelistet. Welches ist richtig.
Kbrose
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

Auf diese Weise sind nicht alle Nachrichten von level = INFO von urllib3 in der Protokolldatei vorhanden.

Sie können also weiterhin level = INFO für Ihre Protokollnachrichten verwenden. Ändern Sie dies einfach für die Bibliothek, die Sie verwenden.

Shaolin
quelle
4
Ich schlage vor setLevel(logging.WARNING), auch mögliche Warn- und Fehlermeldungen zu protokollieren.
Razz0
14

Lassen Sie mich den Dokumentationsabschnitt kopieren / einfügen, den ich vor ein oder zwei Wochen geschrieben habe, nachdem ich ein ähnliches Problem wie Sie hatte:

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
quelle
Was bringt es, spezifischer zu sein als nur "Anfragen" von einem praktischen POV?
aknuds1
Aber was gewinnen Sie, wenn Sie logging.getLogger ("request.packages.urllib3") anstelle von logging.getLogger ("request") aufrufen, wenn Sie berücksichtigen, dass Sie die Protokollierung der Anforderungsbibliothek beeinflussen möchten?
aknuds1
Meinen Sie damit, dass Sie die Protokollierung in request.packages.urllib3 aktivieren möchten? Wenn ja, beantworten Sie die falsche Frage.
aknuds1
@ aknuds1 Es liegt an Ihnen, ob Sie sie deaktivieren oder aktivieren möchten, ich setze nur den Code, der dies vollständig steuert :)
Sorin
3
Ich denke, Sie haben den Umfang der Frage falsch verstanden.
Aknuds1
14

Für jeden Benutzer können logging.config.dictConfigSie die Protokollstufe der Anforderungsbibliothek im Wörterbuch wie folgt ändern:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
quelle
@SebastianWagner Django verwendet dictConfigunter der Haube.
Uhbif19
Ich danke dir sehr! Das ist ziemlich gut. Ein Ort, um alle Bibliotheksprotokolle zu regieren !! :)
MehmedB
5

Festlegen des Loggernamens als requestsoderrequests.urllib3 hat bei mir nicht funktioniert. Ich musste den genauen Loggernamen angeben, um die Protokollierungsstufe zu ändern.

Überprüfen Sie zunächst, welche Logger Sie definiert haben, um festzustellen, welche Sie entfernen möchten

print(logging.Logger.manager.loggerDict)

Und Sie werden so etwas sehen:

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

Konfigurieren Sie dann die Ebene für den genauen Logger:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
quelle
Wo sind diese Ebenen eingestellt?
Javadba
Ich habe sie in den Django-Einstellungen in base.py. Wo sie platziert werden sollen, hängt natürlich von Ihrem Projekt-Setup ab.
Mikko
2

Wenn Sie eine Konfigurationsdatei haben, können Sie diese konfigurieren.

Fügen Sie urllib3 im Abschnitt Logger hinzu:

[loggers]
keys = root, urllib3

Fügen Sie den Abschnitt logger_urllib3 hinzu:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Versank
quelle
Dies ist eine absolut gültige Antwort für Personen, die Konfigurationsdateien verwenden. Nicht sicher, warum es so viele Abstimmungen gab?
Patrick
1

Diese Antwort ist hier: Python: Wie werden Protokollierungsanweisungen aus Bibliotheken von Drittanbietern unterdrückt?

Sie können die Standardprotokollierungsstufe für basicConfig beibehalten und dann die DEBUG-Stufe festlegen, wenn Sie den Logger für Ihr Modul erhalten.

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
quelle
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
quelle
0

Die Anleitung von Kbrose, herauszufinden, welcher Logger Protokollnachrichten generiert, war äußerst nützlich. Für mein Django-Projekt musste ich 120 verschiedene Logger sortieren, bis ich feststellte, dass es die elasticsearchPython-Bibliothek war, die Probleme für mich verursachte. Gemäß den Anweisungen in den meisten Fragen habe ich sie deaktiviert, indem ich sie meinen Loggern hinzugefügt habe:

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

Hier posten, falls jemand anderes die nicht hilfreichen Protokollnachrichten sieht, wenn er eine Elasticsearch-Abfrage ausführt.

Robert Townley
quelle
-1

einfach: einfach requests.packages.urllib3.disable_warnings()nachher hinzufügenimport requests

evandrix
quelle
2
Ich habe diese Methode in meiner Version nicht gefunden. Das Deaktivieren von Warnungen ist übermäßig, da die nervigen Meldungen gleich sind INFO.
Tripleee
-1

Ich bin mir nicht sicher, ob die vorherigen Ansätze nicht mehr funktionieren, aber auf jeden Fall gibt es eine andere Möglichkeit, die Warnungen zu entfernen:

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

Grundsätzlich Hinzufügen einer Umgebungsvariablen im Kontext der Skriptausführung.

Aus der Dokumentation: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

Newlog
quelle