Python 向django 1.3中的logging.filters添加动态元素

Python 向django 1.3中的logging.filters添加动态元素,python,django,logging,filter,django-1.3,Python,Django,Logging,Filter,Django 1.3,我试图通过日志模块向一些日志添加一些上下文信息。我需要能够查看日志中每行旁边的projectid,每天创建20000多个项目。这些数据非常有用。为此,我创建了logging.Filter模块的一个派生模块 import logging class MTFilter(logging.Filter): def __init__(self, projectid=0): self.projectid = projectid def filter(self, record): rec

我试图通过日志模块向一些日志添加一些上下文信息。我需要能够查看日志中每行旁边的projectid,每天创建20000多个项目。这些数据非常有用。为此,我创建了logging.Filter模块的一个派生模块

import logging

class MTFilter(logging.Filter):

def __init__(self, projectid=0):
    self.projectid = projectid

def filter(self, record):
    record.projectid = self.projectid
    return True
这是我在settings.py中的日志变量

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'filters': {
        'project': {
            '()':  'app.proj.logging.mtfilter.MTFilter',
        },  
    },
    'formatters': { 
        'projectformat': {
            'format': '%(asctime)s %(levelname)8s PID[%(projectid)d] %(name)s[%(funcName)s]: %(message)s',
        },
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'django.utils.log.NullHandler',
        },
        'project-log': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'projectformat',
            'filename': os.path.join(SITE_ROOT, '../logs/django.log'),
            'filters':  ['project'],
            'maxBytes': 1024*1024*16, #16Mb
        },
    },
    'loggers': {
        '': {
            'handlers':     ['null'],
            'level':        'DEBUG',
            'propagate':    True,
        },
        'proj': {
             'handlers':    ['project-log'],
             'level':       'DEBUG',
         },
    }
}
在我看来,我使用以下方法

logger = logging.getLogger('proj')
logger.info('Log Message')
通过在Logging.filters.project中不为“projectid”添加任何值,我将获得默认格式值,即“0”。日志结果如下所示:

2011-07-26 02:41:44,488     INFO PID[0] proj[view]: Log Message
我想做的是以某种方式动态地获取“projectd”值,例如,当创建一个logger对象时,或者使用一些中间件时,但我不知道怎么做。有人有什么建议吗

我想做的是动态地获取“projectid”值, 例如,当创建一个logger对象时,或者使用一些中间件时,我只是 我不知道怎么做

创建记录器时不适合这样做,因为这是一次性操作。您可能需要做的是找到将当前项目ID放入筛选器的方法。例如,不必在构造时将记录传递给筛选器,您可以使用筛选器调用的可调用的设计来获取项目ID。例如:

class ProjectFilter(logging.Filter):
    def __init__(self, func):
        self.func = func

    def filter(self, record):
        record.projectid = self.func()
        return True

可调用的对象可以是任何知道如何从当前上下文中获取项目ID的对象(例如,线程本地——尽管Django核心团队没有认可它,但它是线程本地被发明出来的,并且被其他框架(如Flask)成功地使用)。我对您的应用程序了解不够,无法建议如何使用callable。

我知道这不是最优雅的解决方案,但查看日志记录的源代码后,我发现您可以通过“extra”参数添加上下文信息

logger.info('A long entry', extra={'projectid': 1})
我将用我自己的方法派生一个logger对象,该对象覆盖日志条目方法,并在存在的情况下附加“extra”参数


我想使用LogAdapters,但我使用的python版本是2.5x:(

谢谢Vinay,虽然它感觉不太好,但对于这么简单的东西来说似乎太复杂了。我接受了答案,因为这正是我想要的。PS-Love logging.py:)我看到了你的评论。日志记录本身提供了许多向日志添加上下文信息的方法,例如,日志记录调用中的
LoggingAdapter
extra
关键字arg。但是,如果您想将上下文信息添加到无法访问其源(例如,在第三方库中)的日志记录调用中,那么我建议使用这种方法。