Как лучше использовать модуль логирования в моей программе? - PullRequest
3 голосов
/ 28 ноября 2011

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

LogMethod(LogFileName, LogMessage):
    LogRlock.acquire()

    LogFile = open(LogFileName, "a")
    LogFile.write(LogMessage)
    LogFile.close()

    LogRlock.release()

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

LogMethod(LogFileName, LogMessage):
    #### Do I need to destroy the instance Logger at the end of this method?
    LogRlock.acquire()

    Logger = logging.getLogger("Demo")
    Logger.setLevel(logging.DEBUG)
    SizeHandler = logging.handlers.RotatingFileHandler(filename = LogFileName, mode = "a", maxBytes = 1000000)
    SimpleFormatter = logging.Formatter(fmt = '%(asctime)s%(message)s', datefmt = '[%Y-%m-%d, %H:%M:%S]:')
    SizeHandler.setFormatter(SimpleFormatter)
    Logger.addHandler(SizeHandler)
    Logger.info(LogMessage)

    LogRlock.release()

Документы Python говорят, что модуль журналирования является потокобезопасным, поэтому я полагаю, что мне не нужен LogRlock, верно?И еще один вопрос, нужно ли уничтожать экземпляр в конце описанного выше метода?Если да, то как мне это сделать?И это безопасный способ использовать модуль регистрации?

Большое спасибо

Ответы [ 2 ]

2 голосов
/ 28 ноября 2011

Использование регистратора и определение его свойств - это две разные задачи, которые необходимо отделить, чтобы отделить бизнес-логику от логики конфигурации.

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

def logMethod(loggerName, logMessage):
    logger = logging.getLogger(loggerName)
    logger.info(logMessage)

Определение свойств регистраторов можно выполнить отдельно, как это:

def configureLogger(loggerName):
    logger = logging.getLogger(loggerName)
    logger.setLevel(logging.DEBUG)
    sizeHandler = logging.handlers.RotatingFileHandler(filename = LogFileName, mode = "a", maxBytes = 1000000)
    simpleFormatter = logging.Formatter(fmt = '%(asctime)s%(message)s', datefmt = '[%Y-%m-%d, %H:%M:%S]:')
    sizeHandler.setFormatter(simpleFormattesr)
    logger.addHandler(sizeHandler)

Другая альтернатива приведенному вышепредставленная «ручная» конфигурация ведения журнала будет заключаться в использовании файла конфигурации ведения журнала или словаре конфигурации .

Разработчикам Python не нужно заботиться об уничтожении объектов,это делает сборщик мусора Python.В случае с классом logging.Logger было бы даже ошибкой явно уничтожить регистратор: Экземпляр регистратора сохраняется модулем журналирования, чтобы возвращать один и тот же экземпляр при каждом вызове logging.getLogger (если одно и то же имя регистратора).)) (метод logging.getLogger («Demo») создает новый экземпляр при первом вызове) В вашем случае это означает, что RotatingFileHandler добавляется второй, третий, четвертый ... раз в ваш регистратор при каждом вызовеlogMethod ...

PS: соглашение о кодировании Python: функции и переменные начинаются со строчной буквы

1 голос
/ 28 ноября 2011

Документы Python говорят, что модуль журналирования является поточно-ориентированным, так что, думаю, мне не нужен LogRlock, верно?

Правильно, вам не нужна блокировка для защиты вашего регистрационного кода.

И еще один вопрос, нужно ли уничтожать экземпляр в конце описанного выше метода? Если да, то как мне это сделать?

Нет, нет. На самом деле, вы не можете уничтожать объекты в Python. Они будут автоматически собираться, когда на них нет ссылок.

Кроме того, объекты Logger предназначены для сохранения в течение всей жизни вашей программы. Даже если вы можете уничтожить его в конце функции регистрации, вы не должны этого делать.

И это безопасный способ использования модуля регистрации?

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

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

logger = logging.getLogger("package.module")

Или, если в модуле используется несколько регистраторов, сделайте это для каждого из них. Внутри каждой функции, где вам нужно зарегистрировать сообщение, вы можете просто сделать

def foo():
    ...
    logger.info("message")
    ...

Этот вызов logger.info заменяет ваш LogMethod.

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