Как я могу получить имя класса, содержащего вызов регистрации в Python? - PullRequest
13 голосов
/ 12 сентября 2011

Если мне нужно имя функции, я могу просто включить %(funcName)s в Formatter. Но как мне получить имя класса, содержащего вызов регистрации?

Я просмотрел документацию для logging, но не могу найти упоминания об этом.

Ответы [ 4 ]

10 голосов
/ 03 февраля 2016

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

import logging


# Create a base class
class LoggingHandler:
    def __init__(self, *args, **kwargs):
        self.log = logging.getLogger(self.__class__.__name__)


# Create test class A that inherits the base class
class testclassa(LoggingHandler):
    def testmethod1(self):
        # call self.log.<log level> instead of logging.log.<log level>
        self.log.error("error from test class A")


# Create test class B that inherits the base class
class testclassb(LoggingHandler):
    def testmethod2(self):
        # call self.log.<log level> instead of logging.log.<log level>
        self.log.error("error from test class B")


testclassa().testmethod1()
testclassb().testmethod2()

При названии регистратора, как указано выше, %(name)s будет названием вашего класса

пример вывода

$ python mymodule.py
[2016-02-03 07:12:25,624] ERROR [testclassa.testmethod1:29] error from test class A
[2016-02-03 07:12:25,624] ERROR [testclassb.testmethod2:36] error from test class B

Альтернативный вариант (ы)

Не Наследование

import logging


def log(className):
    return logging.getLogger(className)


class testclassa:
    def testmethod1(self):
        log(self.__class__.__name__).error("error from test class A")


class testclassb:
    def testmethod2(self):
        log(self.__class__.__name__).error("error from test class B")


testclassa().testmethod1()
testclassb().testmethod2()
2 голосов
/ 12 сентября 2011

Почти наверняка есть лучший способ сделать это, но пока кто-то не укажет, это будет работать:

import inspect

class testclass:
    def testmethod(self):
        log()

def log():
    stack = inspect.stack()
    try:
        print "Whole stack is:"
        print "\n".join([str(x[4]) for x in stack])
        print "-"*20
        print "Caller was %s" %(str(stack[2][4]))
    finally:
        del stack

testclass().testmethod()

Вывод этого следующий:

Whole stack is:
['    stack = inspect.stack()\n']
['        f()\n']
['testclass().testmethod()\n']
['                exec code in self.locals\n']
['            ret = method(*args, **kwargs)\n']
None
--------------------
Caller was ['testclass().testmethod()\n']
0 голосов
/ 19 февраля 2018

Это функция для создания информативного лог-сообщения с использованием метода класса представления:

https://docs.python.org/3/library/functions.html#repr

def log_message(thing: object = None, message: str = '') -> str:
    """:returns: detailed error message using reflection"""
    return '{} {}'.format(repr(thing), message)

Это может быть реализовано для любого класса с использованием микширования:

class UtilMixin(object):
    def log(self, message: str = '') -> str:
        """:returns: Log message formatting"""
        return log_message(thing=self, message=message)

Вы можете быть связаны с классом, используя множественное наследование:

class MyClass(object, UtilMixin):
    def __repr__(self) -> str:
        return '<{}>'.format(self)
    pass

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

logger.warning(self.log('error message goes here'))
0 голосов
/ 12 сентября 2011

Лично я, как правило, называю свои регистраторы после уроков, так как намного легче отследить, откуда пришло конкретное сообщение. Таким образом, у вас может быть корневой логгер с именем "top", а для модуля "a" и класса "testclass" я называю свой логгер "top.a.testclass".

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

Ответ

@ ed выше, мне кажется, что это очень нелепо, и это не то, что мне было бы удобно использовать в рабочем коде.

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