¿Cómo deshabilito y reactivo el registro de la consola en Python?

Estoy usando el módulo de registro de Python y quiero deshabilitar el registro de la consola por un tiempo, pero no funciona.

#!/usr/bin/python import logging logger = logging.getLogger() # this gets the root logger # ... here I add my own handlers #logger.removeHandler(sys.stdout) #logger.removeHandler(sys.stderr) print logger.handlers # this will print [] # but I may have other handlers there that I want to keep logger.debug("bla bla") 

El código anterior muestra el bla bla en la salida estándar y no sé cómo puedo desactivar de forma segura el controlador de la consola. ¿Cómo puedo asegurarme de que elimine temporalmente la consola StreamHandler y no otra?

Encontré una solución para esto:

 logger = logging.getLogger('my-logger') logger.propagate = False # now if you use logger it will not log to console. 

Esto evitará que el registro se envíe al registrador superior que incluye el registro de la consola.

Yo suelo:

 logger = logging.getLogger() logger.disabled = True ... whatever you want ... logger.disabled = False 

Puedes usar:

 logging.basicConfig(level=your_level) 

donde tu nivel es uno de esos:

  'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL 

Por lo tanto, si configura su_nivel a registro.CRÍPICO , solo recibirá mensajes críticos enviados por:

 logging.critical('This is a critical error message') 

Al establecer su nivel en logging.DE, se mostrarán todos los niveles de registro.

Para más detalles, eche un vistazo a los ejemplos de registro.

De la misma manera para cambiar el nivel de cada Handler, use la función Handler.setLevel () .

 import logging import logging.handlers LOG_FILENAME = '/tmp/logging_rotatingfile_example.out' # Set up a specific logger with our desired output level my_logger = logging.getLogger('MyLogger') my_logger.setLevel(logging.DEBUG) # Add the log message handler to the logger handler = logging.handlers.RotatingFileHandler( LOG_FILENAME, maxBytes=20, backupCount=5) handler.setLevel(logging.CRITICAL) my_logger.addHandler(handler) 

(Pregunta muerta hace tiempo, pero para futuros buscadores)

Más cerca del código / intención del cartel original, esto funciona para mí en python 2.6

 #!/usr/bin/python import logging logger = logging.getLogger() # this gets the root logger lhStdout = logger.handlers[0] # stdout is the only handler initially # ... here I add my own handlers f = open("/tmp/debug","w") # example handler lh = logging.StreamHandler(f) logger.addHandler(lh) logger.removeHandler(lhStdout) logger.debug("bla bla") 

El gotcha que tuve que hacer fue quitar el controlador de la salida de la consola después de agregar uno nuevo; el código del registrador aparece para volver a agregar automáticamente la salida estándar si no hay controladores presentes.

Gestor de contexto

 import logging class DisableLogger(): def __enter__(self): logging.disable(logging.CRITICAL) def __exit__(self, a, b, c): logging.disable(logging.NOTSET) 

Ejemplo de uso:

 with DisableLogger(): do_something() 

Hay algunas respuestas realmente buenas aquí, pero aparentemente la más simple no se toma demasiado en consideración (solo de infinito).

 root_logger = logging.getLogger() root_logger.disabled = True 

Esto deshabilita el registrador raíz, y por lo tanto todos los otros registradores. Realmente no he probado, pero debería ser también el más rápido.

Desde el código de registro en Python 2.7 veo esto

 def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) 

Lo que significa que cuando está deshabilitado no se llama a ningún controlador, y debería ser más eficiente que filtrar a un valor muy alto o establecer un controlador sin operación, por ejemplo.

Para deshabilitar completamente el registro :

 logging.disable(sys.maxint) # Python 2 logging.disable(sys.maxsize) # Python 3 

Para habilitar el registro :

 logging.disable(logging.NOTSET) 

Otras respuestas proporcionan soluciones que no resuelven completamente el problema, como

 logging.getLogger().disabled = True 

y, para algunos n mayores de 50,

 logging.disable(n) 

