Python 日志记录 - 禁用导入模块的日志记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35325042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 16:17:57  来源:igfitidea点击:

Python Logging - Disable logging from imported modules

pythonlogging

提问by blindsnowmobile

I'm using the Python logging module, and would like to disable log messages printed by the third party modules that I import. For example, I'm using something like the following:

我正在使用 Python 日志记录模块,并希望禁用由我导入的第三方模块打印的日志消息。例如,我正在使用以下内容:

logger = logging.getLogger()
logger.setLevel(level=logging.DEBUG)
fh = logging.StreamHandler()
fh_formatter = logging.Formatter('%(asctime)s %(levelname)s %(lineno)d:%(filename)s(%(process)d) - %(message)s')
fh.setFormatter(fh_formatter)
logger.addHandler(fh)

This prints out my debug messages when I do a logger.debug("my message!"), but it also prints out the debug messages from any module I import (such as requests, and a number of other things).

这会在我执行 logger.debug("my message!") 时打印出我的调试消息,但它也会打印出我导入的任何模块(例如请求和许多其他内容)中的调试消息。

I'd like to see only the log messages from modules I'm interested in. Is it possible to make the logging module do this?

我只想查看来自我感兴趣的模块的日志消息。是否可以让日志模块执行此操作?

Ideally, I'd like to be able tell the logger to print messages from "ModuleX, ModuleY" and ignore all others.

理想情况下,我希望能够告诉记录器打印来自“ModuleX、ModuleY”的消息并忽略所有其他消息。

I looked at the following, but I don't want to have to disable/enable logging before every call to an imported function: logging - how to ignore imported module logs?

我查看了以下内容,但我不想在每次调用导入函数之前都禁用/启用日志记录: 日志记录 - 如何忽略导入的模块日志?

采纳答案by Bakuriu

The problem is that calling getLoggerwithout arguments returns the rootlogger so when you set the level to logging.DEBUGyou are also setting the level for other modules that use that logger.

问题是getLogger不带参数的调用会返回记录器,因此当您将级别设置为时,logging.DEBUG您也在为使用该记录器的其他模块设置级别。

You can solve this by simply notusing the root logger. To do this just pass a name as argument, for example the name of your module:

您可以通过使用根记录器来解决此问题。为此,只需传递一个名称作为参数,例如您的模块的名称:

logger = logging.getLogger('my_module_name')
# as before

this will create a new logger and thus it wont inadvertently change logging level for other modules.

这将创建一个新的记录器,因此它不会无意中更改其他模块的日志记录级别。



Obviously you have to use logger.debuginstead of logging.debugsince the latter is a convenience function that calls the debugmethod of the root logger.

显然你必须使用logger.debug而不是logging.debug因为后者是一个调用debug根记录器方法的便利函数。

This is mentioned in the Advanced Logging Tutorial. It also allows you to know which module triggered the log message in a simple way.

高级日志记录教程中提到了这一点。它还允许您以简单的方式知道哪个模块触发了日志消息。

回答by apex-meme-lord

@Bakuriu quite elegantly explains the function. Conversely, you can use the getLogger()method to retrieve and reconfigure/disable the unwanted loggers.

@Bakuriu 非常优雅地解释了该功能。相反,您可以使用该getLogger()方法来检索和重新配置/禁用不需要的记录器。

I also wanted to add the logging.fileConfig()method accepts a parameter called disable_existing_loggerswhich will disable any loggers previously defined (i.e., in imported modules).

我还想添加该logging.fileConfig()方法接受一个调用的参数disable_existing_loggers,该参数将禁用先前定义的任何记录器(即,在导入的模块中)。

回答by Brendan Abel

If you're going to use the python loggingpackage, it's a common convention to define a logger in every module that uses it.

如果你打算使用 pythonlogging包,那么在使用它的每个模块中定义一个记录器是一个常见的约定。

logger = logging.getLogger(__name__)

Many popular python packages do this, including requests. If a package uses this convention, it's easy to enable/disable logging for it, because the logger name will be the same name as the package (or will be a child of that logger). You can even log it to the same file as your other loggers.

许多流行的 python 包都这样做,包括requests. 如果包使用此约定,则很容易为其启用/禁用日志记录,因为记录器名称将与包名称相同(或将是该记录器的子项)。您甚至可以将其记录到与其他记录器相同的文件中。

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

requests_logger = logging.getLogger('requests')
requests_logger.setLevel(logging.DEBUG)

handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
requests_logger.addHandler(handler)

