日志处理器为空 - 为什么时间滚动文件处理器不工作
我用 logging.config.fileConfig 从一个配置文件中设置日志记录,这个配置文件里有控制台和文件处理器。然后我用 logging.getLogger(name) 来获取我的日志记录器并进行日志记录。有时候我想要文件处理器的文件名改变,也就是进行日志轮转(因为在Windows平台上有些问题,我不能使用时间轮转)。所以我调用 logger.handlers,但它显示的是一个空列表,这样我就无法关闭它们了!不过当我在调试器中逐步查看时,明显不是空的(当然,如果它是空的,我就无法记录日志了)
我不太明白这是怎么回事,有没有我遗漏的地方?
感谢任何帮助。谢谢。
4 个回答
可能你提到的 'TimeRoatingFileHandler' 这个名字是错的,因为你把 'Timed' 这个词里的 'd' 给漏掉了。所以正确的应该是:'TimedRoatingFileHandler'
你可以使用 RotatingFileHandler
这个工具(而不是 TimedRotatingFileHandler
)。
调用这个工具的 doRollover
方法可以让日志文件进行轮换,也就是说,它会把旧的日志文件换成新的。
首先,问题在于,如果你用配置文件来初始化日志记录,同时设置文件和控制台的处理器,那么它不会把这些处理器放到 logging.handlers 列表里。这样你就不能遍历这个列表,也无法在打开新的日志文件之前关闭和刷新之前的流。
如果你想使用 TimeRotatingFileHandler 或 RotatingFileHandler,这些处理器在 logging/handler.py 文件里。当它尝试进行文件轮换时,只会关闭它自己打开的流,因为它不知道父级的 logging 类(通常是单例模式)可能还有哪些流是打开的。因此,当你进行轮换时,会出现文件锁的问题(文件处理器),结果就会失败。
所以对我来说,解决办法是通过编程的方式来初始化日志记录,并使用 addHandlers 方法,这样就会填充 logging.handlers 列表。然后我可以遍历我的控制台和文件处理器,在手动轮换文件之前先关闭它们。
在我看来,这看起来像是日志记录类的一个明显错误,如果它在 Unix 系统上工作,那真的不应该这样。
感谢大家,特别是 @falsetru 的帮助。
看起来你需要正确地获取根日志记录器:
logger = logging.getLogger(__name__)
handlers = logger.handlers[:]
print('module {}'.format(handlers))
print('module {}'.format(logger.hasHandlers()))
logger = logging.getLogger('root')
handlers = logger.handlers[:]
print('root {}'.format(handlers))
print('root {}'.format(logger.hasHandlers()))
logger = logging.getLogger()
handlers = logger.handlers[:]
print('blank {}'.format(handlers))
print('blank {}'.format(logger.hasHandlers()))
输出结果:
模块 []
模块 True
根 []
根 True
空白
[<logging.handlers.RotatingFileHandler object at 0x108d82898>, <logging.StreamHandler object at 0x108d826d8>]
空白 True