Python Logger регистрирует одну и ту же запись много раз - PullRequest
11 голосов
/ 12 августа 2010

У меня есть такая функция инициализации логгера:

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger

И в какой-то части моего кода я ловлю такие исключения:

logger = generate_logger()
except AttributeError:
    logger.error('Opps we got an error')

Странно, но одну и ту же ошибку записывают 2 раза, и ее можно исправить только один раз, когда я заменяю logger.error('Opps we got an error') на print "test", я получаю «тест», напечатанный один раз.

В чем может быть проблема и решение.

Привет

Ответы [ 5 ]

12 голосов
/ 17 июня 2011

Вы добавляете новый FileHandler в корневой регистратор каждый раз, когда вызываете эту функцию: вызов logger.getLogger() без аргумента имени каждый раз возвращает один и тот же объект регистратора.

Вы должны вызвать generate_logger()только один раз, а затем просто получите тот же объект регистратора, вызвав logger.getLogger():

generate_logger()

# .... some time later

log = logger.getLogger()
except AttributeError:
   log.error('Opps we got an error')

(обратите внимание, что вам не нужно generate_logger() для возврата значения)

10 голосов
/ 21 января 2012

Я тоже столкнулся с той же проблемой и наткнулся на эту страницу.Да, я также создавал несколько обработчиков.В generate_logger() вы можете проверить, есть ли другие обработчики и удалить их.

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    # Reset the logger.handlers if it already exists.
    if logger.handlers:
        logger.handlers = []
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger
3 голосов
/ 12 августа 2010

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

2 голосов
/ 12 августа 2010

Возможно, у вас есть два обработчика, идущих к одному и тому же полученному журналу.

Сколько обработчиков вы создаете? Сколько раз вы выполняете generate_logger? Каждый раз, когда вы выполняете generate_logger, вы создаете новый обработчик для того же файла, что приводит к потенциальному дублированию.

0 голосов
/ 19 марта 2019

Использование может использовать шаблон проектирования Singleton для этого:

43 класс Singleton (тип):
44 "" "
45 Определите операцию экземпляра, которая позволяет клиентам получать доступ к ее уникальному
46 экземпляр.
47 "" "
48
49 def init (cls, name, base, attrs, ** kwargs):
50 супер (). init (имя, основания, атрибуты)
51 cls._instance = нет
52
53 def вызов (cls, * args, ** kwargs):
54, если cls._instance - None:
55 cls._instance = super (). call (* args, ** kwargs)
56 возврат cls._instance
57
58
59
60 def _setup_logger (name, log_file, level = logging.INFO):
61 "" "Функция устанавливает столько регистраторов, сколько вы хотите" ""
62
63 обработчик = logging.FileHandler (log_file)
64 handler.setFormatter (форматтер)
65 logger = logging.getLogger (имя)
66 logger.setLevel (уровень)
67 logger.addHandler (обработчик)
68
69 возврат логгера
70
Регистратор 71 класса (метакласс = Singleton):
72
73 def init (self, file_name, level):
74 если нет (isinstance (имя_файла, str) и
75 isinstance (level, int)):
76 повысить ValueError («Неверные аргументы»)
77
78 self.log_inf = _setup_logger ('inf', имя_файла + '. Inf', уровень)
79 self.log_err = _setup_logger ('err', имя_файла + '. Err', уровень)

...