2

我正在尝试通过日志记录模块将一些上下文信息添加到一些日志中。我需要能够查看日志中每一行旁边的 projectid,每天创建超过 20,000 个项目,这些数据非常有用。为此,我创建了 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 变量

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

我想做的是以某种方式动态地获取“projectid”值,例如。在创建记录器对象或使用一些中间件时,但我只是不知道该怎么做。有人有建议吗?

4

2 回答 2

3

我想做的是以某种方式动态地获取“projectid”值,例如。在创建记录器对象或使用一些中间件时,但我只是不知道该怎么做。

创建记录器时不适合这样做,因为这是一次性操作。您可能需要做的是找到某种方法将当前项目 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 核心团队不认可,但它是线程本地人的发明目的,并且被其他框架非常成功地使用,例如烧瓶)。我对您的应用程序了解不足,无法建议可调用对象如何工作。

于 2011-07-26T09:52:14.583 回答
0

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

logger.info('A long entry', extra={'projectid': 1})

我将派生一个我自己的记录器对象,它会覆盖日志条目方法并附加“额外”参数(如果存在)。

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

于 2011-07-27T01:37:22.553 回答