Seite 1 von 1

print statements an logging.logger weiterleiten

Verfasst: Mittwoch 2. April 2008, 13:17
von Zap
Hallo zusammen,

gibt es eine Möglichkeit einen logger des logging modules so mit dem
sys.stdout Objekt zu verknüpfen das alle print-Anweisungen die in einem bestehenden Programm vorhanden über diesen logger laufen?

Meine Vorstellung geht in die Richtung, dass wenn ein ''print'' ausgeführt wird,
der auszugebende Text an logger.info() weitergeleitet wird.

Oder wünsche ich mir da was unrealistisches ?! :)

Verfasst: Mittwoch 2. April 2008, 13:26
von Y0Gi
Ich vermute, das ist so nicht möglich.

In Py3k könntest du zu Beginn jeden Moduls (oder geht das vielleicht noch global durch Veränderung der Builtins?) die `print`-Funktion überschreiben - in Python 2 ist es aber noch ein Statement.

Ansonsten fällt mir nur ein, STDOUT in der Shell umzuleiten.

Verfasst: Mittwoch 2. April 2008, 13:39
von Leonidas
Y0Gi hat geschrieben:Ich vermute, das ist so nicht möglich.
Doch, durchaus. Sogar ganz einfach. Ein minimaler Ansatz wäre ja sowas, aber das ist natürlich verbesserungswürdig:

Code: Alles auswählen

import logging, sys

class PrintLogger(object):
    def write(self, text):
        text = text.strip()
        if text:
            logging.info(text)

logging.basicConfig(level=logging.INFO)

print "I'm outta control"
sys.stdout = PrintLogger()
print 'All your stdout are belong to us'
Bevor man das einsetzt muss man natürlich ``write()`` etwas robuster machen als ich das gemacht habe.

Verfasst: Mittwoch 2. April 2008, 13:41
von Jan-Peer
Das logging-Modul bietet für diesen Zweck die Streamhandler an. Ein Beispiel muß ich jetzt gerade schuldig bleiben, aber ich glaube, es gab hier im Forum auch schon reichlich Material dazu.

Verfasst: Mittwoch 2. April 2008, 14:18
von Leonidas
Jan-Peer hat geschrieben:Das logging-Modul bietet für diesen Zweck die Streamhandler an.
Die Handler ist dafür zuständig die Events wegzuleiten von logging (also etwa in eine Datei, in stdout, zu syslog, übers Netzwerk) nicht aber die Events an logging anzuliefern. Dafür gibt es die Funktionen des Moduls/Loggers.

Verfasst: Mittwoch 2. April 2008, 14:54
von lunar
@Leonidas
Dein Beispiel ist geradezu prädestiniert für eine anständige Endlosschleife, die dann auftritt, wenn man logging so konfiguriert, dass es nach sys.stdout loggt ;)

Imho ist die Aufgabestellung an sich auch eher unsinnig. Wenn man logging möchte, dann sollte man lieber search & replace über die Quellen laufen lassen, und gleich richtig auf logging.* Aufrufe umstellen. Zum einen fördert das die Lesbarkeit, weil jeder weiß, dass hier auch wirklich logging genutzt wird, was bei einer sys.stdout-Lösung ja nicht automatisch der Fall ist ;) Zum anderen kann man dann die Ausgabe auch richtig steuern, in dem man z.B. für verschiedene Unterbereiche der Anwendung verschiedene Logger nutzt.

Mehraufwand sehe ich da auch nicht, denn wenn man logging richtig nutzen will, muss man eh früher oder später direkt logging-Aufrufe einsetzen.

Zudem ist die Lösung auch ziemlich fragil, weil nicht garantiert werden kann, dass sys.stdout nicht doch irgendwo mit einem anderen Objekt überschrieben wird.

Verfasst: Mittwoch 2. April 2008, 16:00
von Leonidas
lunar hat geschrieben:@Leonidas
Dein Beispiel ist geradezu prädestiniert für eine anständige Endlosschleife, die dann auftritt, wenn man logging so konfiguriert, dass es nach sys.stdout loggt ;)
Richtig lustig wird es wenn man in ``write()`` auch noch ``print`` aufruft ;)
lunar hat geschrieben:Zudem ist die Lösung auch ziemlich fragil, weil nicht garantiert werden kann, dass sys.stdout nicht doch irgendwo mit einem anderen Objekt überschrieben wird.
Naja, das ist eben das typische Monkeypatching-Problem, welches man in Ruby (ninja patching, anyone?) und auch in Python hat. Im letzteren aber zumindest nicht bei den eingebauten Typen.

Verfasst: Mittwoch 2. April 2008, 21:05
von Zap
lunar hat geschrieben:Zudem ist die Lösung auch ziemlich fragil, weil nicht garantiert werden kann, dass sys.stdout nicht doch irgendwo mit einem anderen Objekt überschrieben wird.
Jo, mehr als ein fieser Monkey-Patch auf ein bestehendes unschönes Skript wäre das auch nicht gewesen, also nichts für ernsthafte Zwecke ;)

Trotzdem vielen dank für die Antworten.