日志模块:太多的打开文件描述符。

时间:2022-11-26 21:59:27

I am using Python logging module to print logs to a file, but I encountered the issue that "too many open file descriptors", I did remember to close the log file handlers, but the issue was still there.

我正在使用Python日志模块将日志打印到文件中,但是我遇到了“太多打开的文件描述符”的问题,我确实记得关闭日志文件处理程序,但是问题仍然存在。

Below is my code

下面是我的代码

class LogService(object):
    __instance = None
    def __init__(self):
        self.__logger = logging.getLogger('ddd')
        self.__handler = logging.FileHandler('/var/log/ddd/ddd.log')
        self.__formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        self.__handler.setFormatter(self.__formatter)
        #self.__logger.addHandler(self.__handler)

    @classmethod
    def getInstance(cls):
        if cls.__instance == None:
            cls.__instance = LogService()

        return cls.__instance

    # log Error
    def logError(self, msg):
        self.__logger.addHandler(self.__handler)
        self.__logger.setLevel(logging.ERROR)
        self.__logger.error(msg)
        # Remember to close the file handler
        self.closeHandler()

    # log Warning
    def logWarning(self, msg):
        self.__logger.addHandler(self.__handler)
        self.__logger.setLevel(logging.WARNING)
        self.__logger.warn(msg)
        # Remember to close the file handler
        self.closeHandler()

    # log Info
    def logInfo(self, msg):
        self.__logger.addHandler(self.__handler)
        self.__logger.setLevel(logging.INFO)
        self.__logger.info(msg)
        # Remember to close the file handler
        self.closeHandler()

    def closeHandler(self):
        self.__logger.removeHandler(self.__handler)
        self.__handler.close()

And after running this code for a while, the following showed that there were too many open file descriptors.

在运行这段代码一段时间后,下面的代码显示有太多的打开的文件描述符。

[root@my-centos ~]# lsof | grep ddd | wc -l
11555

2 个解决方案

#1


2  

No no. The usage is far simpler

不不。使用起来要简单得多

import logging
logging.basicConfig()

logger = logging.getLogger("mylogger")
logger.info("test")
logger.debug("test")

In your case you are appending the handler in every logging operation, which is at least overkill.

在您的例子中,您将在每个日志操作中附加处理程序,这至少有点过头了。

Check the documentation https://docs.python.org/2/library/logging.html

检查文档https://docs.python.org/2/library/logging.html

#2


1  

Each time you log anything, you add another instance of the handler.

每次记录任何内容时,都要添加处理程序的另一个实例。

Yes, you close it every time. But this just means it takes slightly longer to blow up. Closing it doesn't remove it from the logger.

是的,你每次都关门。但这仅仅意味着爆炸需要更长的时间。关闭它不会从日志记录器中删除它。

The first message, you have one handler, so you open one file descriptor and then close it.

第一个消息,你有一个处理器,所以你打开一个文件描述符然后关闭它。

The next message, you have two handlers, so you open two file descriptors and close them.

下一条消息,有两个处理程序,所以打开两个文件描述符并关闭它们。

The next message, you open three file descriptors and close them.

下一条消息,您将打开三个文件描述符并关闭它们。

And so on, until you're opening more file descriptors than you're allowed to, and you get an error.

等等,直到你打开更多的文件描述符,你就会得到一个错误。

To solution is just to not do that.

解决方法就是不这么做。

#1


2  

No no. The usage is far simpler

不不。使用起来要简单得多

import logging
logging.basicConfig()

logger = logging.getLogger("mylogger")
logger.info("test")
logger.debug("test")

In your case you are appending the handler in every logging operation, which is at least overkill.

在您的例子中,您将在每个日志操作中附加处理程序,这至少有点过头了。

Check the documentation https://docs.python.org/2/library/logging.html

检查文档https://docs.python.org/2/library/logging.html

#2


1  

Each time you log anything, you add another instance of the handler.

每次记录任何内容时,都要添加处理程序的另一个实例。

Yes, you close it every time. But this just means it takes slightly longer to blow up. Closing it doesn't remove it from the logger.

是的,你每次都关门。但这仅仅意味着爆炸需要更长的时间。关闭它不会从日志记录器中删除它。

The first message, you have one handler, so you open one file descriptor and then close it.

第一个消息,你有一个处理器,所以你打开一个文件描述符然后关闭它。

The next message, you have two handlers, so you open two file descriptors and close them.

下一条消息,有两个处理程序,所以打开两个文件描述符并关闭它们。

The next message, you open three file descriptors and close them.

下一条消息,您将打开三个文件描述符并关闭它们。

And so on, until you're opening more file descriptors than you're allowed to, and you get an error.

等等,直到你打开更多的文件描述符,你就会得到一个错误。

To solution is just to not do that.

解决方法就是不这么做。