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
Python Logging - Disable logging from imported modules
提问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 getLogger
without arguments returns the rootlogger so when you set the level to logging.DEBUG
you 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.debug
instead of logging.debug
since the latter is a convenience function that calls the debug
method 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_loggers
which 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 logging
package, 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 coloredlog
library.
有关使用相关配置选项的更详细示例,请参阅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.py
file:
在我的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。