Logging 无法在Flask中使用Python登录子模块
我的Flask项目布局有两个文件夹-前进和后退。Fro是我的Flask应用程序,“back”是包含我的Flask应用程序调用的文件/模块的服务层 我的问题是,在输出控制台上记录以Fro编写的函数中的日志语句时,在服务层中编写的函数中的日志语句不会显示在日志输出中 我已尝试禁用默认的flask.logger,但似乎没有帮助Logging 无法在Flask中使用Python登录子模块,logging,flask,python-3.5,Logging,Flask,Python 3.5,我的Flask项目布局有两个文件夹-前进和后退。Fro是我的Flask应用程序,“back”是包含我的Flask应用程序调用的文件/模块的服务层 我的问题是,在输出控制台上记录以Fro编写的函数中的日志语句时,在服务层中编写的函数中的日志语句不会显示在日志输出中 我已尝试禁用默认的flask.logger,但似乎没有帮助 app.logger.disabled = True logger = logging.getLogger('werkzeug') logger.disabled = True
app.logger.disabled = True
logger = logging.getLogger('werkzeug')
logger.disabled = True
下面是app.py中的代码-
import os
from flask import Flask
import click
import logging
log = logging.getLogger(__name__)
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.logger.info("This gets printed")
configure(app)
app.logger.info("This also gets printed")
# bunch of code
# ...
return app
下面是route方法的样子-
import logging
from back.services import request_service
log = logging.getLogger(__name__)
@bp.route('/install', methods=('GET', 'POST'))
def install():
log.info("This gets printed")
is_valid_request = request_service.check_request_authenticity(request)
return str(is_hmac_valid)
请求服务中的检查请求真实性功能如下所示-
import logging
log = logging.getLogger(__name__)
def check_request_authenticity():
log.info("However this DOES NOT get printed")
我希望能够使用本机python日志记录来登录服务层中的函数,而不必将flask app.logger传递给服务层中的函数
有什么指点吗?我给你弄来了
为什么有效
问题在于记录器,在app.py
中,您的日志工作正常,因为:
log = logging.getLogger(__name__)
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.logger.info("This gets printed")
configure(app)
app.logger.info("This also gets printed")
# bunch of code
# ...
return app
log
和app.logger
是同一个记录器,因为您向记录器和Flask
对象传递了相同的\uuuuuuu名称
当您执行app.logger
时,Flask
将使用已实例化的\uuuuu名称\uuuuuuuu
创建该记录器。但是,由于您以前创建过该记录器,因此在执行以下操作时:log=logging.getLogger(\uuuu name\uuuuu)
,Flask
将看到它存在,并且将只获取现有记录器,并向其添加处理程序,以及具有日期、时间和文件名的良好格式,产生以下形式的日志
:
INFO:fro.app:This gets printed
INFO:fro.app:This also gets printed
INFO:back.services:However this DOES get printed
[2019-09-15 12:51:47534]应用程序中的信息:这会被打印出来
Flask
还将该记录器的级别设置为logging.DEBUG
,这就是.info()
调用工作的原因
如果在调用app.logger.info()
之前执行log.info('Whats poppin cuz')
,您将看到它不会向控制台打印任何内容,因为所使用的默认日志记录级别将是根级别的警告级别(请记住这一点,因为在本说明中,它将是有价值的信息)
问题
继续,当您在back.services
中执行log=logging.getLogger(\uuu name\uuuu)
时,
您创建了另一个名为back.services
的记录器,它与上面创建的fro.app
记录器无关(因此禁用该记录器不会影响此记录器)
这意味着,当您这样做时:
log.info(“但是不会打印”)
它会将此消息一直传播到根日志记录器,根日志记录器的默认级别为,您从上面猜到,警告,并且只有大于或等于警告的消息才会被注销。看所有的照片
如果将log.info()
替换为log.warning()
,您将看到它将被打印出来。但是,与flask logger不同的是,消息的格式不好,只能打印出消息的基本内容
解决
解决方案1
现在我明白了,您不想在所有模块中传递app.logger
对象,但您不必这样做。利用该记录器所要做的就是获取它,而不传递任何对象,然后使用python本机日志记录机制和具有良好格式的flask对象,因为python日志记录机制就是这样工作的。一旦创建了一个记录器,使用该名称的任何其他调用都将只获取该记录器,而不是再次创建它
因此,与其这样做
log=logging.getLogger(\uuuuu name\uuuuuuuuuuuuuuuuuuuuuuuuuuu)
inback.services
照办
log=logging.getLogger('fro.app')
(或者在create\u app
函数中实例化Flask
对象的值中的任何值),您将看到消息的格式和打印效果如何
确保您尽早调用app.logger
(基本上就像您在创建Flask对象后或在app.py
中的某个地方所做的那样),以便Flask可以正确设置记录器
解决方案2
如果您根本不想在任何地方使用app.logger
,只需尽早调用logging.basicConfig(level=DEBUG)
,您就会在整个应用程序的各个级别上看到所有消息
您可以继续根据模块名称实例化记录器,就像您现在所做的那样,即log=logging.getLogger(\uu name\uuu)
您的create\u应用程序可以是:
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
logging.basicConfig(level=logging.DEBUG) # this added here
app.logger.info("This gets printed")
app.logger.info("This also gets printed")
# more code below
return app
整个应用程序中的安装函数和记录器可以保持原样,并且日志的形式如下:
INFO:fro.app:This gets printed
INFO:fro.app:This also gets printed
INFO:back.services:However this DOES get printed
解决方案3
这是更高级的东西,您可以创建一个日志配置(通过dictConfig或fileConfig),并在应用程序启动时很早加载它,但这超出了本文的范围。你可以在本论坛的文档和其他答案中找到这方面的信息。我为你找到了fam
为什么有效
问题在于记录器,在app.py
中,您的日志工作正常,因为:
log = logging.getLogger(__name__)
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.logger.info("This gets printed")
configure(app)
app.logger.info("This also gets printed")
# bunch of code
# ...
return app
log
和app.logger
是同一个记录器,因为您向记录器和Flask
对象传递了相同的\uuuuuuu名称
当您执行app.logger
时,Flask
将使用已实例化的\uuuuu名称\uuuuuuuu
创建该记录器。但是,由于您以前创建过该记录器,因此在执行以下操作时:log=logging.getLogger(\uuuuu name\uuuuuuu)
,Flask
将