Ich habe einen Logger, der eine RotatingFileHandler
hat. Ich möchte alle Stdout
und Stderr
an den Logger umleiten. Wie geht das?Wie Umleitung stdout und stderr Logger in Python
Antwort
Wenn es ein All-Python-System (dh keine C-Bibliotheken direkt an fds schreiben, als Ignacio Vazquez-Abrams gefragt), dann könnten Sie in der Lage sein, einen Ansatz zu verwenden, wie here vorgeschlagen:
class LoggerWriter:
def __init__(self, logger, level):
self.logger = logger
self.level = level
def write(self, message):
if message != '\n':
self.logger.log(self.level, message)
und Setzen Sie dann sys.stdout
und sys.stderr
auf LoggerWriter
Instanzen.
danke, das hat den Job, aber aus irgendeinem Grund 'stderr' senden Sie es die Nachricht jedes Wort getrennt, weißt du warum? – orenma
@orenma vermutlich weil Schreiben Wort für Wort heißt. Sie können meinen Beispielcode besser an Ihre Bedürfnisse anpassen. –
Was passiert, wenn sys.stderr.flush() nach dem Umleiten von stderr aufgerufen wird? – Moberg
Nicht genug rep, um zu kommentieren, aber ich wollte die Version von dieser hinzufügen, die für mich arbeitete, falls andere in einer ähnlichen Situation sind.
class LoggerWriter:
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level
def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message != '\n':
self.level(message)
def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level(sys.stderr)
und dies würde wie etwas aussehen:
log = logging.getLogger('foobar')
sys.stdout = LoggerWriter(log.debug)
sys.stderr = LoggerWriter(log.warning)
Ich bekomme eine seltsame Ausgabe wegen der Flush-Methode: 'warning archan_pylint: 18:
Mit bündig hinzugefügt Vinay Sajip Antwort:
class LoggerWriter:
def __init__(self, logger, level):
self.logger = logger
self.level = level
def write(self, message):
if message != '\n':
self.logger.log(self.level, message)
def flush(self):
pass
alle vorherigen Antworten scheinen Probleme Hinzufügen von zusätzlichen Zeilenumbrüche zu haben, wo sie werden nicht benötigt. Die Lösung, die für mich am besten funktioniert, ist von http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/, wo er zeigt, wie Fehler- und Standardausgaben an den Logger senden:
import logging
import sys
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
filename="out.log",
filemode='a'
)
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
print "Test to standard out"
raise Exception('Test to standard error')
Die Ausgabe sieht so aus:
2011-08-14 14:46:20,573:INFO:STDOUT:Test to standard out
2011-08-14 14:46:20,573:ERROR:STDERR:Traceback (most recent call last):
2011-08-14 14:46:20,574:ERROR:STDERR: File "redirect.py", line 33, in
2011-08-14 14:46:20,574:ERROR:STDERR:raise Exception('Test to standard error')
2011-08-14 14:46:20,574:ERROR:STDERR:Exception
2011-08-14 14:46:20,574:ERROR:STDERR::
2011-08-14 14:46:20,574:ERROR:STDERR:Test to standard error
Beachten Sie, dass self.linebuf = ' 'wird der Flush behandelt, anstatt eine Flush-Funktion zu implementieren.
Dieser Code ist lizenziert [GPL] (https://www.electricmonk.nl/log/posting-license/). Ich bin nicht sicher, ob es sogar auf SO gepostet werden kann, was Kompatibilität mit [CC by-sa] erfordert (https://meta.stackexchange.com/help/licensing). – asmeurer
können Sie redirect_stdout Kontext-Manager verwenden:
import logging
from contextlib import redirect_stdout
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.write = lambda msg: logging.info(msg) if msg != '\n' else None
with redirect_stdout(logging):
print('Test')
oder ähnliche
import logging
from contextlib import redirect_stdout
logger = logging.getLogger('Meow')
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
fmt='[{name}] {asctime} {levelname}: {message}',
datefmt='%m/%d/%Y %H:%M:%S',
style='{'
)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.write = lambda msg: logger.info(msg) if msg != '\n' else None
with redirect_stdout(logger):
print('Test')
- 1. stderr Umleitung zu stdout
- 2. Wie stdout und stderr Logger-Datei in Kolben hinzufügen
- 3. Wie Umleitung Child-Prozess stdout/stderr auf den Hauptprozess stdout/stderr in Java?
- 4. Fangen stderr und stdout in log4j vor Unix-Umleitung
- 5. Umleitung stdout und stderr in eine einzelne Datei mit Präfixen
- 6. ABAP Stdout und Stderr
- 7. Linux G ++ Compiler Umleitung Stderr und Stdout erstellt leere Datei
- 8. Python Logging Split zwischen stdout und stderr
- 9. Speichern Sie stdout, stderr und stdout + stderr synchron
- 10. Wie steuert man Popen Stdin, Stdout, Stderr Umleitung?
- 11. Piping popen stderr und stdout
- 12. Unterdrücken stdout/stderr Drucken von Python-Funktionen
- 13. Apache Spark Stderr und Stdout
- 14. vim filter und stdout/stderr
- 15. paramiko kombinieren stdout und stderr
- 16. Wie erfasse ich Aufforderungen in stdout/stderr?
- 17. Umleitung stdout/stderr unter Unix-C-Datei ++ - wieder
- 18. Capture stderr von Python Subprozess.Popen (Befehl, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
- 19. Piping sowohl stdout und stderr in bash?
- 20. Wie stdout und stderr child_process in Gulp verwenden
- 21. LLVM stdin/stdout/stderr
- 22. Dupliziere stdout zu stderr
- 23. stdout Umleitung mit Ctypes
- 24. redirect stdout/stderr in C
- 25. über stdout/stderr Umleitungen
- 26. bash: Umleitung (und hängen) stdout und stderr Datei und Terminal und die richtige Exit-Status
- 27. Protokollierung und/oder stdout/stderr im Python-Daemon pflegen
- 28. umleiten stdout und stderr auf die gleiche Datei und wiederherstellen
- 29. Wie stdout und stderr von csh-Skript umleiten
- 30. Wiederherstellen von stdout und stderr Standardwert
Haben Sie externe Module/Bibliotheken, die FDs 1 und 2 direkt schreiben? –
@ IgnacioVazquez-Abrams Ich verstehe nicht wirklich, was du meintest, aber ich versuche es zu erklären. Ich benutze mehrere Python-Prozesse, und von allen möchte ich alle "stdout" und "stderr" Nachricht an meinen Logger umleiten. – orenma
Mögliches Duplikat von [Wie kopiere ich sys.stdout in eine Protokolldatei in Python?] (Https://stackoverflow.com/questions/616645/how-do-i-duplicate-sys-stdout-to-a-log -file-in-python) – user