最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Flask的log输出异常:file和console中无法输出指定的level的log

Flask crifan 6747浏览 0评论

折腾:

【已解决】Flask中添加log且输出到文件中

期间,虽然可以在Flask中输出log了,但是却无法输出指定的level的log到对应的file文件和console终端中。

How to Write Error Log in Python Flask Web Application

Logging — Flask Documentation (0.13-dev)

“If app.logger is accessed before logging is configured, it will add a default handler”

所以应该是不用配置,可以直接使用才对的啊

logging is not working under Flask in Python 3 – Stack Overflow

python – Why does logging not work when running a Flask app with werkzeug? – Stack Overflow

算了,还是参考之前自己的配置,去添加此处吧

结果出错了:

【已解决】PyCharm中创建logger的RotatingFileHandler出错:FileNotFoundError Errno 2 No such file or directory

然后,虽然:

<code>import logging
from logging.handlers import RotatingFileHandler

FLASK_APP = "RobotQA"

LOG_FILE_FILENAME = "logs/" + FLASK_APP + ".log"
LOG_FILE_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

app.config['LOG_FILE_FILENAME'] = LOG_FILE_FILENAME
app.config["LOG_FILE_FORMAT"] = LOG_FILE_FORMAT

fileHandler = RotatingFileHandler(
    app.config['LOG_FILE_FILENAME'],
    maxBytes=2*1024*1024,
    backupCount=3,
    encoding="UTF-8")
fileHandler.setLevel(logging.DEBUG)

fileLogFormatterStr = app.config["LOG_FILE_FORMAT"]
fileLogFormatter = logging.Formatter(fileLogFormatterStr)
fileHandler.setFormatter(fileLogFormatter)
app.logger.addHandler(fileHandler)

log = app.logger
log.error("app=%s", app)
log.warning("app=%s", app)
log.debug("app=%s", app)
</code>

可以正常输出log到文件了,但是还是没有输出到PyCharm的debug的console中:

flask logging pycharm console

参考:

https://stackoverflow.com/questions/43852004/logging-is-not-working-under-flask-in-python-3

去试试:StreamHandler

结果是:

直接用StreamHandler,可以输出error和warning:

但是:

(1)多余的,之前那个error的输出,还存在

(2)额外的,info,debug没有输出

去加了debug的level也不行:

<code>streamHandler = logging.StreamHandler()
streamHandler.setLevel(logging.DEBUG)
app.logger.addHandler(streamHandler)

log = app.logger
log.error("error: app=%s", app)
log.warning("warning: app=%s", app)
log.debug("debug: app=%s", app)
log.info("info: app=%s", app)
</code>

console输出:

<code>[2018-04-18 16:13:00,546] ERROR in testRestApi: error: app=&lt;Flask 'testRestApi'&gt;
error: app=&lt;Flask 'testRestApi'&gt;
warning: app=&lt;Flask 'testRestApi'&gt;
</code>

flask logging  not output console

此处很怪的是:

<code>fileHandler.setLevel(logging.INFO)
fileHandler.setFormatter(logFormatter)
app.logger.addHandler(fileHandler)

streamHandler = logging.StreamHandler()
streamHandler.setFormatter(logFormatter)
streamHandler.setLevel(logging.DEBUG)
app.logger.addHandler(streamHandler)

log = app.logger
log.error("error: app=%s", app)
log.warning("warning: app=%s", app)
log.debug("debug: app=%s", app)
log.info("info: app=%s", app)
</code>

但是此处:

console和file中,竟然都只能输出:

warning和error的

debug和info都没有输出:

突然,调试期间发现:

app.logger,有自己的level,且是warning:

所以导致此处的file和console的level都没生效

flask app.logger level

昔我往矣 » Flask日志级别的问题 杨柳依依

果然是:

<code>app.logger.setLevel(logging.INFO)
</code>

Logging, Flask, and Gunicorn … the Manageable Way – Thomas Stringer – Medium

也是:

<code>if __name__ != ‘__main__’:
    gunicorn_logger = logging.getLogger(‘gunicorn.error’)
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)
</code>

python – Change Flask logs from INFO to DEBUG – Stack Overflow

结果:

<code>app = Flask(__name__)
app.logger.setLevel(logging.INFO) # set root log level
# logging.getLogger().setLevel(logging.DEBUG)
# app = Flask(__name__, instance_relative_config=True)
# app.config.from_object('config') # load config.py
# app.config.from_pyfile('config.py')
# app.debug = app.config["FLASK_DEBUG"]

