Deaktivieren Sie Konsolennachrichten auf dem Flask-Server

87

Ich habe einen Flask-Server, der im Standalone-Modus (mit app.run()) ausgeführt wird. Aber ich möchte keine Nachrichten in der Konsole, wie

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

Wie deaktiviere ich den ausführlichen Modus?

ATOzTOA
quelle
So , jetzt haben Sie eine App Fäden treten aus (die schwer genug sind , um sich zu debuggen) und jetzt sind Sie gehen zu Unterdrückungs - Protokollierung auf oben davon? Eesh, hört sich wie das Gegenteil von dem an, was ich tun würde. Je ausführlicher Ihre Protokollierung ist, desto besser (offensichtlich solange es relevant ist;)).
Demian Brecht
6
@ DemianBrecht Die Sache ist, die Protokolle werden gesendet, stderraber sie protokollieren nur jede HTTP-Transaktion, irgendwie irrelevant für mich ...
ATOzTOA

Antworten:

127

Sie können die Ebene des Werkzeug-Loggers auf ERROR setzen. In diesem Fall werden nur Fehler protokolliert:

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

Hier ist ein voll funktionsfähiges Beispiel, das unter OSX, Python 2.7.5, Flask 0.10.0 getestet wurde:

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
quelle
9
Dies scheint nicht zu verhindern, dass HTTP-Protokolle an stderr gesendet werden. Es stoppt die "Start" -Nachricht (die eindeutig den "werkzeug" -Modulnamen im Protokollformat hat ".
rsb
2
Funktioniert bei mir. Die Anforderungs-Debug-Meldungen werden unterdrückt. Mit Python 3.5.2, Flask 0.12 und Werkzeug 0.11.11
JackLeEmmerdeur
3
Funktioniert auch mit Python 3.6, Flask 0.12 und Werkzeug 0.11.15.
Vallentin
8
Leider funktioniert nicht mehr vollständig aufgrund von Flask mitclick.secho
Peter
1
Das Ändern der Protokollierungsstufe sollte nicht die Lösung sein, um zu vermeiden, dass nur eine bestimmte Anforderung protokolliert wird.
Gented
11

Diese Lösung bietet Ihnen eine Möglichkeit, Ihre eigenen Ausdrucke und Stapelspuren zu erhalten, jedoch ohne Protokolle auf Informationsebene aus dem Kolben saugen als 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
quelle
Dies funktioniert, wenn mein Server lokal ausgeführt wird, aber seltsamerweise auf Heroku nicht.
Garrett
10

Die @ Drewes-Lösung funktioniert die meiste Zeit, aber in einigen Fällen bekomme ich immer noch Werkzeugprotokolle. Wenn Sie wirklich keine von ihnen sehen möchten, empfehle ich Ihnen, sie so zu deaktivieren.

from flask import Flask
import logging

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

Für mich ist es gescheitert, als abort(500)es angehoben wurde.

Tom Wojcik
quelle
8

Wenn Sie einen WSGI-Server verwenden, setzen Sie das Protokoll auf Keine

gevent_server = gevent.pywsgi.WSGIServer(("0.0.0.0", 8080), app,log = None)
Ami
quelle
Dies ist die einzige Lösung, die für mich funktioniert hat, und ich verwende Flask mit WSGIServer
Woody
6

Ein weiterer Grund, warum Sie möglicherweise die Protokollausgabe ändern möchten, sind Tests und die Umleitung der Serverprotokolle in eine Protokolldatei.

Ich konnte den obigen Vorschlag auch nicht zum Laufen bringen. Es sieht so aus, als würden Logger als Teil des App-Starts eingerichtet. Ich konnte es zum Laufen bringen, indem ich die Protokollebenen nach dem Start der App änderte :

... (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)

Leider wird der * Running on localhost:9151und der erste Gesundheitscheck immer noch standardmäßig gedruckt, aber wenn viele Tests ausgeführt werden, wird die Ausgabe eine Tonne bereinigt.

"Also warum log_names?", Fragst du. In meinem Fall gab es einige zusätzliche Protokolle, die ich entfernen musste. Ich konnte herausfinden, welche Logger zu log_names hinzugefügt werden sollen über:

from flask import Flask
app = Flask(__name__)

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

Randnotiz: Es wäre schön, wenn es eine flaskapp.getLogger () oder etwas anderes gäbe, so dass dies über Versionen hinweg robuster wäre. Irgendwelche Ideen?

Einige weitere Schlüsselwörter: Kolbentestprotokoll stdout-Ausgabe entfernen

Dank an:

daicoden
quelle
6

Späte Antwort, aber ich habe einen Weg gefunden, JEDE UND JEDE KONSOLE-NACHRICHT zu unterdrücken (einschließlich derjenigen, die während eines abort(...)Fehlers angezeigt werden).

import os
import logging

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

Dies ist im Grunde eine Kombination der Antworten von Slava V und Tom Wojcik

Programmierer
quelle
6

Keine der anderen Antworten funktionierte richtig für mich, aber ich fand eine Lösung basierend auf Peters Kommentar . Flask wird anscheinend nicht mehr loggingfür die Protokollierung verwendet und hat auf das Click- Paket umgestellt . Durch Überschreiben click.echound click.sechoich habe Flask's Startmeldung von entfernt 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()

Zwischen dem Festlegen der Protokollierungsstufe ERRORund dem Überschreiben der Klickmethoden mit leeren Funktionen sollten alle fehlerfreien Protokollausgaben verhindert werden.

Brendan Burkhart
quelle
5

Um zu unterdrücken Serving Flask app ...:

os.environ['WERKZEUG_RUN_MAIN'] = 'true'
app.run()
Slava V.
quelle
1
Dies funktioniert bei mir. Ich habe es beim Testen der Kolbenanwendung (mit Nase2) verwendet. Dadurch wird die Unordnung im Terminal beseitigt. Danke
CpK
0

Eine Brute-Force- Methode, wenn Sie wirklich nicht möchten, dass sich neben print () -Anweisungen etwas in der Konsole anmeldet, ist to logging.basicConfig(level=logging.FATAL). Dies würde alle Protokolle deaktivieren, die den Status "Schwerwiegend" haben. Es würde das Drucken nicht deaktivieren, aber ja, nur ein Gedanke: /

EDIT: Mir wurde klar, dass es egoistisch von mir wäre, keinen Link zu der von mir verwendeten Dokumentation zu setzen :) https://docs.python.org/3/howto/logging.html#logging-basic-tutorial

Tiefer Zustand der Verleugnung
quelle
-2

Der erste Punkt: Gemäß der offiziellen Flask-Dokumentation sollten Sie die Flask-Anwendung nicht mit app.run () ausführen. Die beste Lösung ist die Verwendung von uwsgi, sodass Sie Standard-Kolbenprotokolle mit dem Befehl "--disable-logging" deaktivieren können.

Beispielsweise:

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

Anton Erjomin
quelle