使用mod_python时python日志记录模块的不同行为

时间:2009-05-28 09:31:42

标签: python django logging mod-python

我们遇到一个令人讨厌的问题,我们发现在我们的服务器上使用mod_python运行时,python日志记录模块的行为会有所不同。在shell中执行相同的代码,或者使用runserver命令或使用mod_wsgi在django中执行相同的代码时,行为是正确的:

import logging
logger = logging.getLogger('site-errors')
logging.debug('logger=%s' % (logger.__dict__))
logging.debug('logger.parent=%s' % (logger.parent.__dict__))
logger.error('some message that is not logged.')

然后我们进行以下日志记录:

  

2009-05-28 10:36:43,440,DEBUG,error_middleware.py:31,[logger = {'name':'site-errors','parent':< logging.RootLogger instance at 0x85f8aac>, 'handlers':[],'level':0,'disabled':0,'manager':< logging.Manager实例位于0x85f8aec>,'propagate':1,'filters':[]}]

     

2009-05-28 10:36:43,440,DEBUG,error_middleware.py:32,[logger.parent = {'name':    'root','parent':无,'处理程序':    [< logging.StreamHandler实例at    0x8ec612c>中    < logging.handlers.RotatingFileHandler    实例在0x8ec616c>],'level':10,    '禁用':0,'传播':1,    '过滤器':[]}]

可以看出,没有为子记录器“site-errors”设置处理程序或级别。

日志配置在settings.py中完成:

MONITOR_LOGGING_CONFIG = ROOT + 'error_monitor_logging.conf'

import logging
import logging.config

logging.config.fileConfig(MONITOR_LOGGING_CONFIG)

if CONFIG == CONFIG_DEV:
   DB_LOGLEVEL = logging.INFO
else:
   DB_LOGLEVEL = logging.WARNING

第二个问题是我们还在__init__.py中添加了一个自定义处理程序,该处理程序位于文件夹中,作为error_middleware.py:

import logging
from django.conf import settings
from db_log_handler import DBLogHandler

handler = DBLogHandler()
handler.setLevel(settings.DB_LOGLEVEL)
logging.root.addHandler(handler)

在日志记录中无法看到自定义处理程序!

如果有人知道问题所在,请告诉我们!不要犹豫要求提供额外的信息。这肯定有助于解决问题。

3 个答案:

答案 0 :(得分:5)

如果不在settings.py中配置日志记录,可能会更好。

我们在根urls.py中配置您的日志记录。这似乎更好。我没有读过足够的Django来源知道为什么,确切地说,它更好,但它对我们来说效果很好。我也会在这里添加自定义处理程序。

另外,请密切关注mod_wsgi。它看起来比mod_python好得多。

答案 1 :(得分:0)

使用mod_wsgi无法解决问题。

我可以通过将完整配置放在一个文件中来解决问题。混合文件和代码配置似乎会产生apache问题(无论是使用mod_wsgi还是mod_python)。

要使用带文件配置的自定义日志记录处理程序,我必须执行以下操作:

import logging
import logging.config
logging.custhandlers = sitemonitoring.db_log_handler
logging.config.fileConfig(settings.MONITORING_FILE_CONFIG)

在settings.py中,我无法导入sitemonitoring.db_log_handler,因此我必须将此代码放在根urls.py中。

在配置文件中,我使用以下语句引用DBLogHandler

[handler_db]
class=custhandlers.DBLogHandler()
level=ERROR
args=(,)

PS:请注意,custhandler'属性'是动态创建的,可以有其他名称。这是使用动态语言的一个优点。

答案 2 :(得分:0)

您似乎没有发布所有相关信息 - 例如,您的日志配置文件在哪里?

你这么说:

  

在执行相同的代码时   shell,或者在django中使用runserver   命令或mod_wsgi,行为   是正确的

您没有弄清楚您显示的日志记录输出是来自其中一个环境,还是来自mod_python运行。看起来没错 - 在您的代码中,您将处理程序添加到根目录,而不是记录器“site-errors”。您还在处理程序上设置了一个级别,而不是记录器 - 因此您不希望在日志记录输出中看到“site-errors”记录器的级别设置,是吗?可以在记录器和处理程序上设置级别,但它们不同,但它们以相同的方式过滤掉事件。

如果您查看配置的日志记录文档,可以轻松解释有关自定义处理程序的问题,请参阅

http://docs.python.org/library/logging.html(搜索“类条目表示”)

这解释了配置文件中描述的任何处理程序类都是日志包命名空间中的eval()。因此,通过将logging.custhandlers绑定到自定义处理程序模块,然后在配置文件中声明“custhandlers.MyCustomClass”,eval()会生成预期的结果。你也可以做到

logging.sitemonitoring = sitemonitoring

并将处理程序类指定为

sitemonitoring.db_log_handler.DBLogHandler

也可以正常工作(只要已导入db_log_handler子包)。

顺便说一句,人们有时在settings.py中配置日志记录时遇到问题的原因是由于Django的导入魔法导致循环导入问题。我通常配置settings.py中的日志记录,除非你想导入Django的某些位(例如在django.db中 - 因为应用程序导入逻辑在django.db中,你可以遇到循环导入问题,如果你试图在settings.py中导入django.db.x。