No puedo encontrar la forma de registrar mensajes de nivel de información a stdout, pero todo lo demás a stderr. Ya leí esto http://docs.python.org/library/logging.html. ¿Cualquier sugerencia?Registro, StreamHandler y transmisiones estándar
Respuesta
La siguiente secuencia de comandos, 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")
cuando se ejecuta, produce los siguientes resultados.
C:\temp>log1.py A DEBUG message An INFO message A WARNING message An ERROR message A CRITICAL message
Como era de esperar, ya que en un terminal sys.stdout
y sys.stderr
son los mismos. Ahora, vamos a redirigir la salida estándar a un archivo, tmp
:
C:\temp>log1.py >tmp A DEBUG message A WARNING message An ERROR message A CRITICAL message
Así que el mensaje INFO no se ha impreso al terminal - pero los mensajes dirigidos a sys.stderr
se han impreso. Veamos lo que está en tmp
:
C:\temp>type tmp An INFO message
Así que el enfoque parece hacer lo que quiera.
En general, creo que tiene sentido para redirigir los mensajes inferiores a WARNING
stdout, en lugar de sólo los mensajes INFO
.
Basado en excelente respuesta Vinay Sajip 's, se me ocurrió esto:
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
#...
Desde mi edición fue rechazado, aquí está mi respuesta. La respuesta de @ goncalopp es buena, pero no está sola ni funciona de la caja. Aquí está mi versión mejorada:
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. C# usando transmisiones
- 2. Abortar/cancelar transmisiones
- 3. Spring: aspecto de registro estándar (interceptor)
- 4. Anular las transmisiones de C++
- 5. ¿Qué desencadena las transmisiones BluetoothDevice.ACTION_ACL?
- 6. Obteniendo múltiples transmisiones desde intenciones?
- 7. Java: sincronización de salida estándar y error estándar
- 8. log4j: ¿Forma estándar de evitar mensajes de registro repetitivos?
- 9. ¿Puede iOS recibir transmisiones como Android?
- 10. ¿Las transmisiones se cierran automáticamente por error?
- 11. Tratamiento de archivos 7z como transmisiones .NET
- 12. ¿Puede un broadcastReceiver captar múltiples transmisiones?
- 13. Envío de transmisiones por correo electrónico
- 14. Cómo deshabilitar las transmisiones RSS en STS?
- 15. Wireshark no reconoce las transmisiones RTMP
- 16. java API de registro, deshabilitar el registro a la salida estándar
- 17. No se pueden recibir transmisiones para intenciones de PAQUETE
- 18. la salida estándar de registro y stderr al archivo usando Python conectarse 'con' declaración
- 19. Redirección de la salida estándar y de error que se agrega al mismo archivo de registro
- 20. std :: tuple y diseño estándar
- 21. Automake y bibliotecas compartidas estándar
- 22. Incompatibilidad de registro de Python entre 2.5 y 2.6
- 23. ¿Cómo puedo gzip estándar en un archivo y también imprimir estándar en estándar?
- 24. Registro Log4net y Unity
- 25. MSMQ y registro
- 26. ¿Se reciben las transmisiones de Android en orden?
- 27. ¿Cómo manejar múltiples transmisiones de video en Red5?
- 28. ¿Cómo puedo concatenar perfectamente las transmisiones de MP3?
- 29. Cuándo se producirá una EOFException en las transmisiones de JAVA
- 30. Ventajas de usar flush() close() en las transmisiones de Android?
Si te gusta una respuesta, la forma normal de respuesta es aceptarlo - es decir, marcarlo como aceptadas :-) –