10

我想将特定记录器名称的消息记录INFO到特定的日志处理程序,比如文件处理程序,同时仍将所有日志消息发送到控制台。Python 是 2.7 版。

到目前为止,我尝试的是创建两个记录器:

  • 根记录器
  • 命名记录器

对于根记录器,我附加了一个logging.StreamHandler,并将日志级别设置为logging.DEBUG

然后我将一个处理程序附加到命名的记录器并logging.INFO为该记录器设置级别。

当我现在调用使用命名记录器的模块时,我不再将DEBUG日志传播到根记录器。

注意:extraLogger 在这里有一个StreamHandler来演示这个问题。在我的生产代码中,我会使用FileHandler

import logging

def do_logging(turn):
    logger = logging.getLogger('extra')
    logger.info('some info turn %d' % turn) 
    logger.debug('this is debug fudge turn %d' % turn)

rootLogger = logging.getLogger()
handler = logging.StreamHandler()
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s')
handler.setFormatter(rootFormatter)
rootLogger.addHandler(handler)
rootLogger.setLevel(logging.DEBUG)

do_logging(1)

extraLogger = logging.getLogger('extra')
extraHandler = logging.StreamHandler()
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s')
extraHandler.setFormatter(extraFormatter)
extraLogger.addHandler(extraHandler)
extraLogger.setLevel(logging.INFO)

do_logging(2)

实际输出:

root - INFO: some info turn 1
root - DEBUG: this is debug fudge turn 1
extra - INFO: some info turn 2
root - INFO: some info turn 2

我想要的输出:

root - INFO: some info turn 1
root - DEBUG: this is debug fudge turn 1
extra - INFO: some info turn 2
root - INFO: some info turn 2
root - DEBUG: this is debug fudge turn 2

我怀疑Filter在这种情况下习惯会有所帮助,但我不知道如何......

4

3 回答 3

6

你可以像这样使用robert 的 LevelFilter

# Put the Filter on the Handler so only INFO and higher is handled
extraHandler.addFilter(LevelFilter(logging.INFO))

# Let the Logger process everything (so it can propagate records to root)
extraLogger.setLevel(logging.DEBUG)

import logging

class LevelFilter(logging.Filter):
    """
    https://stackoverflow.com/a/7447596/190597 (robert)
    """
    def __init__(self, level):
        self.level = level

    def filter(self, record):
        return record.levelno >= self.level

def do_logging(turn):
    logger = logging.getLogger('extra')
    logger.info('some info turn %d' % turn) 
    logger.debug('this is debug fudge turn %d' % turn)

rootLogger = logging.getLogger()
handler = logging.StreamHandler()
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s')
handler.setFormatter(rootFormatter)
rootLogger.addHandler(handler)
rootLogger.setLevel(logging.DEBUG)
do_logging(1)

extraLogger = logging.getLogger('extra')
extraHandler = logging.StreamHandler()
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s')
extraHandler.setFormatter(extraFormatter)
extraLogger.addHandler(extraHandler)

# Put the Filter on the Handler so only INFO and higher is handled
extraHandler.addFilter(LevelFilter(logging.INFO))

# Handle everything (so it can propagate to root)
extraLogger.setLevel(logging.DEBUG)
do_logging(2)
于 2013-08-05T13:32:16.957 回答
2

logger 类中有一个名为“propagate”的方法,它似乎可以满足您的要求:http ://docs.python.org/2/library/logging.html#logger-objects

于 2013-08-05T13:28:25.880 回答
1

传播

如果此属性评估为 true,则记录到此记录器的事件将传递给更高级别(祖先)记录器的处理程序,以及附加到此记录器的任何处理程序。消息直接传递给祖先记录器的处理程序 - 既不考虑所讨论的祖先记录器的级别也不考虑过滤器。

如果计算结果为 false,则日志消息不会传递给祖先记录器的处理程序。

请访问官方 python站点以获取有关此的详细讨论。

禁用传播消息

import logging

handler = logging.StreamHandler()

parent = logging.getLogger("parent")
parent.addHandler(handler)
child = logging.getLogger("parent.child")
child.propagate = False

child.setLevel(logging.DEBUG)
child.addHandler(handler)

child.info("你好")

输出:

$ python3.10 propagate.py 
HELLO

不禁用传播消息的代码

import logging

handler = logging.StreamHandler()

parent = logging.getLogger("parent")
parent.addHandler(handler)
child = logging.getLogger("parent.child")
#child.propagate = False

child.setLevel(logging.DEBUG)
child.addHandler(handler)


child.info("HELLO")

输出:

$ python3.10 propagate.py 
HELLO
HELLO
于 2022-02-12T03:31:56.450 回答