2011-03-16 24 views
5

我在我的django应用程序中使用python日志记录。连接到后端api的类会根据需要使用文件处理程序初始化此记录器。每次进行api调用时,该类都会被实例化。我试图确保额外的处理程序没有添加每一次,但Python与文件处理程序正确记录

lsof | grep my.log 

显示了我的日志文件和后处理的量增加,而我的服务器出现故障时,由于这个打开的文件的限制。

self.logger = logging.getLogger("FPA") 

     try: 
      if self.logger.handlers[0].__class__.__name__=="FileHandler": 
       pass 
     except Exception, e: 
      print 'new filehandler added'+str(e) 
      ch = logging.FileHandler(FPA_LOG_TARGET) 
      formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s - %(pathname)s @ line %(lineno)d") 
      ch.setFormatter(formatter) 
      self.logger.setLevel(logging.DEBUG) 
      self.logger.addHandler(ch) 

我意识到这可能不是这样做的最佳方式,但我还没有发现我在执行错误为止。

+0

你的问题到底是什么? – 2011-03-16 10:17:47

+0

什么''打印'新的文件处理程序添加'+ str(e)''打印出你的日志语句? – 2011-03-16 10:18:24

+0

我的问题是我做错了什么? – pyeleven 2011-03-16 10:58:07

回答

1

我没有分析,如果很长一段时间,但它看起来像并发问题。

每个进程/线程都将其自己的文件句柄列表保存到打开的日志文件中。

如何解决?对于多线程代码,请确保存在保留所有句柄的全局字典。对于多进程 - 恐怕我没有答案......每个进程都保留它自己的文件句柄,可能将其映射到内存(内存映射文件可能是一个选项),但我不确定这是很好的解决方案 - see this remark

但主要问题是为什么你需要做这样的事情。首先,您可以使用logging.conf文件初始化所有记录器/处理程序/格式化程序,并在需要时(例如,特定的loger文件很广泛,并且想要将其记录到单独的文件中),请添加另一个具有不同文件名的记录程序。这是非常明智的,如果你将增加每Django应用程序一个记录器,通过增加应用程序的主要__init__.py

import logging 
log = logging.getLogger(__name__) 

,然后导入log在应用程序代码的其余部分(视图,模型等)

要使用logging.conf添加以下行到你的settings.py:

import os 
import logging 
DIRNAME = os.path.abspath(os.path.dirname(__file__)) 
logging.config.fileConfig(os.path.join(DIRNAME, 'logging.conf')) 

是的,这是手动的,但你并不需要更改代码,而只是一个配置文件。

另一种方法(如果你真的想每个记录器类型有一个文件)是有一个单独的进程,将保持文件打开,接受来自应用程序的连接。记录模块文档有一个nice example of this method

最后,但并非最不重要的是,已经有一些很好的解决方案可能会有所帮助。其中一个很好,就是使用django-sentry。这个模块可以记录你所有的异常,404(包括额外的中间件)并捕获所有日志(通过包含的日志处理程序)。

提供的UI将为您提供搜索所有记录的消息的可能性,并根据严重性和日志记录源对其进行过滤。但是这不仅限于这些 - 您可以简单地添加自己的模块。

相关问题