Bagaimana cara menonaktifkan pesan log dari perpustakaan Permintaan?

367

Secara default, pustaka Permintaan python menulis pesan log ke konsol, di sepanjang baris:

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

Saya biasanya tidak tertarik dengan pesan-pesan ini, dan ingin menonaktifkannya. Apa cara terbaik untuk membungkam pesan-pesan itu atau mengurangi verbositas Permintaan?

aknuds1
sumber
Terkait: nginx dan gunicorn
Martin Thoma

Jawaban:

573

Saya menemukan cara mengkonfigurasi tingkat pencatatan permintaan , dilakukan melalui modul pencatatan standar . Saya memutuskan untuk mengonfigurasinya agar tidak mencatat pesan kecuali itu setidaknya peringatan:

import logging

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

Jika Anda ingin menerapkan pengaturan ini untuk pustaka urllib3 (biasanya digunakan oleh permintaan), tambahkan berikut ini:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
sumber
4
Saya memiliki masalah yang sama dengan pysimplesoap, dan jawaban ini membantu saya menyelamatkan hari saya
Janith Chinthana
2
Anda dapat menggabungkan dua baris seperti ini: logging.getLogger ('permintaan'). SetLevel (logging.WARNING)
jpoppe
7
Saya harus menambahkan baris ini untuk logger "urllib3" untuk menekan pesan log permintaan.
dgassaway
9
Saya perlu mengimpor logging; logging.getLogger ("urllib3"). setLevel (logging.WARNING), juga. Logger untuk "permintaan" tidak mencegah pesan-pesan ini.
m_messiah
4
Untuk beberapa alasan saat menggunakan perpustakaan permintaan di python3 yang harus Anda lakukan getLogger("urllib3")untuk menekan pesan.
robru
104

Jika Anda datang ke sini mencari cara untuk memodifikasi logging dari setiap (mungkin sangat bersarang) modul, gunakan logging.Logger.manager.loggerDictuntuk mendapatkan kamus dari semua objek logger. Nama-nama yang dikembalikan kemudian dapat digunakan sebagai argumen untuk 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)

Per pengguna136036 dalam komentar, perlu diketahui bahwa metode ini hanya menunjukkan kepada Anda para penebang yang ada pada saat Anda menjalankan cuplikan di atas. Jika, misalnya, modul membuat logger baru ketika Anda membuat instance sebuah kelas, maka Anda harus meletakkan potongan ini setelah membuat kelas untuk mencetak namanya.

kbrose
sumber
3
Terima kasih, ini membantu saya membungkam urllib3pesan log saat menggunakan boto3. Logger dalam kasus ini adalah botocore.vendored.requests.packages.urllib3, jadi saya menggunakan ini: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)dan saya akhirnya menyingkirkan pesan-pesannya.
Bob Dem
Terima kasih banyak atas ini! Mengubah kriteria cetak memungkinkan saya untuk mengisolasi bahwa python-elasticsearch adalah penyebab dalam kasus saya.
Robert Townley
2
Ketahuilah bahwa ini tidak akan berfungsi ketika modul membuat logger mereka di dalam kelas mereka yang akan Anda panggil nanti, seperti yang APSchedulerdilakukan saat Anda menelepon BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: objek logger adalah lajang, tidak masalah jika Anda atau pustaka yang membuatnya terlebih dahulu. Jika Anda menggunakan nama yang sama persis seperti yang digunakan perpustakaan, itu akan berfungsi .
Martijn Pieters
1
Saya pikir mereka mengatakan bahwa jika Anda membuat daftar penebang sebelum perpustakaan membuat loggernya, maka itu tidak akan terdaftar. Yang mana yang benar.
kbrose
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

Dengan cara ini semua pesan level = INFO dari urllib3 tidak akan ada di logfile.

Jadi Anda dapat terus menggunakan level = INFO untuk pesan log Anda ... cukup modifikasi ini untuk perpustakaan yang Anda gunakan.

shaolin
sumber
4
Saya sarankan menggunakan setLevel(logging.WARNING)juga kemungkinan pesan peringatan dan kesalahan.
razz0
14

