Logging 无法在Flask中使用Python登录子模块

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

我的Flask项目布局有两个文件夹-前进和后退。Fro是我的Flask应用程序,“back”是包含我的Flask应用程序调用的文件/模块的服务层

我的问题是,在输出控制台上记录以Fro编写的函数中的日志语句时,在服务层中编写的函数中的日志语句不会显示在日志输出中

我已尝试禁用默认的flask.logger,但似乎没有帮助

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)
in
back.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