Добавление динамических элементов в logging.filters в django 1.3 - PullRequest
1 голос
/ 26 июля 2011

Я пытаюсь добавить некоторую контекстную информацию в некоторые журналы через модуль регистрации.Мне нужно иметь возможность просматривать проект рядом с каждой строкой в ​​журналах. Ежедневно создается более 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

Вот моя переменная LOGGING в 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')

Не задавая значения для 'projectid 'в Logging.filters.project Я получаю значение формата по умолчанию, равное' 0 '.Результат журнала выглядит следующим образом:

2011-07-26 02:41:44,488     INFO PID[0] proj[view]: Log Message

То, что я хотел бы сделать, это как-то динамически получить значение 'projectid', например.при создании объекта регистратора или использовании некоторого Middleware, но я просто не знаю, как это сделать.У кого-нибудь есть предложения?

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Что я хотел бы сделать, так это как-то динамически получить значение 'projectid', например. при создании объекта регистратора, или с использованием некоторого Middleware, но я просто не знаю как это сделать.

Неправильно делать это при создании регистратора, так как это одноразовая операция. То, что вам, вероятно, нужно сделать, - это найти способ вставить идентификатор текущего проекта в фильтр. Например, вместо того, чтобы передавать запись в фильтр во время создания, вы можете использовать конструкцию с функцией вызова, которую фильтр вызывает для получения идентификатора проекта. Например:

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

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

Вызываемым может быть все, что знает, как получить идентификатор проекта из текущего контекста (например, локальный поток - хотя это не одобрено основной командой Django, это то, для чего были изобретены локальные потоки, и которые довольно успешно использовались другими рамки, такие как колба). Я недостаточно знаю о вашем заявлении, чтобы предположить, как может работать вызываемый объект.

0 голосов
/ 27 июля 2011

Я знаю, что это не самое элегантное решение, но, просматривая источник для ведения журнала, я обнаружил, что вы можете добавить контекстную информацию с помощью параметра 'extra'.

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

Я просто выведуобъект logger с моим собственным, который переопределяет методы записи журнала и добавляет параметр 'extra', если существует.

Я хотел бы использовать LogAdaptors, но я использую версию Python 2.5x: (

...