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

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

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

如何禁用详细模式?

94733 次浏览

您可以将 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()

您可能希望更改日志记录输出的另一个原因是用于测试,并将服务器日志重定向到日志文件。

我也不能得到上面的建议工作,它看起来像日志设置作为应用程序启动的一部分。我能够让它工作通过改变日志级别 之后启动应用程序:

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

Unfortunately the * Running on localhost:9151 and the first health check is still printed to standard out, but when running lots of tests it cleans up the output a ton.

"So why log_names?", you ask. In my case there were some extra logs I needed to get rid of. I was able to find which loggers to add to log_names via:

from flask import Flask
app = Flask(__name__)


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

附注: 如果有一个 flaskapp.getLogger ()或者类似的东西就好了,这样在不同版本之间会更加健壮。有什么想法吗?

Some more key words: flask test log remove stdout output

感谢:

@ Drewes 解决方案大部分时间都有效,但在某些情况下,我还是倾向于得到 Werkzeug 日志。如果你真的不想看到它们,我建议你像那样关闭它。

from flask import Flask
import logging


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

对我来说,当 abort(500)升高时,它就失败了。

如果您正在使用 WSGI 服务器,请将日志设置为 Nothing

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

这个解决方案为您提供了一种方法来获得自己的打印和堆栈跟踪,但没有信息级别的日志从烧瓶吮吸作为 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

如果您确实不想让任何东西登录到 print ()语句旁边的控制台,蛮力的方法是使用 logging.basicConfig(level=logging.FATAL)。这将禁用所有处于“致命”状态的日志。它不会禁用打印,但是,只是一个想法:/

编辑: 我意识到,如果我不把链接放到我使用的文档中,那将是自私的:) https://docs.python.org/3/howto/logging.html#logging-basic-tutorial

To suppress Serving Flask app ...:

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

回答晚了,但我找到了一种方法来禁止每个和每个控制台消息(包括在 abort(...)错误期间显示的消息)。

import os
import logging


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

这基本上是由 斯拉瓦五世Tom Wojcik给出的答案的组合

其他的答案对我来说都不正确,但是我找到了一个基于 Peter 的评论的解决方案。烧瓶显然不再使用 logging进行日志记录,并已切换到 点击包。通过重写 click.echoclick.secho,我从 app.run()中消除了 Flask 的启动消息。

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 方法之间,应该防止所有非错误日志输出。

The first point: In according to official Flask documentation, you shouldn't run Flask application using app.run(). The best solution is using uwsgi, so you can disable default flask logs using command "--disable-logging"

例如:

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

我花了很长时间试图用所有不同的解决方案来消除这些响应日志,但结果并不是 Flask/Werkzeug,而是转储在 stderr 上的 Gunicorn 访问日志..。

解决方案是将默认访问日志处理程序替换为 NullHandler,方法是在 Gunicorn 配置文件中添加以下代码块:

logconfig_dict = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {"class": "logging.StreamHandler", "level": "INFO"},
"null": {"class": "logging.NullHandler"},
},
"loggers": {
"gunicorn.error": {"level": "INFO", "propagate": False, "handlers": ["console"]},
"gunicorn.access": {"level": "INFO", "propagate": False, "handlers": ["null"]},
},
}

不知怎么的,上面的选项,包括 .disabled = True,对我都不起作用。

不过,下面的方法奏效了:

logging.getLogger('werkzeug').setLevel(logging.CRITICAL)

在 Python 3.7.3下使用截至2021年11月的最新版本:

pip3 list | grep -E "(connexion|Flask|Werkzeug)"
connexion2               2.10.0
Flask                    2.0.2
Werkzeug                 2.0.2

下面是禁用所有日志记录的解决方案,包括在 werkzeg 2.1.0版本和更新版本中:

import flask.cli
flask.cli.show_server_banner = lambda *args: None


import logging
logging.getLogger("werkzeug").disabled = True

我现在的工作方法是在2022年到2010年让 Flask 闭嘴。

它禁用日志和启动横幅:

class WSServer:


...


@staticmethod
def _disabled_server_banner(*args, **kwargs):
"""
Mock for the show_server_banner method to suppress spam to stdout
"""
pass


def _run_server(self):
"""
Winds-up the server.
"""
# disable general logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.CRITICAL)
# disable start-up banner
from flask import cli
if hasattr(cli, "show_server_banner"):
cli.show_server_banner = self._disabled_server_banner
...