簡體   English   中英

Python 日志記錄:傳播級別低於當前記錄器級別的消息

[英]Python logging: propagate messages of level below current logger level

我想將特定記錄器名稱、特定級別和更高級別(比如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)

實際 Output:

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

我想要的 Output:

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在這種情況下會有所幫助,但我不知道如何......

您可以像這樣使用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)

傳播

如果此屬性評估為真,則記錄到此記錄器的事件將傳遞給更高級別(祖先)記錄器的處理程序,以及附加到此記錄器的任何處理程序。 消息直接傳遞給祖先記錄器的處理程序——既不考慮相關祖先記錄器的級別也不考慮過濾器。

如果這評估為 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("HELLO")

Output:

$ 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")

Output:

$ python3.10 propagate.py 
HELLO
HELLO

記錄器類中有一個名為“propagate”的方法似乎可以滿足您的要求: http//docs.python.org/2/library/logging.html#logger-objects

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM