在Python中,是否有任何方法可以根据记录器的名称设置日志级别?

huangapple go评论63阅读模式
英文:

In python, is there any way to set the LOG level based on the logger's name?

问题

让我们考虑一个名为"foo"的Python 3包。我已经定义了一个根记录器(root logger)和一个流处理器(stream handler),每当我在不同的模块中创建一个记录器时,我都调用logging.getLogger(__ name__)。

我还使用了一些第三方库。

我原本只希望看到自己的日志,其中记录器的名称为"foo.A"之类的。但除了这些日志之外,我还收到了第三方库的日志,这些日志的记录器名称为"urllib3.connectionpool"或"asyncio"之类的。

我想要能够设置这些记录器的日志级别。

我尝试创建这些记录器的父记录器,并逐个设置日志级别。例如:

urllib3_logger = logging.getLogger("urllib3")
urllib3_logger.setLevel("WARNING")

这可以实现,但我想使用某种正则表达式来为每个不以"foo"开头的记录器设置"WARNING"级别。您有任何想法我该如何实现这一点?

英文:

Let's consider a python3 package called "foo". I have defined a root logger, a stream handler and each time I create a logger in different modules I call logging.getLogger(__ name__).
I use some third-party libraries too.

I was expecting only to see my own logs with logger names such as "foo.A". But, in addition to those logs, I am also getting third-party logs of the libraries with loggers names such as: "urllib3.connectionpool" or "asyncio".

I would like to be able to set the LOG level of those loggers.

I have tried to create parent loggers for those and set the log level one by one. For example:

urllib3_logger = logging.getLogger("urllib3")
urllib3_logger.setLevel("WARNING")

It works, but I would like to use some kind of regex to do it for every logger. For example set "WARNING" level for any logger for whose name does not start with "foo".

Do you have any idea how could I achieve this?

答案1

得分: 1

logging库不直接支持正则表达式用于记录器名称,我们可以将根记录器的级别设置为WARNING,然后将您的应用程序记录器的级别设置为较低级别,类似以下方式:

import logging

root_logger = logging.getLogger()
root_logger.setLevel(logging.WARNING)

my_logger = logging.getLogger('foo')
my_logger.setLevel(logging.INFO)

third_party_logger = logging.getLogger('urllib3')

handler = logging.StreamHandler()
root_logger.addHandler(handler)
my_logger.addHandler(handler)
third_party_logger.addHandler(handler)

my_logger.info("This will print because its level is INFO")
third_party_logger.info("This will not print because its level is WARNING")
英文:

logging library doesn't directly support regular expressions for logger names, we could set the root logger's level to WARNING and then set your application's logger level to a lower level, something like the following

import logging

root_logger = logging.getLogger()
root_logger.setLevel(logging.WARNING)

my_logger = logging.getLogger('foo')
my_logger.setLevel(logging.INFO)

third_party_logger = logging.getLogger('urllib3')

handler = logging.StreamHandler()
root_logger.addHandler(handler)
my_logger.addHandler(handler)
third_party_logger.addHandler(handler)

my_logger.info("This will print because its level is INFO")
third_party_logger.info("This will not print because its level is WARNING")

答案2

得分: 1

这是一个小的演示,它假定:

  • 唯一具有处理程序(或处理程序)的记录器是根记录器
  • 所有其他记录器都是以 "propagate" 设置为 true 创建的(这是默认值)

然后,所有消息都使用根记录器的处理程序发出,并且您可以向该处理程序添加一个过滤器(不是向记录器添加,它不会对传播的消息调用)。

import logging

def rootfilter(record):
    name = record.name
    if name == 'foo' or name.startswith('foo.'):
        level = logging.DEBUG
    else:
        level = logging.WARNING
    # --仅用于测试--
    if record.levelno < level:
        print(f"rejecting {record}")
    # --结束--
    return record.levelno >= level

root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.addFilter(rootfilter)
root_logger.addHandler(handler)

my_logger = logging.getLogger('foo')
other_logger = logging.getLogger('other')

my_logger.info("foo INFO")
other_logger.info("other INFO")
other_logger.warning("other WARNING")
英文:

Here is a little demo, it assumes:

  • the only logger with a handler (or handlers) is the
    root logger
  • all ohter loggers are created with 'propagate' set to true
    (this is the default)

Then all messages are emitted with the root logger's handler and you can add a filter to that handler (not to the logger, it won't be called for propagated messages)

import logging

def rootfilter(record):
    name = record.name
    if name == &#39;foo&#39; or name.startswith(&#39;foo.&#39;):
        level = logging.DEBUG
    else:
        level = logging.WARNING
    # --testing only--
    if record.levelno &lt; level:
        print(f&quot;rejecting {record}&quot;)
    # --end--
    return record.levelno &gt;= level

root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.addFilter(rootfilter)
root_logger.addHandler(handler)

my_logger = logging.getLogger(&#39;foo&#39;)
other_logger = logging.getLogger(&#39;other&#39;)

my_logger.info(&quot;foo INFO&quot;)
other_logger.info(&quot;other INFO&quot;)
other_logger.warning(&quot;other WARNING&quot;)

huangapple
  • 本文由 发表于 2023年6月13日 17:47:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76463632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定