簡體   English   中英

使用 logging.info 而不是 logger.info 破壞 StreamHandler

[英]Using logging.info instead of logger.info wrecks StreamHandler

我正在使用兩個日志處理程序。 一個到 DEBUG 及以上級別的文件,另一個到 WARNING 及以上級別的控制台。 我正在使用許多模塊,其中一些是外部模塊(使用 pip 安裝)。 當調用logging.info() (而不是logger.info() )時,這會破壞控制台記錄器的設置:

import logging
import logging.handlers
import sys, os
from demo_module import something, something_else

logger = logging.getLogger("demo")
logger.setLevel(logging.DEBUG)
main_handler = logging.FileHandler('demo.log')
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)-8s %(filename)s:%(lineno)d %(message)s')
main_handler.setFormatter(formatter)
logger.addHandler(main_handler)

# log serious issues to console
console_handler = logging.StreamHandler(stream=sys.stderr)
console_handler.setLevel(logging.WARNING)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
logger.debug('this is a debug')
logger.info('this is an info')
logger.warning('this is a warning')
logger.error('this is an error')
logger.critical('reactor has melted down')
something()
logger.info('after something')
something_else()
logger.info('after something else')

demo_module.py 在哪里:

import logging
logger = logging.getLogger('demo')

def something():
    logger.info('something needs to be done')
    a = 1+1
    logger.info('something has been done')
    logger.error('some banale error')

def something_else():
    logger.info('calling logger.info')
    # OOPS, calling logging instead of logger here
    logging.info("module may use logging directly instead of logger")
    logger.info('logger.info called')

如您所見,在demo_module.something_else()內部調用了logging.info而不是logger.info

控制台的輸出如下所示:

% python logger.py 
2017-10-07 17:45:08,077 demo WARNING  logger2.py:21 this is a warning
2017-10-07 17:45:08,077 demo ERROR    logger2.py:22 this is an error
2017-10-07 17:45:08,077 demo CRITICAL logger2.py:23 reactor has melted down
2017-10-07 17:45:08,078 demo ERROR    demo_module.py:8 some banale error
INFO:demo:logger.info called
INFO:demo:after something else

如您所見,最后兩行丟失了我最初為控制台處理程序設置的所有設置,例如級別和格式化程序。 如果只是我的代碼,我可以找到這個有問題的logging.info()語句並替換它,但有些代碼不是我的而是第三方的,因此超出了我的控制范圍。 知道如何使這些設置堅持下去嗎?

默認情況下,模塊級日志函數將調用logging.basicConfig()來嘗試配置根記錄器。 文檔

... 委托給根記錄器的模塊級便利函數調用 basicConfig() 以確保至少有一個處理程序可用。

logging.basicConfig文檔狀態:

如果根記錄器已經為其配置了處理程序,則此函數不執行任何操作。

因此,解決方案是在調用任何模塊級日志函數之前在根記錄器上配置處理程序,同時還指示您的記錄器不要在記錄器層次結構中向上傳播消息,以避免重復輸出。

import logging
import logging.handlers
import sys, os
from demo import something, something_else

formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)-8s %(filename)s:%(lineno)d %(message)s')

# Configure the root logger.
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
# Configure file handler.
root_main_handler = logging.FileHandler('demo.log')
root_main_handler.setFormatter(formatter)
root_logger.addHandler(root_main_handler)
# Configure console handler.
root_console_handler = logging.StreamHandler(stream=sys.stderr)
root_console_handler.setLevel(logging.WARNING)
root_console_handler.setFormatter(formatter)
root_logger.addHandler(root_console_handler)

logger = logging.getLogger("demo")
logger.setLevel(logging.DEBUG)
main_handler = logging.FileHandler('demo.log')
main_handler.setFormatter(formatter)
logger.addHandler(main_handler)

# log serious issues to console
console_handler = logging.StreamHandler(stream=sys.stderr)
console_handler.setLevel(logging.WARNING)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# Don't propagate messages up to the root logger.
logger.propagate = False
logger.debug('this is a debug')
logger.info('this is an info')
logger.warning('this is a warning')
logger.error('this is an error')
logger.critical('reactor has melted down')
something()
logger.info('after something')
something_else()
logger.info('after something else')

控制台輸出:

2017-10-07 18:46:50,644 demo WARNING  run.py:35 this is a warning
2017-10-07 18:46:50,644 demo ERROR    run.py:36 this is an error
2017-10-07 18:46:50,644 demo CRITICAL run.py:37 reactor has melted down
2017-10-07 18:46:50,645 demo ERROR    demo.py:8 some banale error

文件輸出:

2017-10-07 18:46:50,644 demo DEBUG    run.py:33 this is a debug
2017-10-07 18:46:50,644 demo INFO     run.py:34 this is an info
2017-10-07 18:46:50,644 demo WARNING  run.py:35 this is a warning
2017-10-07 18:46:50,644 demo ERROR    run.py:36 this is an error
2017-10-07 18:46:50,644 demo CRITICAL run.py:37 reactor has melted down
2017-10-07 18:46:50,645 demo INFO     demo.py:5 something needs to be done
2017-10-07 18:46:50,645 demo INFO     demo.py:7 something has been done
2017-10-07 18:46:50,645 demo ERROR    demo.py:8 some banale error
2017-10-07 18:46:50,645 demo INFO     run.py:39 after something
2017-10-07 18:46:50,645 demo INFO     demo.py:11 calling logger.info
2017-10-07 18:46:50,645 root INFO     demo.py:13 module may use logging directly instead of logger
2017-10-07 18:46:50,645 demo INFO     demo.py:14 logger.info called
2017-10-07 18:46:50,645 demo INFO     run.py:41 after something else

暫無
暫無

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

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