簡體   English   中英

Python記錄器忽略類中的FileHandler和StreamHandler級別

[英]Python logger ignores FileHandler and StreamHandler levels in class

我正在嘗試為日志文件和流設置不同的記錄器級別,並且(似乎)已將演示( https://docs.python.org/3/howto/logging-cookbook.html )跟蹤到了點。 但是,在我的實際代碼中,它不起作用。 只需在測試腳本中運行此演示即可:

import logging

logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

print(logger.handlers)
print(logger)

結果是

alex@alexpc:~/Projects/claritydb$ python test.py ; cat spam.log
2019-09-16 11:53:44,293 - simple_example - ERROR - error message
2019-09-16 11:53:44,293 - simple_example - CRITICAL - critical message
[<StreamHandler <stderr> (ERROR)>, <FileHandler /home/Projects/claritydb/spam.log (DEBUG)>]
<Logger simple_example (DEBUG)>
2019-09-16 11:53:44,293 - simple_example - DEBUG - debug message
2019-09-16 11:53:44,293 - simple_example - INFO - info message
2019-09-16 11:53:44,293 - simple_example - WARNING - warn message
2019-09-16 11:53:44,293 - simple_example - ERROR - error message
2019-09-16 11:53:44,293 - simple_example - CRITICAL - critical message

但這由於某種原因將無法在實際代碼中正確執行:

class MyClass(object):

    def __init__(self,
                 verbosity_stream="WARNING", 
                 verbosity_log="INFO"):

        self.logger = self.setup_logger(verbosity_stream=verbosity_stream, verbosity_log=verbosity_log)

    def setup_logger(self, verbosity_stream="ERROR", verbosity_log="WARNING"):

        # Create a custom logger

        logger = logging.getLogger(f"do_stuff")
        logger.setLevel(logging.DEBUG)

        fh = logging.FileHandler(f"do_stuff.log", mode='w')
        fh.setLevel(getattr(logging, verbosity_log))

        ch = logging.StreamHandler()
        ch.setLevel(getattr(logging, verbosity_stream))

        # create formatter and add it to the handlers
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        ch.setFormatter(formatter)
        fh.setFormatter(formatter)

        # add the handlers to the self.logger
        logger.addHandler(ch)
        logger.addHandler(fh)

        print(logger.handlers)

        return logger

self.logger的任何調用都將輸出到控制台和logging.DEBUG級別的日志文件,這顯然不是我想要的。 我對丟失的內容感到非常困惑,因為當我問主要方法時,我得到了它的文件處理程序是什么

print(self.logger.handlers)
print(self.logger)
[<StreamHandler <stderr> (ERROR)>, <FileHandler /home/Projects/claritydb/do_stuff.log (DEBUG)>]
<Logger do_stuff (DEBUG)>

這與測試用例相同,但是在控制台和日志文件中都有所有信息級別的輸出。 更改我的handler.setLevel命令對輸出沒有影響,唯一改變的是將setLevel命令更改為定義頂部的初始記錄器調用(即ch.setLevel和fh.setLevel不起作用) ,但logger.setLevel確實存在[而且我認為它應該只是初始過濾器)。

這真讓我發瘋,有人知道嗎?

EDIT1:更改

logger = logging.getLogger(f"do_stuff")

線到

logger = logging.getLogger()

似乎可以解決問題,但我不知道為什么...

當您調用logger = logging.getLogger()您將獲得根記錄器,然后追加處理程序並設置其級別,依此類推。 當您執行logger = logging.getLogger(f"do_stuff")您會得到一個名為do_stuff的記錄器,但根記錄器仍然存在,並且新創建的記錄器會將其日志傳播到根記錄器處理程序。 因為在那種情況下,根記錄器沒有添加任何處理程序,所以它使用默認的logging.lastResort及其默認級別。 您可以通過多種方式解決此問題。 一種簡單的解決方案是設置logger.propagate = False

您也不需要此fh.setLevel(getattr(logging, verbosity_log)) Python可以直接處理傳入的字符串。

暫無
暫無

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

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