вход с фильтрами - PullRequest
       11

вход с фильтрами

30 голосов
/ 19 мая 2009

Я использую Logging (import logging) для регистрации сообщений.

В одном модуле я регистрирую сообщения на уровне отладки my_logger.debug('msg');

Некоторые из этих отладочных сообщений приходят от function_a(), а другие от function_b(); Я хотел бы иметь возможность включить / отключить ведение журнала в зависимости от того, приходят ли они от a или от b;

Я предполагаю, что мне нужно использовать механизм фильтрации Logging.

Может ли кто-нибудь показать мне, как приведенный ниже код должен был бы быть инструментирован, чтобы делать то, что я хочу?

import logging
logger= logging.getLogger( "module_name" )

def function_a( ... ):
    logger.debug( "a message" )

def function_b( ... ):
    logger.debug( "another message" )

if __name__ == "__main__":
    logging.basicConfig( stream=sys.stderr, level=logging.DEBUG )

    #don't want function_a()'s noise -> ....
    #somehow filter-out function_a's logging
    function_a()

    #don't want function_b()'s noise -> ....
    #somehow filter-out function_b's logging
    function_b()

Если бы я масштабировал этот простой пример до большего количества модулей и большего количества функций на модуль, я бы был обеспокоен большим количеством регистраторов;

Могу ли я сохранить его до 1 регистратора на модуль? Обратите внимание, что сообщения журнала «структурированы», т. Е. Если регистрирующие их функции выполняют некоторую работу по синтаксическому анализу, все они содержат префикс logger.debug("parsing: xxx") - можно ли как-то одной строкой просто отключить все «синтаксические» сообщения (независимо от модуля / функции, отправляющей сообщение?)

Ответы [ 2 ]

48 голосов
/ 19 мая 2009

Просто реализуйте подкласс logging.Filter: http://docs.python.org/library/logging.html#filter-objects. У него будет один метод, filter(record), который проверяет запись журнала и возвращает True для записи в журнал или False для ее удаления. Затем вы можете установить фильтр на Logger или Handler, вызвав его метод addFilter(filter).

Пример:

class NoParsingFilter(logging.Filter):
    def filter(self, record):
        return not record.getMessage().startswith('parsing')

logger.addFilter(NoParsingFilter())

Или что-то в этом роде.

17 голосов
/ 19 мая 2009

Не используйте глобальные. Это несчастный случай, ожидающий.

Вы можете указать регистраторам любые имена, разделенные ".", Которые имеют для вас значение.

Вы можете управлять ими как иерархией. Если у вас есть регистраторы с именем a.b.c и a.b.d, вы можете проверить уровень ведения журнала для a.b и изменить оба регистратора.

У вас может быть любое количество регистраторов - они недорогие.

Наиболее распространенный шаблон проектирования - один регистратор на модуль. См. Именование регистраторов Python

Сделай это.

import logging

logger= logging.getLogger( "module_name" )
logger_a = logger.getLogger( "module_name.function_a" )
logger_b = logger.getLogger( "module_name.function_b" )

def function_a( ... ):
    logger_a.debug( "a message" )

def functio_b( ... ):
    logger_b.debug( "another message" )

if __name__ == "__main__":
    logging.basicConfig( stream=sys.stderr, level=logging.DEBUG )
    logger_a.setLevel( logging.DEBUG )
    logger_b.setLevel( logging.WARN )

    ... etc ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...