write values multiple logger log files example disable_existing_loggers python logging

python - values - ¿Cómo se pueden enviar mensajes de registro INFO y DEPURAR a stdout y un mensaje de nivel superior a stderr?



python logging multiple files (6)

¿Hay alguna manera fácil con el módulo de registro de Python para enviar mensajes con un nivel DEBUG o INFO y el que tiene un nivel más alto a diferentes flujos?

¿Es una buena idea de todos modos?


No es necesariamente una buena idea (¡puede ser confuso ver información y depurar mensajes mezclados con salida normal!), Pero es factible, ya que puede tener múltiples objetos de manejador y un filtro personalizado para cada uno de ellos, para seleccionar y elegir registros de registro que maneja cada controlador.



directamente desde los documentos actualizados, cubre este caso bastante bien ahora.

http://docs.python.org/howto/logging.html#logging-advanced-tutorial

import sys # Add this. import logging # create logger logger = logging.getLogger(''simple_example'') logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler( sys.__stdout__ ) # Add this ch.setLevel(logging.DEBUG) # create formatter formatter = logging.Formatter(''%(asctime)s - %(name)s - %(levelname)s - %(message)s'') # add formatter to ch ch.setFormatter(formatter) # add ch to logger logger.addHandler(ch) # ''application'' code logger.debug(''debug message'') logger.info(''info message'') logger.warn(''warn message'') logger.error(''error message'') logger.critical(''critical message'')

He mencionado en los comentarios los dos cambios requeridos en el ejemplo para hacer que la salida vaya a stdout. también puede usar filtros para redirigir dependiendo del nivel.

Para obtener más información sobre cómo entender los cambios, visite http://docs.python.org/library/logging.handlers.html#module-logging.handlers.


Tuve el mismo problema y escribí un controlador de registro personalizado llamado SplitStreamHandler:

import sys import logging class SplitStreamHandler(logging.Handler): def __init__(self): logging.Handler.__init__(self) def emit(self, record): # mostly copy-paste from logging.StreamHandler try: msg = self.format(record) if record.levelno < logging.WARNING: stream = sys.stdout else: stream = sys.stderr fs = "%s/n" try: if (isinstance(msg, unicode) and getattr(stream, ''encoding'', None)): ufs = fs.decode(stream.encoding) try: stream.write(ufs % msg) except UnicodeEncodeError: stream.write((ufs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) stream.flush() except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record)


import logging import sys class LessThanFilter(logging.Filter): def __init__(self, exclusive_maximum, name=""): super(LessThanFilter, self).__init__(name) self.max_level = exclusive_maximum def filter(self, record): #non-zero return means we log this message return 1 if record.levelno < self.max_level else 0 #Get the root logger logger = logging.getLogger() #Have to set the root logger level, it defaults to logging.WARNING logger.setLevel(logging.NOTSET) logging_handler_out = logging.StreamHandler(sys.stdout) logging_handler_out.setLevel(logging.DEBUG) logging_handler_out.addFilter(LessThanFilter(logging.WARNING)) logger.addHandler(logging_handler_out) logging_handler_err = logging.StreamHandler(sys.stderr) logging_handler_err.setLevel(logging.WARNING) logger.addHandler(logging_handler_err) #demonstrate the logging levels logger.debug(''DEBUG'') logger.info(''INFO'') logger.warning(''WARNING'') logger.error(''ERROR'') logger.critical(''CRITICAL'')

Dejando a un lado la implementación, creo que es una buena idea utilizar las funciones de registro en python para enviarlas a la terminal, en particular porque puede agregar otro controlador para iniciar sesión en un archivo. Si establece que stdout sea INFO en lugar de DEPURAR, incluso puede incluir información de DEPURACIÓN adicional que el usuario no vería normalmente en el archivo de registro.


#!/usr/bin/env python3 # -*- coding: utf-8 -*- import logging import sys class LessThenFilter(logging.Filter): def __init__(self, level): self._level = level logging.Filter.__init__(self) def filter(self, rec): return rec.levelno < self._level log = logging.getLogger() log.setLevel(logging.NOTSET) sh_out = logging.StreamHandler(stream=sys.stdout) sh_out.setLevel(logging.DEBUG) sh_out.setFormatter(logging.Formatter(''%(levelname)s: %(message)s'')) sh_out.addFilter(LessThenFilter(logging.WARNING)) log.addHandler(sh_out) sh_err = logging.StreamHandler(stream=sys.stderr) sh_err.setLevel(logging.WARNING) sh_err.setFormatter(logging.Formatter(''%(levelname)s: %(message)s'')) log.addHandler(sh_err) logging.critical(''x'') logging.error(''x'') logging.warning(''x'') logging.info(''x'') logging.debug(''x'')