Jak wyłączyć komunikaty dziennika z biblioteki Żądania?

367

Domyślnie Wnioski python library pisze komunikaty dziennika do konsoli, wzdłuż linii:

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

Zazwyczaj nie jestem zainteresowany tymi wiadomościami i chciałbym je wyłączyć. Jaki byłby najlepszy sposób wyciszenia tych wiadomości lub zmniejszenia szczegółowości żądań?

aknuds1
źródło
Powiązane: nginx i gunicorn
Martin Thoma

Odpowiedzi:

573

Dowiedziałem się, jak skonfigurować poziom rejestrowania żądań , odbywa się to za pośrednictwem standardowego modułu rejestrowania . Zdecydowałem się tak skonfigurować, aby nie rejestrował wiadomości, chyba że są to przynajmniej ostrzeżenia:

import logging

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

Jeśli chcesz zastosować to ustawienie również do biblioteki urllib3 (zwykle używanej w żądaniach), dodaj:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
źródło
4
Mam ten sam problem pysimplesoapi ta odpowiedź pomaga mi uratować mój dzień
Janith Chinthana
2
Możesz połączyć dwa wiersze w ten sposób: Logowanie.getLogger („żądania”). SetLevel (logowanie.WARNING)
jpoppe
7
Musiałem dodać tę linię do programu rejestrującego „urllib3”, aby ukryć komunikaty dziennika żądań.
dgassaway
9
Musiałem zaimportować rejestrowanie; logowanie.getLogger („urllib3”). setLevel (logowanie.WARNING). Rejestrator „żądań” nie zapobiega tym wiadomościom.
m_messiah
4
Z jakiegoś powodu, gdy używasz biblioteki żądań w python3, musisz zrobić, getLogger("urllib3")aby ukryć wiadomości.
robru
104

Jeśli przyszedłeś tutaj, aby znaleźć sposób na zmodyfikowanie rejestrowania dowolnego (prawdopodobnie głęboko zagnieżdżonego) modułu, użyj, logging.Logger.manager.loggerDictaby uzyskać słownik wszystkich obiektów rejestrujących. Zwrócone nazwy można następnie wykorzystać jako argument do 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)

Na użytkownika 136036 w komentarzu należy pamiętać, że ta metoda pokazuje tylko programy rejestrujące, które istnieją w momencie uruchomienia powyższego fragmentu. Jeśli na przykład moduł tworzy nowy program rejestrujący podczas tworzenia instancji klasy, to po utworzeniu klasy należy umieścić ten fragment kodu, aby wydrukować jego nazwę.

kbrose
źródło
3
Dziękuję, pomogło mi to wyciszyć urllib3komunikaty dziennika podczas używania boto3. Logger w takim przypadku jest botocore.vendored.requests.packages.urllib3, więc użyłem tego: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)i w końcu pozbyłem się wiadomości.
Bob Dem
Wielkie dzięki za to! Zmiana kryteriów drukowania pozwoliła mi wyodrębnić, że winowajcą w moim przypadku był winowajca.
Robert Townley,
2
Pamiętaj, że to nie zadziała, gdy moduły utworzą swoje moduły rejestrujące w swojej klasie, do której zadzwonisz później, podobnie jak APSchedulerpodczas wywołania BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: obiekty rejestrujące są singletonami, nie ma znaczenia, czy ty lub biblioteka je najpierw utworzysz. Jeśli użyjesz dokładnie tej samej nazwy co biblioteka, będzie działać .
Martijn Pieters
1
Myślę, że mówią, że jeśli wyszczególnisz programy rejestrujące, zanim biblioteka utworzy program rejestrujący, to nie będzie na liście. Który jest poprawny.
kbrose
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

W ten sposób wszystkie komunikaty o poziomie = informacje z urllib3 nie będzie obecny w pliku dziennika.

Możesz więc nadal używać poziomu = INFO do wiadomości w dzienniku ... po prostu zmodyfikuj to dla używanej biblioteki.

Shaolin
źródło
4
Sugeruję używanie setLevel(logging.WARNING)do rejestrowania również możliwych komunikatów ostrzegawczych i błędów.
razz0
14

