Desative as mensagens do console no servidor Flask

91

Eu tenho um servidor Flask em execução no modo autônomo (usando app.run()). Mas, eu não quero nenhuma mensagem no console, como

127.0.0.1 - - [15/Feb/2013 10:52:22] "GET /index.html HTTP/1.1" 200 -
...

Como eu desativo o modo detalhado?

ATOzTOA
fonte
Então agora você tem um aplicativo iniciando threads (que são difíceis de depurar) e agora você suprimirá o log em cima disso? Eesh, soa como o oposto do que eu faria. Quanto mais detalhado for o seu registro, melhor (obviamente, desde que seja relevante;)).
Demian Brecht de
7
@DemianBrecht Acontece que os logs são enviados, stderrmas eles apenas registram cada transação HTTP, meio irrelevante para mim ...
ATOzTOA

Respostas:

133

Você pode definir o nível do registrador Werkzeug para ERROR, nesse caso, apenas os erros são registrados:

import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

Aqui está um exemplo totalmente funcional testado em OSX, Python 2.7.5, Flask 0.10.0:

from flask import Flask
app = Flask(__name__)

import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()
Drewes
fonte
9
Isso não parece impedir que os logs de HTTP vão para stderr; PARE a mensagem "iniciando" (que claramente tem o nome do módulo "werkzeug" no formato de log ".
rsb
2
Funciona para mim. As mensagens de depuração do pedido são suprimidas. Usando Python 3.5.2, Flask 0.12 e Werkzeug 0.11.11
JackLeEmmerdeur
3
Também funciona com Python 3.6, Flask 0.12 e Werkzeug 0.11.15.
vallentin
8
Infelizmente não funciona mais totalmente devido ao uso do Flaskclick.secho
Peter
1
Alterar o nível de registro não deve ser a solução para evitar o registro de apenas uma solicitação específica.
agendado em
13

Esta solução fornece uma maneira de obter suas próprias impressões e rastreamentos de pilha, mas sem registros de nível de informação do frasco de sucção como 127.0.0.1 - - [15/Feb/2013 10:52:22] "GET /index.html HTTP/1.1" 200

from flask import Flask
import logging

app = Flask(__name__)
log = logging.getLogger('werkzeug')
log.disabled = True
Iamtodor
fonte
Isso funciona ao executar meu servidor localmente, mas estranhamente no Heroku, não funciona.
Garrett
10

A solução @Drewes funciona na maioria das vezes, mas, em alguns casos, ainda tenho a tendência de obter logs de werkzeug. Se você realmente não quiser ver nenhum deles, sugiro que desative-o assim.

from flask import Flask
import logging

app = Flask(__name__)
log = logging.getLogger('werkzeug')
log.disabled = True
app.logger.disabled = True

Para mim, falhou quando abort(500)foi criado.

Tom Wojcik
fonte
9

Caso você esteja usando um servidor WSGI, defina o log como Nenhum

gevent_server = gevent.pywsgi.WSGIServer(("0.0.0.0", 8080), app,log = None)
Ami
fonte
Esta é a única solução que funcionou para mim, e eu uso o Flask com WSGIServer
Woody
8

Nenhuma das outras respostas funcionou corretamente para mim, mas encontrei uma solução com base no comentário de Peter . O Flask aparentemente não usa mais loggingpara registro e mudou para o pacote de cliques . Substituindo click.echoe click.sechoeliminei a mensagem de inicialização do Flask de app.run().

import logging

import click
from flask import Flask

app = Flask(__name__)

log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

def secho(text, file=None, nl=None, err=None, color=None, **styles):
    pass

def echo(text, file=None, nl=None, err=None, color=None, **styles):
    pass

click.echo = echo
click.secho = secho

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

Entre definir o nível de registro ERRORe substituir os métodos de clique com funções vazias, todas as saídas de registro sem erros devem ser evitadas.

Brendan Burkhart
fonte
7

Outro motivo pelo qual você pode querer alterar a saída de log é para testes e redirecionar os logs do servidor para um arquivo de log.

Eu também não consegui fazer a sugestão acima funcionar, parece que os loggers são configurados como parte da inicialização do aplicativo. Consegui fazê-lo funcionar alterando os níveis de registro após iniciar o aplicativo:

... (in setUpClass)
server = Thread(target=lambda: app.run(host=hostname, port=port, threaded=True))
server.daemon = True
server.start()
wait_for_boot(hostname, port)  # curls a health check endpoint

log_names = ['werkzeug']
app_logs = map(lambda logname: logging.getLogger(logname), log_names)
file_handler = logging.FileHandler('log/app.test.log', 'w')

for app_log in app_logs:
    for hdlr in app_log.handlers[:]:  # remove all old handlers
        app_log.removeHandler(hdlr)

    app_log.addHandler(file_handler)

Infelizmente, o * Running on localhost:9151e a primeira verificação de integridade ainda é impressa de acordo com os padrões, mas ao executar muitos testes, ela limpa a saída em uma tonelada.

"Então, por quê log_names?", Você pergunta. No meu caso, havia alguns logs extras dos quais eu precisava me livrar. Consegui encontrar quais registradores adicionar a log_names por meio de:

from flask import Flask
app = Flask(__name__)

import logging
print(logging.Logger.manager.loggerDict)

Nota lateral: seria bom se houvesse um flaskapp.getLogger () ou algo assim, para que fosse mais robusto em todas as versões. Alguma ideia?

Mais algumas palavras-chave: log de teste de flask remove saída stdout

graças a:

Daicoden
fonte
6

Para suprimir Serving Flask app ...:

os.environ['WERKZEUG_RUN_MAIN'] = 'true'
app.run()
Slava V
fonte
1
Isso funciona para mim, eu usei ao testar o aplicativo flask (usando o nose2) isso remove a desordem no terminal. Obrigado
CpK
6

Resposta tardia, mas encontrei uma maneira de suprimir CADA E TODAS AS MENSAGENS DO CONSOLE (incluindo as exibidas durante um abort(...)erro).

import os
import logging

logging.getLogger('werkzeug').disabled = True
os.environ['WERKZEUG_RUN_MAIN'] = 'true'

Esta é basicamente uma combinação das respostas dadas por Slava V e Tom Wojcik

progyammer
fonte
-1

Uma maneira de força bruta de fazer isso se você realmente não quiser que nada entre no console ao lado das instruções print () é logging.basicConfig(level=logging.FATAL). Isso desabilitaria todos os logs com status fatal. Não desabilitaria a impressão, mas sim, apenas um pensamento: /

EDITAR: Percebi que seria egoísmo da minha parte não colocar um link para a documentação que usei :) https://docs.python.org/3/howto/logging.html#logging-basic-tutorial

Profundo estado de negação
fonte
-3

O primeiro ponto: de acordo com a documentação oficial do Flask, você não deve executar o aplicativo Flask usando app.run (). A melhor solução é usar uwsgi, então você pode desabilitar os logs de flask padrão usando o comando "--disable-logging"

Por exemplo:

uwsgi --socket 0.0.0.0:8001 --disable-logging --protocol=http -w app:app

Anton Erjomin
fonte