在Flask服务器中禁用控制台消息


90

我有一个在独立模式下运行的Flask服务器(使用app.run())。但是,我不需要控制台中的任何消息,例如

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

如何禁用详细模式?


因此,现在您有了一个启动线程的应用程序(这些线程很难调试自己),现在您将要禁止在此之上登录吗?Eesh,听起来和我要做的相反。.日志越详细越好(显然,只要相关即可;)。
Demian Brecht

6
@DemianBrecht问题是,日志发送到了,stderr但它们只是记录每个HTTP事务,对我来说
一点都不重要

Answers:


129

您可以将Werkzeug记录器的级别设置为ERROR,在这种情况下,仅记录错误:

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

这是在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()

9
这似乎并没有阻止HTTP日志发送到stderr。它确实停止了“正在启动”消息(该日志消息显然具有日志格式的“ werkzeug”模块名称。)
rsb 2015年

2
为我工作。请求调试消息被禁止。使用Python 3.5.2,Flask 0.12和Werkzeug 0.11.11
JackLeEmmerdeur

3
也可以使用Python 3.6,Flask 0.12和Werkzeug 0.11.15使用。
vallentin

8
不幸的是不再完全适用,由于烧瓶中使用click.secho
彼得

1
更改日志记录级别不应成为避免仅记录一个特定请求的解决方案。
6

11

该解决方案为您提供了一种获取自己的打印件和堆栈轨迹的方法,但是却没有烧瓶中的信息级别日志。 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

这在本地运行服务器时有效,但奇怪的是在Heroku上却没有。
加勒特

10

@Drewes解决方案在大多数情况下都有效,但是在某些情况下,我仍然倾向于获取werkzeug日志。如果您真的不想看到它们中的任何一个,我建议您像这样禁用它。

from flask import Flask
import logging

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

对我来说,它失败abort(500)了。


8

如果您使用的是WSGI服务器,请将日志设置为None

gevent_server = gevent.pywsgi.WSGIServer(("0.0.0.0", 8080), app,log = None)

这是唯一对我有用的解决方案,我将Flask与WSGIServer一起使用
Woody,

7

您可能想要更改日志记录输出的另一个原因是为了进行测试,并将服务器日志重定向到日志文件。

我也无法接受上面的建议,看来记录器已作为启动应用程序的一部分进行了设置。启动应用程序后,我可以通过更改日志级别使其工作:

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

不幸的* Running on localhost:9151是,仍然进行了第一次健康检查并按标准进行打印,但是在运行大量测试时,它会大量清除输出。

log_names你问:“那为什么?” 就我而言,有一些多余的日志需要清除。我能够通过以下方式找到要添加到log_names的记录器:

from flask import Flask
app = Flask(__name__)

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

旁注:如果有flaskapp.getLogger()或类似的东西,那会很好,因此它在各个版本之间都更可靠。有任何想法吗?

其他一些关键字:flask测试日志,删除stdout输出

谢谢:


6

抑制Serving Flask app ...

os.environ['WERKZEUG_RUN_MAIN'] = 'true'
app.run()

1
这对我有用,我在测试烧瓶应用时使用了它(使用nas2),这消除了终端中的混乱。谢谢
CpK

6

答案较晚,但我发现了一种抑制每次和每个控制台消息(包括abort(...)错误期间显示的消息)的方法。

import os
import logging

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

这基本上是Slava VTom Wojcik给出的答案的组合


6

没有其他答案对我来说是正确的,但是我根据彼得的评论找到了一个解决方案。Flask显然不再logging用于日志记录,并且已切换到click包。通过覆盖click.echoclick.secho我从中消除了Flask的启动消息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()

在将日志记录级别设置为ERROR和使用空功能覆盖click方法之间,应防止所有非错误日志输出。


-1

如果您真的不希望任何东西登录到print()语句旁边的控制台,则可以使用蛮力方式进行操作logging.basicConfig(level=logging.FATAL)。这将禁用处于致命状态的所有日志。它不会禁用打印,但是,是一个想法:/

编辑:我意识到不给我使用的文档提供链接是我的自私:) https://docs.python.org/3/howto/logging.html#logging-basic-tutorial


-2

第一点:根据Flask官方文档,您不应使用app.run()运行Flask应用程序。最好的解决方案是使用uwsgi,因此您可以使用命令“ --disable-logging”禁用默认的烧瓶日志

例如:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.