昔我往矣

Flask日志级别的问题

2017年03月26日

这也是个老问题,很早之前发现使用logging模块在flask里记录info日志记录不上,没在意,但是有时候习惯拿info级别在线调试服务的时候没有日志就很苦恼,网上关于设置日志级别的文档大多是错误的(不排除可能是flask版本差异导致的),花了点时间来研究怎么设置flask的日志级别。

表面现象

下面是一个最简单的flask + logging的demo代码,网上几乎都是这个版本,但是我这里就是运行不对:

from flask import Flask
from logging.handlers import RotatingFileHandler
import logging

app = Flask(__name__)
log_path = '/tmp/web.log'
handler = RotatingFileHandler(log_path, maxBytes=500000, backupCount=10)
handler.setLevel(logging.INFO)
formatter = logging.Formatter(
            "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s")
handler.setFormatter(formatter)
app.logger.addHandler(handler)

@app.route("/")
@app.route("/index")
def index():
    app.logger.info("log info level test")
    app.logger.error("log error level test")
    return "test logging in flask"

if __name__ == '__main__':
    app.run(port=8000)

我们使用了handler.setLevel(logging.INFO)语句来设置日志级别为INFO。使用如上的代码做测试,会发现日志里只记录了error级别的日志,而没有info级别的日志。但是如果添加如下的语句,开启flask调试模式,则可以会记录info级别的日志:

app.debug = True

抽丝剥茧

通过pdb来调试以上代码:

(Pdb) p app.logger.getEffectiveLevel()
30

发现,如果没有设置debug的时候,以上的getEffectiveLevel()函数返回的是30,如果设置了debug,该函数返回的是10。根据logging模块的官方文档http://python.usyiyi.cn/python_278/library/logging.html

Logger.getEffectiveLevel()
表明该logger的有效级别。

又根据该文档可以发现,日志级别对应的数值如下

CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

可见,我们在以上使用的handler.setLevel(logging.INFO)语句压根没生效。更进一步可以发现是由于Flask自带app.logger设置的level覆盖了handler设置的level。那么如何让我们自定义的日志级别生效呢?

拨云见日

既然Flask内置了app.logger,那我们只需要对app.logger,而不是对handler设置level即可吧,找到如下的语句可以用:

app.logger.setLevel(logging.INFO)

以后,修改日志级别便可以通过修改 app.logger.setLevel中的变量来修改了,也可以写入配置文件,通过程序启动时加载。

当前暂无评论 »

添加新评论 »