Seite 1 von 1

Verhalten von logging...

Verfasst: Dienstag 5. November 2019, 10:56
von drnicolas
Ich habe mit folgendem Code ein für mich unerklärliches Verhalten:

Code: Alles auswählen

def PrepLogger():
    import logging.handlers
    
    global log
    global f1
    global _loglevel
    
    #_loglevel=logging.DEBUG  
        
    logging.basicConfig(format='%(funcName)-12s %(lineno)-3s %(levelname)-6s  %(asctime)-9s: %(message)s', \
        level=_loglevel, datefmt="%H:%M:%S")
    log=logging.getLogger("test")
    if _logfile=='':
        f1=logging.handlers.RotatingFileHandler(_logfile)
    else:
        f1=logging.handlers.RotatingFileHandler(_logfile)
    f1.setFormatter(logging.Formatter('%(funcName)-12s %(lineno)-3s %(levelname)-6s  %(asctime)-9s: %(message)s',"%H:%M:%S"))
    
    f1.setLevel(_loglevel)
    log.addHandler(f1)
    log.critical('logging-Objekt erfolgreich erstellt.')


Das Skript ruft zunächst die obige Routine auf. Der Default Log-Level sthet bei logging.error
Später wird dann die Cmdline analysiert - hier gibt's natürlich die Möglichkeit mit '-v' das Loglevel zu senken.
Hier der Code dazu:

Code: Alles auswählen

.....
elif opt=='-v':
            # alten Loglevel speichern
            xx=log.getEffectiveLevel()
            if log.getEffectiveLevel()>=10:
                log.setLevel(log.getEffectiveLevel()-10)
                log.debug('loglevel alt=%i  logLevel neu=%i', xx, log.getEffectiveLevel())
        .....
Mache ich das, dann passiert folgendes komisch:
Lasse ich das Skript In der Eclipse IDE oder über das Terminal laufen, dann tauchen am Bildschirm jede Menge logging-Meldungen auf (so wie gewünscht), die Datei mit den Log-Informationen wird aber nur sehr spärlich gefüllt - nämlich mit Meldungen Level critical oder error.
Faktisch sind anscheinend die Level für Datei und Bidlschirmausgabe unterschiedlich (respketive wird für die Datei nicht übernommen)
Was mache ich falsch?

Re: Verhalten von logging...

Verfasst: Dienstag 5. November 2019, 11:10
von Sirius3
Vergiss erst einmal, dass es `global` überhaupt gibt. Alles was eine Funktion braucht, bekommt sie über ihre Argumente. Funktionsnamen schreibt man wie Variablennamen nach Konvention klein_mit_unterstrich.
Importe gehören an den Anfang des Skripts. Variablennamen mit _ am Anfang sind ein Zeichen, dass sie zwar syntaktisch gebraucht, aber nicht benutzt werden, _loglevel heißt also falsch. Du hast zweimal den selben Format-String, den Du am besten als KONSTANTE am Anfang der Datei definierst. `f1` ist ein schlechter Variablename, logfilehandler wäre besser.
`xx` ist ein schlechter Variablenname, insbesondere, weil Du ihn mit einem Kommentar erklären mußt.

Zum Problem: dieser logfilehandler hat seinen eigenen LogLevel, den Du nicht veränderst.

Re: Verhalten von logging...

Verfasst: Dienstag 5. November 2019, 11:38
von drnicolas
Okay, ich gelobe Besserung. Bin halt reiner Hobby-Programmierer. Aber deswegen sollte/kann man es trotzdem ordentlich machen.
Zu meinem Problem:
Ich müsste dann also SOWOHL für das erste Lgging-Objekt wie auch den Handler den Level ändern? Ich war der Meinung, daß ich nur einen Handler hätte.

Re: Verhalten von logging...

Verfasst: Dienstag 5. November 2019, 12:18
von __blackjack__
@drnicolas: Du rufst ja als erstes `basicConfig()` auf, das erstellt natürlich auch einen Handler sonst würde man direkt danach ja noch gar nicht sinnvoll ”loggen” können.

Korrigierend zum Namen `_loglevel`: Wenn der ``global`` ist, hat der führende Unterstrich eine andere Bedeutung und könnte auch sinnvoll sein: Auf Modulebene bedeutet das wie bei Attributen auf Objekten, dass der Name nicht Teil der öffentlichen API ist. Auf Modulebene hat das beispielsweise konkrete Auswirkung auf einen Sternchen-Import aus dem Modul. Nicht das man Sternchen-Importe machen sollte. Ähnliche Kategorie wie ``global``: die sind Böse™.