FLASK_APP = "RobotQA"

LOG_FILE_FILENAME = "logs/" + FLASK_APP + ".log"
LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

app.config['LOG_FILE_FILENAME'] = LOG_FILE_FILENAME
app.config["LOG_FORMAT"] = LOG_FORMAT

logFormatterStr = app.config["LOG_FORMAT"]
logFormatter = logging.Formatter(logFormatterStr)

fileHandler = RotatingFileHandler(
    app.config['LOG_FILE_FILENAME'],
    maxBytes=2*1024*1024,
    backupCount=3,
    encoding="UTF-8")
fileHandler.setLevel(logging.INFO)
fileHandler.setFormatter(logFormatter)
app.logger.addHandler(fileHandler)

streamHandler = logging.StreamHandler()
streamHandler.setFormatter(logFormatter)
streamHandler.setLevel(logging.DEBUG)
app.logger.addHandler(streamHandler)

log = app.logger
log.error("error: app=%s", app)
log.warning("warning: app=%s", app)
log.debug("debug: app=%s", app)
log.info("info: app=%s", app)

api = Api(app)
log.info("api=%s", api)

</code>

竟然:

debug的log没有输出。。。

改了:

<code>fileHandler.setLevel(logging.DEBUG)
streamHandler.setLevel(logging.DEBUG)
</code>

还是不行。

去暂时先关闭掉Flask的debug选项:

<code>if __name__ == "__main__":
    # app.debug = True
    app.run()
</code>

结果:问题依旧。

然后继续研究了半天,终于搞懂了:

<code>import logging
from logging.handlers import RotatingFileHandler
# from flask_pymongo import PyMongo

app = Flask(__name__)

# app.logger.removeHandler(default_handler)

FLASK_APP = "RobotQA"

LOG_FILE_FILENAME = "logs/" + FLASK_APP + ".log"
LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

app.config['LOG_FILE_FILENAME'] = LOG_FILE_FILENAME
app.config["LOG_FORMAT"] = LOG_FORMAT

logFormatterStr = app.config["LOG_FORMAT"]
logFormatter = logging.Formatter(logFormatterStr)

fileHandler = RotatingFileHandler(
    app.config['LOG_FILE_FILENAME'],
    maxBytes=2*1024*1024,
    backupCount=3,
    encoding="UTF-8")
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(logFormatter)
app.logger.addHandler(fileHandler)

streamHandler = logging.StreamHandler()
streamHandler.setFormatter(logFormatter)
streamHandler.setLevel(logging.INFO)
app.logger.addHandler(streamHandler)

app.logger.setLevel(logging.DEBUG) # set root log level

log = app.logger
log.error("error: app=%s", app)
log.warning("warning: app=%s", app)
log.info("info: app=%s", app)
log.debug("debug: app=%s", app)

api = Api(app)
log.info("api=%s", api)

</code>

if __name__ == “__main__”:

    # app.debug = True

    app.run()

此处:

背景是:

<code>CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
</code>

注意到,DEBUG不是比INFO更严重的,而是INFO==verbose,比DEBUG输出更多的log的。

而这点,之前自己搞混了。

共有3个log(和对应level):

  • root的log(的level)

    • app.logger.setLevel(logging.DEBUG)

    • 设置了root的log的level是DEBUG

    • 表示后续的log,只能输出DEBUG级别以上的log

      • 这样才能保证后续的file和console的DEBUG以上的log可以输出

      • 如果root的log设置为更高的,比如:ERROR

        • 那么后续的file和console的,比如debug,info的log,就都无法输出了

  • console的stream的log:

    • streamHandler.setLevel(logging.INFO)

    • 表示 此处的console中,只输出比INFO更严重的log

      • 比如:WARN和ERROR)

  • file文件的log:

    • fileHandler.setLevel(logging.DEBUG)

    • 表示此处文件中只输出比DEBUG更严重的log

      • 比如:INFO,WARN,ERROR

所以此处可以输出:

即:

console中输出了INFO以上级别的log:info,warning,error

file中输出了DEBUG以上级别的log:debug,info,waring,error

转载请注明:在路上 » 【已解决】Flask的log输出异常:file和console中无法输出指定的level的log

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.184 seconds, using 22.12MB memory