回答by avv

This disables all existing loggers, such as those created by imported modules, while still using the root logger (and without having to load an external file).

这将禁用所有现有记录器,例如由导入模块创建的记录器,同时仍然使用根记录器(并且无需加载外部文件)。

logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': True,
})

Note that you need to import all modules you don't want logged first!Otherwise those won't be considered as "existing loggers". It will then disable all loggers from those modules. This might lead you to also miss out on important errors!

请注意,您需要先导入所有不想记录的模块!否则,这些不会被视为“现有记录器”。然后它将禁用这些模块中的所有记录器。这可能会导致您也错过重要的错误!

For more detailed examples using related options for configuration, see https://gist.github.com/st4lk/6287746, and hereis a (partially working) example using YAML for config with the coloredloglibrary.

有关使用相关配置选项的更详细示例,请参阅https://gist.github.com/st4lk/6287746这里是使用 YAML 进行coloredlog库配置的(部分工作)示例。

回答by Finn

Not sure if this is appropriate to post, but I was stuck for a long time & wanted to help out anyone with the same issue, as I hadn't found it anywhere else!

不确定这是否适合发布,但我被困了很长时间并想帮助任何有同样问题的人,因为我没有在其他任何地方找到它!

I was getting debug logs from matplotlib despite following the pretty straightforward documentation at the logging advanced tutorialand the troubleshooting. I was initiating my logger in main()of one file and importing a function to create a plot from another file (where I had imported matplotlib).

尽管遵循日志高级教程故障排除中非常简单的文档,我还是从 matplotlib 获取调试日志。我在main()一个文件中启动我的记录器并导入一个函数以从另一个文件(我在其中导入 matplotlib)创建绘图。

What worked for me was setting the level of matplotlib beforeimporting it, rather than after as I had for other modules in my main file. This seemed counterintuitive to me so if anyone has insight into how you can set the config for a logger that hasn't been imported yet I'd be curious to find out how this works. Thanks!

对我有用的是导入之前设置 matplotlib 的级别,而不是像我在主文件中的其他模块那样设置之后。这对我来说似乎违反直觉,所以如果有人了解如何为尚未导入的记录器设置配置,我很想知道这是如何工作的。谢谢!

In my main file:

在我的主文件中:

import logging
import requests
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logging.getLogger('requests').setLevel(logging.DEBUG)

def main():
  ...

In my plot.pyfile:

在我的plot.py文件中:

import logging
logging.getLogger('matplotlib').setLevel(logging.WARNING)
import matplotlib.pyplot as plt

def generatePlot():
  ...

回答by Kamiku

You could use something like:

你可以使用类似的东西:

logging.getLogger("imported_module").setLevel(logging.WARNING)
logging.getLogger("my_own_logger_name").setLevel(logging.DEBUG)

This will set my own module's log level to DEBUG, while preventing the imported module from using the same level.

这会将我自己的模块的日志级别设置为 DEBUG,同时防止导入的模块使用相同的级别。

Note: "imported_module"can be replaced with imported_module.__name__(without quotes), and "my_own_logger_name"can be replaced by __name__if that's the way you prefer to do it.

注意: "imported_module"可以替换为imported_module.__name__(不带引号),如果您喜欢这样做,"my_own_logger_name"可以替换为__name__

回答by Aseem

I had the same problem. I have a logging_config.py file which I import in all other py files. In logging_config.py file I set root logger logging level to ERROR (by default its warning):

我有同样的问题。我有一个 logging_config.py 文件,我将其导入到所有其他 py 文件中。在 logging_config.py 文件中,我将根记录器日志记录级别设置为 ERROR(默认情况下为警告):

logging.basicConfig(
    handlers=[
        RotatingFileHandler('logs.log',maxBytes=1000, backupCount=2),
        logging.StreamHandler(), #print to console
    ],
    level=logging.ERROR
)

In other modules I import logging_config.py and declare a new logger and set its level to debug:

在其他模块中,我导入 logging_config.py 并声明一个新的记录器并将其级别设置为调试:

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

This way everything I log in my py files is logged, but stuff logged at debug and info level by imported modules like urllib, request,boto3 etc is not logged. If there is some error in those import module then its logged, since I set root loggers level to ERROR.

这样,我在 py 文件中登录的所有内容都会被记录,但不会记录由导入模块(如 urllib、request、boto3 等)在调试和信息级别记录的内容。如果这些导入模块中存在一些错误,则将其记录下来,因为我将根记录器级别设置为 ERROR。