print statements an logging.logger weiterleiten

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
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Mittwoch 2. April 2008, 13:17

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 ?! :)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Mittwoch 2. April 2008, 13:26

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.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 2. April 2008, 13:39

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Jan-Peer
User
Beiträge: 166
Registriert: Dienstag 2. Oktober 2007, 10:55

Mittwoch 2. April 2008, 13:41

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.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 2. April 2008, 14:18

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
lunar

Mittwoch 2. April 2008, 14:54

@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.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 2. April 2008, 16:00

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Mittwoch 2. April 2008, 21:05

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.
Antworten