简体   繁体   English

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

[英]Different behavior of python logging module when using mod_python

We have a nasty problem where we see that the python logging module is behaving differently when running with mod_python on our servers. 我们遇到一个令人讨厌的问题,即在服务器上使用mod_python运行时,我们看到python日志记录模块的行为有所不同。 When executing the same code in the shell, or in django with the runserver command or with mod_wsgi, the behavior is correct: 在shell中或在django中使用runserver命令或mod_wsgi执行相同的代码时,该行为是正确的:

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.')

We then the following logging: 然后我们进行以下日志记录:

2009-05-28 10:36:43,740,DEBUG,error_middleware.py:31,[logger={'name': 'site-errors', 'parent': <logging.RootLogger instance at 0x85f8aac>, 'handlers': [], 'level': 0, 'disabled': 0, 'manager': <logging.Manager instance at 0x85f8aec>, 'propagate': 1, 'filters': []}] 2009-05-28 10:36:43,740,调试,error_middleware.py:31,[logger = {'name':'site-errors','parent':<logging.RootLogger instance at 0x85f8aac>,'handlers: [],“级别”:0,“已禁用”:0,“管理器”:<logging.Manager实例位于0x85f8aec>,“传播”:1,“过滤器”:[]}

2009-05-28 10:36:43,740,DEBUG,error_middleware.py:32,[logger.parent={'name': 'root', 'parent': None, 'handlers': [<logging.StreamHandler instance at 0x8ec612c>, <logging.handlers.RotatingFileHandler instance at 0x8ec616c>], 'level': 10, 'disabled': 0, 'propagate': 1, 'filters': []}] 2009-05-28 10:36:43,740,调试,error_middleware.py:32,[logger.parent = {'name':'root','parent':None,'handlers':[<logging.StreamHandler实例位于0x8ec612c>,<在0x8ec616c处的logging.handlers.RotatingFileHandler实例>],“级别”:10,“禁用”:0,“传播”:1,“过滤器”:[]}]

As one can see, no handlers or level is set for the child logger 'site-errors'. 可以看到,没有为子记录器“ site-errors”设置处理程序或级别。

The logging configuration is done in the settings.py: 日志记录配置在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

The second problem is that we also add a custom handler in the __init__.py that resides that in the folder as error_middleware.py: 第二个问题是,我们还在__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)

The custom handler cannot be seen in the logging! 在日志记录中看不到自定义处理程序!

If someone has idea where the problem lies, please let us know! 如果有人知道问题出在哪里,请告诉我们! Don't hesistate to ask for additonal information. 不要犹豫,要求其他信息。 That will certainly help to solve the problem. 这无疑将有助于解决问题。

It may be better if you do not configure logging in settings.py . 如果不配置settings.py登录,可能会更好。

We configure your logging in our root urls.py . 我们在根urls.py配置您的日志记录。 This seems to work out better. 这似乎更好。 I haven't read enough Django source to know why, precisely, it's better, but it's working out well for us. 我还没有阅读足够的Django资料,不知道为什么会更好,但是对于我们来说效果很好。 I would add custom handlers here, also. 我也将在此处添加自定义处理程序。

Also, look closely at mod_wsgi . 另外,仔细查看mod_wsgi It seems to behave much better than mod_python. 它的行为似乎比mod_python好得多。

The problem is not solved by using mod_wsgi. 使用mod_wsgi无法解决该问题。

I could solve the problem by placing the complete configuration into one file. 我可以通过将完整配置放入一个文件来解决该问题。 Mixing file and code configuration seems to create problems with apache (whether using mod_wsgi or mod_python). 混合文件和代码配置似乎会导致apache问题(无论使用mod_wsgi还是mod_python)。

To use a custom logging handler with file configuration, I had to do the following: 要将自定义日志记录处理程序与文件配置一起使用,我必须执行以下操作:

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

From the settings.py I cannot import the sitemonitoring.db_log_handler , so I have to place this code in the root urls.py . 从settings.py中,我无法导入sitemonitoring.db_log_handler ,因此我必须将此代码放在根urls.py

In the config file, I refer to the DBLogHandler with the following statement 在配置文件中,我使用以下语句引用DBLogHandler

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

PS: Note that the custhandler 'attribute' is created dynamically and can have another name. PS:请注意, custhandler “属性”是动态创建的,可以有另一个名称。 This is an advantage of using a dynamic language. 这是使用动态语言的优势。

You don't appear to have posted all the relevant information - for example, where is your logging configuration file? 您似乎没有发布所有相关信息-例如,您的日志记录配置文件在哪里?

You say that: 你说:

When executing the same code in the shell, or in django with the runserver command or with mod_wsgi, the behavior is correct 在shell中或使用runserver命令或mod_wsgi在django中执行相同的代码时,此行为是正确的

You don't make clear whether the logging output you showed is from one of these environments, or whether it's from a mod_python run. 您不清楚您显示的日志输出是来自这些环境之一,还是来自mod_python运行。 It doesn't look wrong - in your code you added handlers to the root, not to logger 'site-errors'. 看起来没有错-在您的代码中,您将处理程序添加到了根目录,而不是记录了“ site-errors”。 You also set a level on the handler, not the logger - so you wouldn't expect to see a level set for the 'site-errors' logger in the logging output, neh? 您还要在处理程序而不是记录器上设置一个级别-因此,您不会期望在记录输出中看到为“ site-errors”记录器设置的级别,是吗? Levels can be set on both loggers and handlers and they are not the same, though they filter out events in the same way. 级别可以同时在记录器和处理程序上设置,尽管它们以相同的方式过滤事件,但它们并不相同。

The issue about custom handlers is easily explained if you look at the logging documentation for configuration, see 如果查看日志记录文档以进行配置,则可以轻松解释有关自定义处理程序的问题,请参见

http://docs.python.org/library/logging.html (search for "the class entry indicates") http://docs.python.org/library/logging.html (搜索“类条目指示”)

This explains that any handler class described in the configuration file is eval()'d in the logging packages namespace. 这就解释了配置文件中描述的任何处理程序类都在日志包名称空间中的eval()中。 So, by binding logging.custhandlers to your custom handlers module and then stating "custhandlers.MyCustomClass" in the config file, the eval() produces the expected result. 因此,通过将logging.custhandlers绑定到您的自定义处理程序模块,然后在配置文件中声明“ custhandlers.MyCustomClass”,eval()会产生预期的结果。 You could just as well have done 你也可以做到

logging.sitemonitoring = sitemonitoring logging.sitemonitoring =站点监视

and specified the handler class as 并将处理程序类指定为

sitemonitoring.db_log_handler.DBLogHandler sitemonitoring.db_log_handler.DBLogHandler

which would work just as well (as long as the db_log_handler subpackage has been imported already). 这将同样有效(只要已导入db_log_handler子软件包)。

BTW the reason why people sometimes have problems configuring logging in settings.py is due to Django's import magic causing circular import problems. 顺便说一句,人们有时在配置settings.py时遇到问题是由于Django的导入魔术导致循环导入问题。 I generally configure logging in settings.py and it works fine unless you want to import certain bits of Django (eg in django.db - because the app import logic is in django.db, you can run into circular import issues if you try to import django.db.x in settings.py). 我通常会在settings.py中配置日志记录,除非您想导入Django的某些位(例如,在django.db中-因为应用程序导入逻辑在django.db中,否则它会正常工作),如果您尝试执行以下操作会遇到循环导入问题在settings.py中导入django.db.x)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM