我以文档未禁止但未直接提及的方式使用 logging.getLogging()。
我的应用程序处理数据文件和网络连接,有时在线程中。为了识别每个连接和/或数据文件的日志行,我执行以下操作:
data_file_name = "data_file_123.xml"
logger = logging.getLogger(data_file_name)
logger.info("This is logged.")
2013-07-22 05:58:55,721 - data_file_123.xml - INFO - This is logged.
这很好用:
- 避免在软件周围传递记录器实例。
- 确保每个 行标有适当的源标识符,而无需 在每个记录调用中手动执行它。
我担心的是 http://docs.python.org/2/library/logging.html#logging.getLogger 上的文档:
All calls to this function with a given name return the same logger instance. This means that logger instances never need to be passed between different parts of an application.
记录器实例是如何销毁的?他们被摧毁了吗?处理完一百万个文件后,是否会有一百万个命名记录器实例在内存中等待使用?当内存被这些旧的日志记录实例填满时,我是否为内存泄漏做好了准备?
请您参考如下方法:
How are the the logger instances destroyed? Are they destroyed? After processing a million files will there be a million named logger instances waiting in memory to be used? Am I setting myself up for a memory leak as memory fills with these old logging instances?
在解释器退出之前,它们不会被销毁。所有实例都被缓存,因为这是您在记录时想要的行为。处理完一百万个文件后,将有一百万个事件的记录器实例。
正如您自己所说,您将 logging 模块用于某些不属于该模块目标的事情,因此它不是最佳解决方案。
虽然您可以通过以下方式清除缓存,但没有公共(public) API 可以摆脱缓存的记录器:
>>> root = logging.getLogger()
>>> root.manager.loggerDict.clear()
loggerDict 或 manager 属性没有在公共(public)文档中描述,尽管它们没有明确标记为 _private。
我不会为每个处理的文件使用不同的记录器,而是为每个线程使用不同的记录器,并将文件名插入所需的日志消息中。您可以编写一个简单的函数来执行日志记录,从而避免在每次调用记录器时都必须显式插入文件名。
