Standardloggerklasse erweitern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

Das nachfolgende Modul zeigt einen Versuch den logging.Logger zu erweitern. Beabsichtigt ist eine Ausgabe bei Klassen, die die Klassenhierarchie zeigt, nur leider wird meine Klasse MyLogger nicht benutzt!

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys, inspect, logging


class MyLogger(logging.Logger):
    """Deute Klassenhierarchie durch ``A.B.C.method`` an.
    """
    def __init__(self, name=""):
        logging.Logger.__init__(self, name)
    
    def debug(self, msg, *args, **kwargs):
        method = inspect.stack()[1][3]
        frm = inspect.stack()[1][0]
        
        if 'self' in frm.f_locals:
            clst = frm.f_locals['self'].__class__.mro()[:-1]
            clst.reverse()
            method = "%s.%s" % (".".join(x.__name__ for x in clst), method)
        
        if not method.startswith('<'):
            method += '()'
        
        msg = ''.join((method, str(frm.f_lineno), msg))
        self.__class__.__bases__[0].debug(self, msg, *args, **kwargs)

logging.setLoggerClass(MyLogger)
logging.basicConfig(
    level=logging.DEBUG,
    format="%(module)-18s:%(lineno)4d [%(funcName)-17s] %(message)s",
    stream=sys.stdout,
    )
Logger = logging.getLogger()


class A(object):
    def __init__(self, a="<<A>>", *args, **kwargs):
        if Logger.level == logging.DEBUG:
            Logger.debug("Test A")
        self.attr_a = a
    
    def __unicode__(self):
        return u"<A: A.attr_a=%s>" % (self.attr_a,)


class B(A):
    def __init__(self, a="<<A>>", b="<<B>>", *args, **kwargs):
        if Logger.level == logging.DEBUG:
            Logger.debug("Test B")
        
        A.__init__(self, a, *args, **kwargs)
        self.attr_b = b
    
    def __unicode__(self):
        return u"<B: B.attr_a=%s, B.attr_b=%s>" % (self.attr_a, self.attr_b)


if __name__ == "__main__":
    a = A()
    b = B()
Wie man sieht wird die Klassenhierarchie nicht angezeigt. Verschiedene Tests zeigten mir, dass die Klasse gar nicht benutzt wird.
Was läuft hier falsch?
Zuletzt geändert von Anonymous am Dienstag 23. Juli 2013, 06:57, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
CU sedi
----------------------------------------------------------
Python 3.5; Python 3.6
LinuxMint18
BlackJack

@sedi: Die Tests sollten auch gezeigt haben, dass der Logger vom Typ `RootLogger` ist. Den kann man nicht ersetzen. Du musst bei `getLogger()` einfach einen Namen angeben, dann wird auch ein Exemplar von Deinem `MyLogger` erstellt und zurückgegeben.

Dann siehst Du immer noch nichts wegen den ``if``\s vorm Logging, denn selbst erstellte Logger leiten erst einmal alles an den `RootLogger` weiter, haben also nicht DEBUG als Level. Dieser Test wird intern von den Loggern gemacht, den soll man nicht selber machen bevor mal eine Logging-Methode aufruft.

Und die letzte Zeile von `debug()` enthält zu viel Magie. Statt ``self.__class__.__bases__[0]`` sollte dort wie in der `__init__()` besser ``logging.Logger`` stehen.
sedi
User
Beiträge: 104
Registriert: Sonntag 9. Dezember 2007, 19:22

OK - Danke - hat funktioniert.

Leider bringt das aber nicht das von mir erhoffte Ergebnis:

Wollte, dass im Funktionsstring auch die verantwortliche Klassenstruktur sichtbar wird. Muss also noch mal nachbessern. Dazu muss man wohl einen eigenen Formatter erstellen...
CU sedi
----------------------------------------------------------
Python 3.5; Python 3.6
LinuxMint18
BlackJack

@sedi: Was meinst Du mit Klassenstruktur? Und wie willst Du das darstellen? Was ist mit Mehrfachvererbung?
Antworten