Como desabilito as mensagens de log da biblioteca de solicitações?

367

Por padrão, a biblioteca python Requests grava mensagens de log no console, ao longo das linhas de:

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

Normalmente, não estou interessado nessas mensagens e gostaria de desativá-las. Qual seria a melhor maneira de silenciar essas mensagens ou diminuir a verbosidade das solicitações?

aknuds1
fonte
Palavras
Martin Thoma

Respostas:

573

Eu descobri como configurar o nível de log de solicitações , isso é feito através do módulo de log padrão . Decidi configurá-lo para não registrar mensagens, a menos que sejam pelo menos avisos:

import logging

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

Se você deseja aplicar essa configuração à biblioteca urllib3 (normalmente usada por solicitações), adicione o seguinte:

logging.getLogger("urllib3").setLevel(logging.WARNING)
aknuds1
fonte
4
Tenho mesmo problema com pysimplesoap, e esta resposta me ajudar a salvar meu dia
janith Chinthana
2
Você pode combinar as duas linhas como este: logging.getLogger ( 'pedidos') setlevel (logging.WARNING).
jpoppe
7
Eu tive que adicionar esta linha para o criador de logs "urllib3" para suprimir as mensagens de log de solicitações.
precisa saber é o seguinte
9
Eu precisava importar o log; logging.getLogger ("urllib3"). setLevel (logging.WARNING) também. O criador de logs de "solicitações" não impede essas mensagens.
m_messiah
4
Por alguma razão, ao usar a biblioteca de solicitações em python3, você getLogger("urllib3")deve suprimir as mensagens.
robru
104

Caso você tenha vindo aqui procurando uma maneira de modificar o log de qualquer módulo (possivelmente profundamente aninhado), use logging.Logger.manager.loggerDictpara obter um dicionário de todos os objetos do logger. Os nomes retornados podem ser usados ​​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 user136036 em um comentário, saiba que este método mostra apenas os criadores de logs que existem no momento em que você executa o snippet acima. Se, por exemplo, um módulo criar um novo criador de logs ao instanciar uma classe, você deverá colocar esse trecho depois de criar a classe para imprimir seu nome.

kbrose
fonte
3
Obrigado, isso me ajudou a silenciar urllib3as mensagens de log ao usar boto3. O registrador nesse caso é botocore.vendored.requests.packages.urllib3, então eu usei isso: logging.getLogger("botocore.vendored.requests.packages.urllib3").setLevel(logging.WARNING)e finalmente me livrei das mensagens.
31517 Bob Dem Dem
Muito obrigado por isso! Alterar os critérios de impressão permitiu-me isolar que a pesquisa python-elastics era a culpada no meu caso.
precisa
2
Esteja ciente de que isso não funcionará quando os módulos criarem seus registradores dentro da classe que você chamaria mais tarde, como APScheduleracontece quando você chama BackgroundScheduler.BackgroundScheduler().
user136036
@ user136036: os objetos do logger são singletons, não importa se você ou a biblioteca os cria primeiro. Se você usar exatamente o mesmo nome que a biblioteca, ela funcionará .
Martijn Pieters
11
Eu acho que eles estão dizendo que, se você listar os criadores de log antes de uma biblioteca ter criado seu criador, ele não será listado. Qual é correto.
Kbrose # 9/19
28
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

Dessa forma, todas as mensagens de level = INFO de urllib3 não estarão presentes no arquivo de log.

Assim, você pode continuar usando o level = INFO para suas mensagens de log ... apenas modifique-o para a biblioteca que está usando.

shaolin
fonte
4
Sugiro usar setLevel(logging.WARNING)também para registrar possíveis mensagens de aviso e erro.
razz0
14

Deixe-me copiar / colar a seção de documentação que escrevi há uma ou duas semanas, depois de ter um problema semelhante ao seu:

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
fonte
Qual é o sentido de ser mais específico do que apenas 'solicitações', de um ponto de vista prático?
precisa saber é o seguinte
Mas o que você ganha chamando logging.getLogger ("orders.packages.urllib3") em vez de logging.getLogger ("orders"), considerando que deseja afetar o log da biblioteca de solicitações?
precisa saber é o seguinte
Você quer dizer que deseja ativar o log em orders.packages.urllib3? Nesse caso, você está respondendo à pergunta errada.
precisa saber é o seguinte
@ aknuds1 Cabe a você se você quiser desativar ou ativar eles, eu só colocar o código que controla integralmente este :)
Sorin
3
Acho que você não entendeu o escopo da pergunta.
aknuds1
14

Para quem logging.config.dictConfigestiver usando, você pode alterar o nível de log da biblioteca de solicitações no dicionário da seguinte maneira:

'loggers': {
    '': {
        'handlers': ['file'],
        'level': level,
        'propagate': False
    },
    'requests.packages.urllib3': {
        'handlers': ['file'],
        'level': logging.WARNING
    }
}
TheHerk
fonte
@SebastianWagner O Django usa dictConfigsob o capô.
uhbif19
Muito obrigado! Isso é muito bom. Um lugar para governar todos os logs da biblioteca !! :)
MehmedB
5

Definir o nome do criador de logs como requestsou requests.urllib3não funcionou para mim. Eu tive que especificar o nome exato do criador de logs para alterar o nível de criação de log.

Primeiro Veja quais registradores você definiu, para ver quais deseja remover

print(logging.Logger.manager.loggerDict)

E você verá algo assim:

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

Em seguida, configure o nível para o logger exato:

   'loggers': {
    '': {
        'handlers': ['default'],
        'level': 'DEBUG',
        'propagate': True
    },
    'urllib3.connectionpool': {
        'handlers': ['default'],
        'level': 'WARNING',
        'propagate' : False
    },
Mikko
fonte
onde esses níveis são definidos?
javadba 26/01
Eu os tenho nas configurações do Django, em base.py. Onde colocá-los, é claro, depende da configuração do seu projeto.
Mikko
2

Se você tiver um arquivo de configuração, poderá configurá-lo.

Adicione urllib3 na seção de loggers:

[loggers]
keys = root, urllib3

Adicione a seção logger_urllib3:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
Sank
fonte
Esta é uma resposta perfeitamente válida para pessoas que usam o arquivo de configuração. Não sabe por que recebeu tantos votos negativos?
Patrick
1

Esta resposta está aqui: Python: como suprimir instruções de log de bibliotecas de terceiros?

Você pode deixar o nível de log padrão para basicConfig e definir o nível de DEBUG ao obter o logger para o seu 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
fonte
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
fonte
0

As orientações da Kbrose sobre encontrar qual registrador estava gerando mensagens de log eram imensamente úteis. Para o meu projeto Django, tive que classificar entre 120 registradores diferentes até descobrir que era a elasticsearchbiblioteca Python que estava causando problemas para mim. De acordo com as orientações da maioria das perguntas, desativei adicionando isso aos meus criadores de logs:

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

Postando aqui caso alguém veja as mensagens de log inúteis sempre que executar uma consulta do Elasticsearch.

Robert Townley
fonte
-1

simples: basta adicionar requests.packages.urllib3.disable_warnings()depoisimport requests

evandrix
fonte
2
Não encontrei esse método na minha versão. Desativar avisos é excessivo, pois as mensagens irritantes estão niveladas INFO.
tripleee
-1

Não tenho certeza se as abordagens anteriores pararam de funcionar, mas, de qualquer forma, aqui está outra maneira de remover os avisos:

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

Basicamente, adicionando uma variável de ambiente no contexto da execução do script.

Na documentação: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

newlog
fonte