Запись в журнале python

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

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", я получаю "тест" один раз.

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

Привет

Ответ 1

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

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

generate_logger()

# .... some time later

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

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

Ответ 2

Я тоже столкнулся с той же проблемой и наткнулся на эту страницу. Да, я также создавал несколько обработчиков. В 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

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

Ответ 4

У вас, вероятно, есть два обработчика, идущих в один и тот же результирующий журнал.

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

Ответ 5

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

43 класс Синглтон (тип):
44 "" "
45 Определите операцию экземпляра, которая позволяет клиентам получать доступ к ее уникальному
46 экземпляр.
47 "" "
48
49 def init (кл, имя, базы, атрибуты, ** kwargs):
50 супер(). init (имя, основания, атрибуты)
51 cls._instance = нет
52
Вызов 53 def (cls, * args, ** kwargs):
54, если cls._instance - None:
55 cls._instance = super(). вызов (* 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 класс Logger (метакласс = 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', file_name+ '. Inf', уровень)
79 self.log_err = _setup_logger ('err', file_name+ '. Err', level)