Komme mit Logging nicht klar

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
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich möchte, dass mein Launchit verschiedene Statusmeldungen in `stderr` schreibt, wenn es als Executable ausgeführt wird, d.h. Aufruf von der Kommandozeile. Wenn der Anwender das Launchit-Paket jedoch als Bibliothek nutzen möchte (über einen Import), dann soll standardmäßig keine Statusausgabe erfolgen. Ich verwende dafür das Python-Modul `logging`. Da ich den dort angebotenen Root-Logger aber nicht nutzen möchte, habe ich mir das Modul logger geschrieben, welches die Steuerung eines Loggers namens `launchit` auf Modulebene erlaubt. Zudem hat das Modul das Flag `SHOULD_LOG`, um zu bestimmen, ob geloggt werden soll, oder ob nicht.

Die Problematik ist folgende: Ich lese beim Import des Packages `launchit` eine Datei aus, wo der Anwender bestimmte Dinge konfigurieren kann (Dateiname `launchit.conf` wird mittels des Moduls `launchit.settings` gelesen). Zu diesem Zeitpunkt steht das Flag `SHOULD_LOG` noch auf dem Standartwert `False`. Nachdem alle Module initialisiert wurden, besteht natürlich die Möglichkeit, das Flag zu ändern. Das hilft mir aber nicht, wenn ich sowas wie `Reading config file...` ausgeben möchte. Da denkt er halt noch, er soll *nicht* loggen. Und das ist ziemlich blöd, denn meine `bin/launchit` (eben das Executable) sieht halt so aus:

Code: Alles auswählen

import launchit
launchit.logger.SHOULD_LOG = True  # zu spät
launchit.gui.main()
Wie kann ich es also möglichst elegant lösen, dass Launchit bei einem Aufruf als Executable sofort merkt, dass es den Logger anschmeißen soll? Davon ab weiß ich natürlich auch nicht so recht, ob mein `logger`-Modul so furchtbar elegant geworden ist... ^^

//edit: Damit auch klar wird, wie ich genau logge: Es steht z.B. in `launchit.settings.get_user_config()` folgendes:

Code: Alles auswählen

def get_user_config(filename='launchit.conf'):
    """
    Return the parsed contents of a configuration file, which is named with
    `filename`, as a dictionary, where the file is assumed to exist inside 
    the user's "standard" configuration directory. In case that no such file
    could be found, an empty dictionary will be returned. 

    Note that a detailed explanation of the expected scheme inside the config
    file can be found in `iter_config_entries()`, while the config file's path 
    is retrieved by `get_config_path()`.
    """
    path = get_config_path(filename)
    if not os.path.exists(path):
        return {}
    logger.info('Reading configuration from {0!r}'.format(path))
    return get_config_entries(path)
Und `logger.info()` erzeugt nach der Prüfung von `logger.SHOULD_LOG` zu dem Zeitpunkt eben noch keine Ausgabe. Diese Funktion wird schon beim Package-Import ausgeführt.
deets

Zuerstmal solltest du dein Modul so umschreiben, das es *keine* Seiteneffekte beim importieren hat. Und dein aktuelles Problem ist auch genau einer der Gruende dafuer, warum man das besser laesst.

Und dann solltest du dein eigenes Logging-Zeug entsorgen. Das ist dann nicht mehr notwendig. Stattdessen konfigurierst du im EXE das Logging, bevor du mit launchit arbeitest.

Last but not least musst du einen NullHandler an den Root-Logger pappen. Wie das geht, habe ich hier vor einigen Tagen/Wochen beschrieben. Das ist eine unschoene, aber leider notwendige Massnahme, um das logging-modul von Ausgaben abzuhalten, wenn jemand launchit als Bibliothek benutzt, aber *keine* logging-Modul-Konfiguration vornimmt.
Antworten