2015-05-07 34 views
1

我使用Python logging模块打印日志文件,但我遇到了“太多打开的文件描述符”,我也记得要关闭日志文件处理的问题,但问题仍然存在。记录模块:打开太多的文件描述

下面是我的代码

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() 

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

[[email protected] ~]# lsof | grep ddd | wc -l 
11555 
+1

请用实际回溯显示实际的异常,而不是仅仅模糊地描述它。 (我怀疑实际的错误是指“文件描述”。) – abarnert

+1

*提示:* Python不是Java。不要尝试使用Java方法编写Python代码:) –

+0

是的,谢谢,我想你可能是对的,我之前是Java编码器。:-) – hcz

回答

2

No no。用法简单得多

import logging 
logging.basicConfig() 

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

在你的情况要附加在每一个登录操作,这至少是矫枉过正的处理程序。

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

+0

谢谢,我用这个简单的方法,它工作! – hcz

1

每次登录任何时间,您添加处理程序的另一个实例。

是的,你每次都关闭它。但这只是意味着炸开需要更长的时间。关闭它不会将其从记录器中删除。

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

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

下一个消息,你开三个文件描述符并关闭它们。

依此类推,直到你打开更多的文件描述符比你允许,你会得到一个错误。

解决方法就是不这样做。

+0

谢谢!你可以给这个例子的代码示例吗? – hcz

+0

如果您只是在所有方法中删除了'self .__ logger.addHandler(self .__ handler)'和'self.closeHandler()',则此错误将消失。您可能也希望移除'setLevel(...)'调用,因为如果您设置级别以允许在尝试记录每条消息时允许记录级别没有意义。然后你只剩下默认的实现,这意味着你可以完全放弃你的覆盖。换句话说,最好的示例代码根本就没有代码。就像Tasos的回答一样。 – abarnert

+0

感谢您指出这一点,它的工作! – hcz