цепочка логгера в питоне - PullRequest
5 голосов
/ 07 июня 2010

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

import mymodule.utils.worker as worker

w = worker.Worker()
w.run()

Я бы хотел, чтобы регистрация сообщений выглядела так:

2010-06-07 15:15:29 INFO mymodule.utils.worker.Worker.run <pid/threadid>: Hello from worker

Как мне это сделать?

Спасибо.

Ответы [ 2 ]

8 голосов
/ 07 июня 2010

Я склонен использовать модуль регистрации в моих пакетах / модулях, например:

import logging
log = logging.getLogger(__name__)
log.info("Whatever your info message.")

Это устанавливает имя вашего регистратора на имя модуля для включения в сообщение журнала. Вы можете контролировать, где находится имя, где %(name)s находится в строке формата. Точно так же вы можете поместить pid с %(process)d и идентификатор потока с %(thread)d. См. Все документы .

Пример форматирования:

import logging
logging.basicConfig(format="%(asctime)s %(levelname)s %(name)s %(process)d/%(threadName)s: %(message)s")
logging.getLogger('this.is.the.module').warning('Testing for SO')

Дает мне:

2010-06-07 08:43:10,494 WARNING this.is.the.module 14980/MainThread: Testing for SO
2 голосов
/ 17 июня 2010

Вот мое решение, которое вышло из этого обсуждения. Спасибо всем за предложения.

Использование:

>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> from hierlogger import hierlogger as logger
>>> def main():
...     logger().debug("test")
...
>>> main()
DEBUG:main:test

По умолчанию он будет называть логгер как ... Вы также можете контролировать глубину, предоставив параметр:
3 - модуль.класс.метод по умолчанию
2 - module.class
1 - только модуль

Экземпляры регистратора также кэшируются для предотвращения вычисления имени регистратора при каждом вызове. Я надеюсь, что кому-то понравится.

код:

import logging
import inspect

class NullHandler(logging.Handler):
        def emit(self, record): pass

def hierlogger(level=3):
    callerFrame = inspect.stack()[1]
    caller = callerFrame[0]
    lname = '__heirlogger'+str(level)+'__'
    if lname not in caller.f_locals:
        loggerName = str()
        if level >= 1:
            try:
                loggerName += inspect.getmodule(inspect.stack()[1][0]).__name__
            except: pass
        if 'self' in caller.f_locals and (level >= 2):
            loggerName += ('.' if len(loggerName) > 0 else '') + 
                          caller.f_locals['self'].__class__.__name__
        if callerFrame[3] != '' and level >= 3:
            loggerName += ('.' if len(loggerName) > 0 else '') + callerFrame[3]
        caller.f_locals[lname] = logging.getLogger(loggerName)
        caller.f_locals[lname].addHandler(NullHandler())
    return caller.f_locals[lname]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...