阅读日志记录HOWTO(https://docs.python.org/3/howto/logging.html)令我印象深刻,如果我配置了记录器,则随后可以通过logging.getLogger()
从工厂请求记录器,而python将知道如何获取记录器正确的记录器(我配置的记录器),一切都会自动进行,即,我不需要在代码中传递配置的记录器实例,我可以在需要的地方索要它。相反,我观察到了一些不同的东西。
文件log_tester.py
:
from util.logging_custom import SetupLogger
import logging
import datetime
def test():
logger = logging.getLogger()
logger.debug("In test()")
def main():
logger = SetupLogger("logger_test")
logger.setLevel(logging.DEBUG)
logger.info(f"now is {datetime.datetime.now()}", )
logger.debug("In main()")
test()
if __name__ == '__main__':
main()
文件util/logging_custom.py
:
import os
import time
import logging
from logging.handlers import RotatingFileHandler
def SetupLogger(name_prefix):
if not os.path.exists("log"):
os.makedirs("log")
recfmt = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s %(message)s')
handler = RotatingFileHandler(time.strftime(f"log/{name_prefix}.log"),maxBytes=5000000, backupCount=10)
handler.setFormatter(recfmt)
handler.setLevel(logging.DEBUG)
logger = logging.getLogger(f"{name_prefix} {__name__}")
logger.addHandler(handler)
return logger
当我运行此代码时,只有main()
中的debug语句最终出现在日志文件中。来自test()
的debug语句结束了,我不确定确切的位置。
log/logger_test.log
的内容:
2019-02-07 09:14:39,906.906 INFO now is 2019-02-07 09:14:39.906848
2019-02-07 09:14:39,906.906 DEBUG In main()
我期望In test()
也会出现在我的日志文件中。我是否对python日志记录的工作方式做出了一些不正确的假设?如何使程序中的所有日志(具有许多类和模块)都转到相同的配置日志记录器?在main()
中创建记录器实例之后,是否无需在各处传递记录器实例,是否可能?
谢谢。
答案 0 :(得分:2)
getLogger
函数将按其名称(单例类型)返回记录器:
然后您可以做的是:
util / logging_custom.py
def SetupLogger(logger_name, level=logging.INFO):
if not os.path.exists("log"):
os.makedirs("log")
recfmt = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s %(message)s')
handler = RotatingFileHandler(time.strftime(f"log/{logger_name}.log"),maxBytes=5000000, backupCount=10)
handler.setFormatter(recfmt)
handler.setLevel(level)
logger = logging.getLogger(logger_name)
logger.addHandler(handler)
# no need to return the logger, I would even advice not to do so
log_tester.py
from util.logging_custom import SetupLogger
import logging
import datetime
logger = SetupLogger("logger_test", logging.DEBUG) # you only need to run this once, in your main script.
logger = logging.getLogger("logger_test")
def test():
logger.debug("In test()")
def main():
logger.info(f"now is {datetime.datetime.now()}", )
logger.debug("In main()")
test()
if __name__ == '__main__':
main()
any_other.py
import logging
logger = logging.getLogger("logger_test") # this will return the logger you already instantiate in log_tester.py
logger.info("that works!")
更新
要设置 root记录器的级别和处理方式,而不使用您设置的级别,请使用logging.getLogger()
而不传递任何名称:
root_logger = logging.getLogger()
root_logger.addHandler(your_handler)
root_logger.setLevel(logging.DEBUG)
root_logger.info("hello world")
答案 1 :(得分:1)
从文档中
多次调用具有相同名称的getLogger()将返回一个 引用同一记录器对象。
您的假设是正确的。这里的问题是您在getLogger()
中调用test()
的方式。您应该传递在SetupLogger()
的{{1}}中使用的名称,即getLogger()
。