it-swarm.com.de

Wie kann ich die Konsolenprotokollierung in Python deaktivieren und erneut aktivieren?

Ich verwende das Python-Modul logging und möchte die Protokollierung der Konsole für einige Zeit deaktivieren, aber es funktioniert nicht.

#!/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 [<logging.StreamHandler instance at ...>]
# but I may have other handlers there that I want to keep

logger.debug("bla bla")

Der obige Code zeigt den bla bla bei stdout an und ich weiß nicht, wie ich den Console-Handler sicher deaktivieren kann. Wie kann ich sicher sein, dass ich den StreamHandler der Konsole vorübergehend entferne und nicht einen anderen?

120
sorin

Ich habe dafür eine Lösung gefunden:

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

Dadurch wird verhindert, dass die Protokollierung an den oberen Logger gesendet wird, der die Konsolenprotokollierung enthält.

168
sorin

Ich benutze:

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

Sie können verwenden:

logging.basicConfig(level=your_level)

wobei your_level einer von diesen ist:

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

Wenn Sie also your_level auf logging.CRITICAL setzen, erhalten Sie nur kritische Nachrichten, die von: 

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

Wenn Sie your_level auf logging.DEBUG setzen, werden alle Protokollierungsstufen angezeigt.

Weitere Informationen finden Sie unter Beispiele für die Protokollierung.

Um die Ebene für jeden Handler auf dieselbe Weise zu ändern, verwenden Sie die Funktion 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)
56
Vadikus

(lange tote Frage, aber für zukünftige Suchende)

Näher an dem Code/der Absicht des ursprünglichen Posters funktioniert dies für mich unter 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")

Das Problem, das ich ausarbeiten musste, war das Entfernen des stdout-Handlers after Hinzufügen eines neuen; Der Protokollierungscode wird angezeigt, um stdout automatisch wieder hinzuzufügen, wenn keine Handler vorhanden sind.

43
l82ky

Kontextmanager

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

Anwendungsbeispiel:

with DisableLogger():
    do_something()
35
pymen

Es gibt einige wirklich schöne Antworten, aber anscheinend wird die einfachste nicht zu sehr berücksichtigt (nur von infinito).

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

Dies deaktiviert den Root-Logger und somit alle anderen Logger. Ich habe nicht wirklich getestet, sollte aber auch der schnellste sein.

Aus dem Logging-Code in Python 2.7 sehe ich das

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)

Das heißt, wenn es deaktiviert ist, wird kein Handler aufgerufen, und es sollte effizienter sein, beispielsweise auf einen sehr hohen Wert zu filtern oder einen No-Op-Handler festzulegen.

26
andrea_crotti

Um die Protokollierung vollständig zu deaktivieren:

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3

So aktivieren Sie die Protokollierung:

logging.disable(logging.NOTSET)

Andere Antworten bieten Umgehungen, die das Problem nicht vollständig lösen, wie z

logging.getLogger().disabled = True

und für einige n größer als 50,

logging.disable(n)

Das Problem bei der ersten Lösung ist, dass sie nur für den Root-Logger funktioniert. Andere Logger, die beispielsweise mit logging.getLogger(__name__) erstellt wurden, werden von dieser Methode nicht deaktiviert.

Die zweite Lösung betrifft alle Protokolle. Die Ausgabe wird jedoch auf ein höheres als das angegebene Niveau begrenzt. Daher könnte man das Protokoll überschreiben, indem ein Protokoll mit einem Pegel von über 50 erstellt wird. 

Das kann durch verhindert werden

logging.disable(sys.maxint)

was soweit ich sagen kann (nach Überprüfung der source ) ist die einzige Möglichkeit, die Protokollierung vollständig zu deaktivieren.

17
starfry

Keine Notwendigkeit, stdout umzuleiten. Hier ist der bessere Weg:

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

logging.getLogger().addHandler(MyLogHandler())

Ein noch einfacher Weg ist:

logging.getLogger().setLevel(100)
10
Ehsan Foroughi

Ich kenne das Protokollierungsmodul nicht sehr gut, aber ich verwende es so, dass ich normalerweise nur Debug- (oder Info-) Nachrichten deaktivieren möchte. Sie können Handler.setLevel() verwenden, um die Protokollierungsstufe auf CRITICAL oder höher zu setzen.

Sie können auch sys.stderr und sys.stdout durch eine zum Schreiben geöffnete Datei ersetzen. Siehe http://docs.python.org/library/sys.html#sys.stdout . Aber ich würde das nicht empfehlen.

2
Krab

Du könntest auch:

handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers
2
Italo Maia

unterklasse den Handler, den Sie vorübergehend deaktivieren möchten:

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)

den Handler anhand des Namens zu finden, ist recht einfach:

_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))

einmal gefunden:

_handler.disable()
doStuff()
_handler.enable()
0
jake77
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 __== '__main__':
    a = A()
    a.say('111')
    a.disable_console_log()
    a.say('222')
    a.enable_console_log()
    a.say('333')

Konsolenausgabe:

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

inhalt der test.log-Datei:

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
0
Shawn Hu