Izinkan saya menyalin / menempel bagian dokumentasi yang saya tulis sekitar satu atau dua minggu yang lalu, setelah mengalami masalah yang serupa dengan Anda:

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
sumber
Apa gunanya lebih spesifik dari sekadar 'permintaan', dari POV praktis?
aknuds1
Tetapi apa yang Anda peroleh dengan memanggil logging.getLogger ("requests.packages.urllib3") alih-alih logging.getLogger ("permintaan"), mengingat Anda ingin memengaruhi pencatatan log permintaan perpustakaan?
aknuds1
Apakah maksud Anda bahwa Anda ingin mengaktifkan logging di dalam requests.packages.urllib3? Jika demikian, Anda menjawab pertanyaan yang salah.
aknuds1
@ aknuds1 Terserah Anda jika Anda ingin menonaktifkan atau mengaktifkan mereka, saya hanya menempatkan kode yang sepenuhnya mengendalikan :) ini
sorin
3
Saya pikir Anda telah salah memahami ruang lingkup pertanyaan.
aknuds1
14

Bagi siapa pun yang menggunakan logging.config.dictConfigAnda dapat mengubah level log pustaka permintaan dalam kamus seperti ini:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
sumber
@SebastianWagner Django menggunakan di dictConfigbawah kap.
uhbif19
Terima kasih banyak! Ini cukup bagus. Satu tempat untuk mengatur semua log perpustakaan !! :)
MehmedB
5

Menyetel nama logger sebagai requestsatau requests.urllib3tidak berfungsi untuk saya. Saya harus menentukan nama logger yang tepat untuk mengubah level logging.

Pertama Lihat penebang mana yang telah Anda tentukan, untuk melihat mana yang ingin Anda hapus

print(logging.Logger.manager.loggerDict)

Dan Anda akan melihat sesuatu seperti ini:

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

Kemudian konfigurasikan level untuk logger yang tepat:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
sumber
di mana level-level ini ditetapkan?
javadba
Saya memilikinya di pengaturan Django, di base.py. Tempat untuk meletakkannya tentu saja tergantung pada pengaturan proyek Anda.
Mikko
2

Jika Anda memiliki file konfigurasi, Anda dapat mengonfigurasinya.

Tambahkan urllib3 di bagian penebang:

[loggers]
keys = root, urllib3

Tambahkan bagian logger_urllib3:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Sank
sumber
Ini adalah jawaban yang benar-benar valid untuk orang yang menggunakan file konfigurasi. Tidak yakin mengapa itu mendapat begitu banyak suara?
Patrick
1

Jawaban ini ada di sini: Python: bagaimana cara menekan pernyataan logging dari perpustakaan pihak ketiga?

Anda dapat meninggalkan level logging standar untuk basicConfig, dan kemudian Anda mengatur level DEBUG ketika Anda mendapatkan logger untuk modul Anda.

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

Panduan Kbrose tentang menemukan logger mana yang menghasilkan pesan log sangat berguna. Untuk proyek Django saya, saya harus memilah-milah 120 penebang yang berbeda sampai saya menemukan bahwa itu adalah elasticsearchperpustakaan Python yang menyebabkan masalah bagi saya. Sesuai panduan dalam sebagian besar pertanyaan, saya menonaktifkannya dengan menambahkan ini ke penebang saya:

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

Posting di sini kalau-kalau ada orang lain melihat pesan log yang tidak membantu datang setiap kali mereka menjalankan kueri Elasticsearch.

Robert Townley
sumber
-1

sederhana: cukup tambahkan requests.packages.urllib3.disable_warnings()setelahimport requests

evandrix
sumber
2
Saya tidak menemukan metode ini dalam versi saya. Menonaktifkan peringatan itu berlebihan, karena pesan-pesan yang mengganggu itu level INFO.
tripleee
-1

Saya tidak yakin apakah pendekatan sebelumnya telah berhenti berfungsi, tetapi dalam hal apa pun, berikut cara lain untuk menghapus peringatan:

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

Pada dasarnya, menambahkan variabel lingkungan dalam konteks eksekusi skrip.

Dari dokumentasi: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

newlog
sumber