Nie mogę dowiedzieć się, jak rejestrować komunikaty na poziomie informacji na standardowe wyjście, ale wszystko inne na stderr. Przeczytałem już to http://docs.python.org/library/logging.html. Jakieś sugestie?Rejestrowanie, StreamHandler i standardowe strumienie
Odpowiedz
Poniższy skrypt, 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")
podczas uruchamiania, produkuje następujące rezultaty.
C:\temp>log1.py A DEBUG message An INFO message A WARNING message An ERROR message A CRITICAL message
Jak można się spodziewać, ponieważ na terminalu sys.stdout
i sys.stderr
są takie same. A teraz przekierować stdout do pliku, tmp
:
C:\temp>log1.py >tmp A DEBUG message A WARNING message An ERROR message A CRITICAL message
Więc komunikat INFO nie został wydrukowany na terminal - ale komunikaty skierowane do sys.stderr
mają zostały wydrukowane. Spójrzmy na to, co znajduje się w tmp
:
C:\temp>type tmp An INFO message
Więc to podejście wydaje się robić to, co chcesz.
Generalnie myślę, że to ma sens przekierować wiadomości niższe niż WARNING
do stdout, zamiast tylko INFO
wiadomości.
podstawie doskonałą odpowiedź Vinay Sajip „s, wpadłem na to:
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
#...
Ponieważ moja edycja została odrzucona, oto moja odpowiedź. Odpowiedź @ goncalopp jest dobra, ale nie działa samodzielnie lub nie działa. Oto moja ulepszona wersja:
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. Strumienie Java - odchylenie standardowe
- 2. Test Gradle: pokaż strumienie standardowe tylko z konkretnymi testami
- 3. Raven's SentryHandler tłumi wyjście StreamHandler do pliku
- 4. Dopasowywanie wzorców i nieskończone strumienie
- 5. MSMQ i rejestrowanie
- 6. Gunicorn Django i rejestrowanie informacji w pliku
- 7. Czy standardowe strumienie wyjściowe są wątkowe w C++ (cout, cerr, clog)?
- 8. Rejestrowanie błędów w pliku
- 9. Strumienie Scala i ich wykorzystanie pamięci
- 10. Równoległość i Flatmap w Java 8 Strumienie
- 11. buforowane i niebuforowane Strumienie w Javie
- 12. obliczania liczb pierwszych (strumienie i lambda)
- 13. Jak działają strumienie dziennika Winstona?
- 14. Gniazda php a strumienie
- 15. strumienie w rakietach
- 16. Strumienie w Common Lisp?
- 17. Strumienie Java 8 "ifPresent"
- 18. Strumienie Java 8, lambdas
- 19. Szyfrowane strumienie OpenSSL
- 20. Strumienie kontra monady
- 21. Haskell: Listy kontra strumienie
- 22. Standardowe interfejsy
- 23. Typowe szare strumienie lisp
- 24. Wyłącz rejestrowanie dla konkretnej paczki
- 25. JBoss AS 7: Rejestrowanie
- 26. Rejestrowanie PySpark?
- 27. Rejestrowanie asynchroniczne
- 28. Rejestrowanie NSNotifications
- 29. Tworzenie i rejestrowanie nowych ról w Symfony2
- 30. Rejestrowanie w Pythonie pomiędzy stdout i stderr
Jeżeli chcesz odpowiedzieć, normalny sposób reagowania jest to zaakceptować - to znaczy oznaczyć go jako akceptowane :-) –