2

我正在以一种不受文档禁止但未直接引用的方式使用 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的文档:

使用给定名称对该函数的所有调用都返回相同的记录器实例。这意味着记录器实例永远不需要在应用程序的不同部分之间传递。

记录器实例是如何被销毁的?他们被摧毁了吗?处理一百万个文件后,是否会有一百万个命名记录器实例在内存中等待使用?当内存充满这些旧的日志记录实例时,我是否正在为内存泄漏做好准备?

4

1 回答 1

2

记录器实例是如何被销毁的?他们被摧毁了吗?处理一百万个文件后,是否会有一百万个命名记录器实例在内存中等待使用?当内存充满这些旧的日志记录实例时,我是否正在为内存泄漏做好准备?

在解释器退出之前,它们不会被销毁。所有实例都被缓存,因为这是您在记录时想要的行为。处理一百万个文件后,有一百万个记录器实例处于活动状态。

正如您所说的那样,您正在将该logging模块用于不属于模块目标的一部分,因此它是一个次优的解决方案。

没有公共 API 可以摆脱缓存的记录器,尽管您可以通过以下方式清除缓存:

>>> root = logging.getLogger()
>>> root.manager.loggerDict.clear()

公共文档中没有描述loggerDictormanager属性,尽管它们没有明确标记为_private.

我不会为每个处理的文件使用不同的记录器,而是为每个线程使用不同的记录器,并将文件的名称插入所需的日志消息中。您可以编写一个简单的函数来进行日志记录,从而避免在每次调用记录器时显式插入文件名。

于 2013-07-22T09:00:16.747 回答