2017-01-25 2 views
3

Я хотел бы создать два различных лесорубов, и это то, что у меня есть:Почему мой логгер регистрирует одно и то же несколько раз?

import logging 


def logger(logger_name, level): 
    """Create logger with given name and level""" 

    # Set up logger 
    logger = logging.getLogger(logger_name) 
    logger.setLevel(logging.DEBUG) 

    # print(logger.handlers) 
    formatter = logging.Formatter('%(levelname)-8s %(asctime)s %(message)s') 
    handler = logging.StreamHandler() 
    handler.setFormatter(formatter) 

    # Set level 
    handler.setLevel(level) 

    # Add handlers to logger 
    logger.addHandler(handler) 

    return logger 


LOGGER1 = logger(logger_name='main_app', level=logging.INFO) 
LOGGER2 = logger(logger_name='main_app.module', level=logging.DEBUG) 

LOGGER1.info('one') 
LOGGER2.info('two') 
LOGGER1.info('three') 

Это то, что в настоящее время вошли:

INFO  2017-01-25 11:49:45,209 one 
INFO  2017-01-25 11:49:45,209 two 
INFO  2017-01-25 11:49:45,209 two 
INFO  2017-01-25 11:49:45,210 three 

Что я здесь делаю неправильно?
Как я могу предотвратить LOGGER2 для регистрации одной и той же вещи несколько раз?

ответ

6

Изменение атрибута propagate в False, как показано ниже

def logger(logger_name, level): 
    """Create logger with given name and level""" 

    # Set up logger 
    logger = logging.getLogger(logger_name) 

    #stops logging messages being passed to ancestor loggers 
    logger.propagate = False 

    #.... 

Из documentation;

Если [Logger.propagate] истинно, событие, записываемое в этот регистратор будет передан в обработчик более высокого уровня (предок) лесорубы, в дополнении к любым обработчикам, присоединенных к этому регистратору. Сообщения передаются непосредственно обработчикам регистраторов-предшественников - ни уровень, ни фильтры соответствующих регистраторов-предков не рассматриваются.

Значение по умолчанию logger.propagate является True устанавливается конструктором в getLogger.

Обратите внимание, что имя регистратора может быть «иерархическими значениями, разделенными по периоду времени», дающими отношения родитель-ребенок (как это было сделано в двух ваших объектах main.app и main.app.module, причем последний является дочерним).

См. Logger Objects section;

Это потенциально иерархическое значение, разделенное периодом, например foo.bar.baz (хотя оно также может быть просто простым foo, например). Регистраторы, которые находятся ниже в иерархическом списке, являются дочерними элементами регистраторов выше в списке.