Pozwól mi skopiować / wkleić sekcję dokumentacji, o której napisałem tydzień lub dwa lata temu, po wystąpieniu problemu podobnego do twojego:

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
źródło
Jaki jest sens bycia bardziej konkretnym niż tylko „prośby” z praktycznego POV?
aknuds1
Ale co zyskujesz, wywołując logowanie.getLogger („requests.packages.urllib3”) zamiast logowania.getLogger („żądania”), biorąc pod uwagę, że chcesz wpłynąć na rejestrowanie biblioteki żądań?
aknuds1
Czy masz na myśli, że chcesz włączyć rejestrowanie w obrębie requests.packages.urllib3? Jeśli tak, odpowiadasz na złe pytanie.
aknuds1
@ aknuds1 Od Ciebie zależy, czy chcesz je wyłączyć, czy włączyć, umieszczam tylko kod, który w pełni to kontroluje :)
sorin
3
Myślę, że źle zrozumiałeś zakres pytania.
aknuds1
14

Dla każdego, kto używa logging.config.dictConfig, możesz zmienić poziom dziennika bibliotek żądań w słowniku w następujący sposób:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
źródło
@SebastianWagner Django używa dictConfigpod maską.
uhbif19,
Dziękuję bardzo! To całkiem nieźle. Jedno miejsce do rządzenia wszystkimi dziennikami biblioteki !! :)
MehmedB
5

Ustawienie nazwy rejestratora jako requestslub requests.urllib3nie działało dla mnie. Musiałem podać dokładną nazwę rejestratora, aby zmienić poziom rejestrowania.

Najpierw Sprawdź, które loggery zdefiniowałeś, aby zobaczyć, które chcesz usunąć

print(logging.Logger.manager.loggerDict)

I zobaczysz coś takiego:

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

Następnie skonfiguruj poziom dokładnego rejestratora:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
źródło
gdzie są ustawione te poziomy?
javadba
Mam je w ustawieniach Django, w base.py. To, gdzie je umieścić, zależy oczywiście od konfiguracji projektu.
Mikko
2

Jeśli masz plik konfiguracyjny, możesz go skonfigurować.

Dodaj urllib3 w sekcji rejestratorów:

[loggers]
keys = root, urllib3

Dodaj sekcję logger_urllib3:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Zatonął
źródło
Jest to całkowicie poprawna odpowiedź dla osób korzystających z pliku konfiguracyjnego. Nie jesteś pewien, dlaczego otrzymał tak wiele głosów?
Patrick,
1

Oto odpowiedź: Python: jak ukryć instrukcje rejestrowania z bibliotek stron trzecich?

Możesz pozostawić domyślny poziom rejestrowania dla basicConfig, a następnie ustaw poziom DEBUG, kiedy otrzymasz moduł rejestrujący dla swojego modułu.

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
źródło
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
źródło
0

Wskazówki Kbrose dotyczące znalezienia rejestratora, który generował komunikaty dziennika, były niezwykle przydatne. W przypadku mojego projektu Django musiałem posortować 120 różnych programów rejestrujących, dopóki nie odkryłem, elasticsearchże przyczyną problemów była biblioteka Python. Zgodnie z wytycznymi w większości pytań, wyłączyłem go, dodając to do moich rejestratorów:

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

Publikowanie tutaj, na wypadek, gdyby ktoś zobaczył niepomocne komunikaty w dzienniku za każdym razem, gdy uruchomi zapytanie Elasticsearch.

Robert Townley
źródło
-1

proste: wystarczy dodać requests.packages.urllib3.disable_warnings()poimport requests

evandrix
źródło
2
Nie znalazłem tej metody w mojej wersji. Wyłączanie ostrzeżeń jest nadmierne, ponieważ irytujące wiadomości są na poziomie INFO.
tripleee 28.04.16
-1

Nie jestem pewien, czy poprzednie podejścia przestały działać, ale w każdym razie oto inny sposób usunięcia ostrzeżeń:

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

Zasadniczo dodanie zmiennej środowiskowej w kontekście wykonywania skryptu.

Z dokumentacji: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

newlog
źródło