为什么日志记录似乎需要每个模块中的处理程序才能打印到控制台?

时间:2014-05-06 05:03:15

标签: python logging

在我的程序中,我通常想要同时登录文件和屏幕。如果我导入一个模块,我希望在该模块的函数/类中调用logger也会导致记录到文件和屏幕。 Test_module_A执行此操作,test_module_B记录到文件但不记录屏幕。这是因为模块中的记录器传播到根记录器,通过basicConfig只设置为记录到文件?我只是想确保我正确使用日志记录,因为我要重写所有代码以使用这种类型的日志而不是" print。"展望未来,我只会使用日志记录而不是打印,因为我认为日志记录更灵活。这是个好主意吗?

main.py

import logging

logger = logging.getLogger(__name__)

task_file='temp.txt'
format_str = '%(asctime)s %(module)s %(levelname)s: %(message)s'
datefmt_str = '%m/%d/%Y %I:%M:%S%p'
logging.basicConfig(filename=task_file, format=format_str, datefmt=datefmt_str, 
                    level=logging.INFO)
console = logging.StreamHandler()
#console.setLevel(logging.INFO)
formatter = logging.Formatter(format_str)
formatter.datefmt = datefmt_str
console.setFormatter(formatter)
logger.addHandler(console)

logger.info("from main.py")
import test_module_A
import test_module_B

test_module_A.py

import logging

logger = logging.getLogger(__name__)
format_str = '%(asctime)s %(module)s %(levelname)s: %(message)s'
datefmt_str = '%m/%d/%Y %I:%M:%S%p'
console = logging.StreamHandler()
formatter = logging.Formatter(format_str)
formatter.datefmt = datefmt_str
console.setFormatter(formatter)
logger.addHandler(console)

logger.info("upon import of test_module_A")

test_module_B.py

import logging

logger = logging.getLogger(__name__)

logger.info("upon import of test_module_B")

运行main.py:

#screen output
05/06/2014 12:36:33AM main INFO: from main.py
05/06/2014 12:36:33AM test_module_A INFO: upon import of test_module_A

# test.txt
05/06/2014 12:36:33AM main INFO: from main.py
05/06/2014 12:36:33AM test_module_A INFO: upon import of test_module_A
05/06/2014 12:36:33AM test_module_B INFO: upon import of test_module_B

1 个答案:

答案 0 :(得分:1)

在每个模块中配置日志记录(添加处理程序等)并不是一个好习惯:这样做的方法就是

logger = logging.getLogger(__name__)

并根据需要在每个模块中进行实际日志记录调用,并且只在一个地方完成配置(在早期从主脚本调用)

if __name__ == '__main__':
    logging.basicConfig(level=..., format=..., ...) #or other configuration code
    handler = logging.FileHandler(...)
    # set formatters, filters etc.
    logging.getLogger().addHandler(handler) # add to root logger
    main()

basicConfig()调用向根记录器添加一个写入sys.stderr的处理程序,并与显式添加的FileHandler一起,将所有模块的日志写入屏幕和文件。