El problema con la primera solución es que solo funciona para el registrador raíz. Este método no deshabilita otros registradores creados utilizando, por ejemplo, logging.getLogger(__name__) .

La segunda solución afecta a todos los registros. Pero limita la salida a niveles superiores a los dados, por lo que uno podría anularlo al iniciar sesión con un nivel superior a 50.

Eso puede ser prevenido por

 logging.disable(sys.maxint) 

que, por lo que puedo decir (después de revisar la fuente ) es la única forma de deshabilitar completamente el registro.

No hay necesidad de desviar stdout. Aquí es mejor manera de hacerlo:

 import logging class MyLogHandler(logging.Handler): def emit(self, record): pass logging.getLogger().addHandler(MyLogHandler()) 

Una forma aún más simple es:

 logging.getLogger().setLevel(100) 

No conozco muy bien el módulo de registro, pero lo estoy usando de la forma en que normalmente quiero deshabilitar solo los mensajes de depuración (o información). Puede usar Handler.setLevel() para establecer el nivel de registro en CRÍTICO o superior.

Además, podría reemplazar sys.stderr y sys.stdout por un archivo abierto para escritura. Consulte http://docs.python.org/library/sys.html#sys. stdout Pero no lo recomendaría.

También podrías:

 handlers = app.logger.handlers # detach console handler app.logger.handlers = [] # attach app.logger.handlers = handlers 
 import logging log_file = 'test.log' info_format = '%(asctime)s - %(levelname)s - %(message)s' logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'info_format': { 'format': info_format }, }, 'handlers': { 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'info_format' }, 'info_log_file': { 'class': 'logging.handlers.RotatingFileHandler', 'level': 'INFO', 'filename': log_file, 'formatter': 'info_format' } }, 'loggers': { '': { 'handlers': [ 'console', 'info_log_file' ], 'level': 'INFO' } } }) class A: def __init__(self): logging.info('object created of class A') self.logger = logging.getLogger() self.console_handler = None def say(self, word): logging.info('A object says: {}'.format(word)) def disable_console_log(self): if self.console_handler is not None: # Console log has already been disabled return for handler in self.logger.handlers: if type(handler) is logging.StreamHandler: self.console_handler = handler self.logger.removeHandler(handler) def enable_console_log(self): if self.console_handler is None: # Console log has already been enabled return self.logger.addHandler(self.console_handler) self.console_handler = None if __name__ == '__main__': a = A() a.say('111') a.disable_console_log() a.say('222') a.enable_console_log() a.say('333') 

Salida de consola:

 2018-09-15 15:22:23,354 - INFO - object created of class A 2018-09-15 15:22:23,356 - INFO - A object says: 111 2018-09-15 15:22:23,358 - INFO - A object says: 333 

Contenido del archivo test.log:

 2018-09-15 15:22:23,354 - INFO - object created of class A 2018-09-15 15:22:23,356 - INFO - A object says: 111 2018-09-15 15:22:23,357 - INFO - A object says: 222 2018-09-15 15:22:23,358 - INFO - A object says: 333 

subclase el controlador que desea poder desactivar temporalmente:

 class ToggledHandler(logging.StreamHandler): """A handler one can turn on and off""" def __init__(self, args, kwargs): super(ToggledHandler, self).__init__(*args, **kwargs) self.enabled = True # enabled by default def enable(self): """enables""" self.enabled = True def disable(self): """disables""" self.enabled = False def emit(self, record): """emits, if enabled""" if self.enabled: # this is taken from the super's emit, implement your own try: msg = self.format(record) stream = self.stream stream.write(msg) stream.write(self.terminator) self.flush() except Exception: self.handleError(record) 

Encontrar el controlador por nombre es bastante fácil:

 _handler = [x for x in logging.getLogger('').handlers if x.name == your_handler_name] if len(_handler) == 1: _handler = _handler[0] else: raise Exception('Expected one handler but found {}'.format(len(_handler)) 

una vez encontrado:

 _handler.disable() doStuff() _handler.enable()