Ich kann nicht herausfinden, wie man Info-Level-Nachrichten zu stdout, aber alles andere zu stderr protokolliert. Ich lese das bereits http://docs.python.org/library/logging.html. Irgendein Vorschlag?Logging, StreamHandler und Standard-Streams
Antwort
Das folgende Skript, log1.py
:
import logging, sys
class SingleLevelFilter(logging.Filter):
def __init__(self, passlevel, reject):
self.passlevel = passlevel
self.reject = reject
def filter(self, record):
if self.reject:
return (record.levelno != self.passlevel)
else:
return (record.levelno == self.passlevel)
h1 = logging.StreamHandler(sys.stdout)
f1 = SingleLevelFilter(logging.INFO, False)
h1.addFilter(f1)
rootLogger = logging.getLogger()
rootLogger.addHandler(h1)
h2 = logging.StreamHandler(sys.stderr)
f2 = SingleLevelFilter(logging.INFO, True)
h2.addFilter(f2)
rootLogger.addHandler(h2)
logger = logging.getLogger("my.logger")
logger.setLevel(logging.DEBUG)
logger.debug("A DEBUG message")
logger.info("An INFO message")
logger.warning("A WARNING message")
logger.error("An ERROR message")
logger.critical("A CRITICAL message")
wenn ausführen, erzeugt die folgenden Ergebnisse.
C:\temp>log1.py A DEBUG message An INFO message A WARNING message An ERROR message A CRITICAL message
Wie zu erwarten war, da auf einem Terminal sys.stdout
und sys.stderr
sind gleich. Nun lassen Sie uns umleiten stdout in eine Datei, tmp
:
C:\temp>log1.py >tmp A DEBUG message A WARNING message An ERROR message A CRITICAL message
So ist die INFO-Nachricht an das Terminal wurde nicht gedruckt - aber die Nachrichten gerichtet sys.stderr
haben gedruckt. Lassen Sie uns sehen, was ist in tmp
:
C:\temp>type tmp An INFO message
Damit Ansatz zu tun scheint, was Sie wollen.
Generell halte ich es für sinnvoll, Nachrichten umleiten niedriger als WARNING
zu stdout, statt nur INFO
Nachrichten macht.
Basierend auf Vinay Sajip ‚s ausgezeichnete Antwort, kam ich mit auf den Punkt:
class MaxLevelFilter(Filter):
'''Filters (lets through) all messages with level < LEVEL'''
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno < self.level # "<" instead of "<=": since logger.setLevel is inclusive, this should be exclusive
MIN_LEVEL= DEBUG
#...
stdout_hdlr = StreamHandler(sys.stdout)
stderr_hdlr = StreamHandler(sys.stderr)
lower_than_warning= MaxLevelFilter(WARNING)
stdout_hdlr.addFilter(lower_than_warning) #messages lower than WARNING go to stdout
stdout_hdlr.setLevel(MIN_LEVEL)
stderr_hdlr.setLevel(max(MIN_LEVEL, WARNING)) #messages >= WARNING (and >= STDOUT_LOG_LEVEL) go to stderr
#...
Da meine bearbeiten abgelehnt wurde, hier ist meine Antwort. @ Goncalopps Antwort ist gut, aber nicht alleine oder out of the box. Hier ist meine verbesserte Version:
import sys, logging
class LogFilter(logging.Filter):
"""Filters (lets through) all messages with level < LEVEL"""
# http://stackoverflow.com/a/24956305/408556
def __init__(self, level):
self.level = level
def filter(self, record):
# "<" instead of "<=": since logger.setLevel is inclusive, this should
# be exclusive
return record.levelno < self.level
MIN_LEVEL = logging.DEBUG
stdout_hdlr = logging.StreamHandler(sys.stdout)
stderr_hdlr = logging.StreamHandler(sys.stderr)
log_filter = LogFilter(logging.WARNING)
stdout_hdlr.addFilter(log_filter)
stdout_hdlr.setLevel(MIN_LEVEL)
stderr_hdlr.setLevel(max(MIN_LEVEL, logging.WARNING))
# messages lower than WARNING go to stdout
# messages >= WARNING (and >= STDOUT_LOG_LEVEL) go to stderr
rootLogger = logging.getLogger()
rootLogger.addHandler(stdout_hdlr)
rootLogger.addHandler(stderr_hdlr)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# Example Usage
>>> logger.debug("A DEBUG message")
>>> logger.info("An INFO message")
>>> logger.warning("A WARNING message")
>>> logger.error("An ERROR message")
>>> logger.critical("A CRITICAL message")
- 1. Raven's SentryHandler unterdrückt StreamHandler-Ausgabe in Datei
- 2. Sind Standardstreams-Dateien auf einem Datenträger gespeichert?
- 3. commons-logging und log4j Eigenschaftendatei
- 4. Logging mit Castle.Facilities.Logging und log4net
- 5. Django und fcgi - Logging-Frage
- 6. log4net Logging Debug.WriteLine und Console.WriteLine
- 7. Python Logging und Pydev Debugger?
- 8. Castle Logging Facility und log4net.Config.XmlConfigurator
- 9. API Logging und MYSQL Load
- 10. Spring Boot und Logging-Ort
- 11. Logging * Business * Events - Logging-Framework verwenden? hier
- 12. Wie richte ich einen zentralen Logging-Server ein und teile Logging-Ereignisse von Test und Produktion?
- 13. SynchronizationLockException + Logging
- 14. Logging-Strategie
- 15. Logging rekursiv
- 16. Symfony Logging
- 17. Scalaz: Validierung in einem Verständnis und Logging
- 18. dynamisch erstellen und zerstören Logging Appender
- 19. django Logging - django.request Logger und extra Kontext
- 20. Microsoft Logging Application Block und Multithreading
- 21. Java Logging mit log4j und log4j.yaml
- 22. Eclipse, Java und dotCMS Logging-Problem
- 23. Wie entkoppeln Sie Logging-Implementierung und API?
- 24. Windows Task Scheduler und Python Logging Modul
- 25. Logging Javascript/Jquery Fehler und Ausnahmen
- 26. Spark Web Framework Logging Anforderungen und Antworten
- 27. Python Logging Split zwischen stdout und stderr
- 28. Tensorflow verursacht Logging Nachrichten zu verdoppeln
- 29. Logging mit SL4J, Jakarta Commons Logging, log4j für Third Party Libraries und meinen eigenen Code
- 30. Tomcat 7 Logging gibt immer noch FINE und FINER Logging aus, obwohl INFO überall eingestellt ist
Wenn Sie eine Antwort wie die normale Art und Weise zu reagieren, ist es zu akzeptieren - das heißt, sie markiert als angenommen :-) –