Vervang standaard handler van Python logger

Ik heb de volgende code draaien op elk verzoek van een wsgi (web2py) applicatie:

import logging, logging.handlers
from logging import StreamHandler, Formatter
def get_configured_logger(name):
    logger = logging.getLogger(name)
    if (len(logger.handlers) == 0):
        # This logger has no handlers, so we can assume it hasn't yet been configured (Django uses similiar trick)
        # === Configure logger ===
        # Create Formatted StreamHandler:
        FORMAT = "%(process)s %(thread)s: %(message)s"
        formatter = logging.Formatter(fmt=FORMAT)
        handler = logging.StreamHandler()
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.setLevel(logging.DEBUG)
        logger.debug('CONFIGURING LOGGER')
    return logger
# Get app specific logger:
logger = get_configured_logger(request.application)
logger.debug("TEST")

Het is bedoeld om de logger één keer te configureren, met de geformatteerde handler die ik wil. Het werkt, behalve dat ik dubbele invoer krijg in mijn stdout:

81893 4329050112: CONFIGURING LOGGER
DEBUG:dummy:CONFIGURING LOGGER
81893 4329050112: TEST
DEBUG:dummy:TEST

Hoe gebruik ik mijn nieuwe geformatteerde handler en verwijder/verberg de standaard handler?


Antwoord 1, autoriteit 100%

Misschien helpt het volgende voorbeeld. In principe kunt u ofwel de handlers verwijderen van de logger die u wilt uitschakelen, of niet verspreiden met de logger waarvan u aan het loggen bent.

$ cat testlog.py
import logging
logging.basicConfig(filename='foo', level=logging.DEBUG)
root_logger = logging.getLogger()
root_logger.debug('bar')
my_logger = logging.getLogger('my_logger')
FORMAT = "%(process)s %(thread)s: %(message)s"
formatter = logging.Formatter(fmt=FORMAT)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
my_logger.addHandler(handler)
my_logger.setLevel(logging.DEBUG)
my_logger.info('baz')
my_logger.propagate = False
my_logger.info('foobar')
my_logger.propagate = True
my_logger.info('foobaz')
root_logger.handlers = []
my_logger.info('barbaz')
$ python testlog.py
5927 140735224465760: baz
5927 140735224465760: foobar
5927 140735224465760: foobaz
5927 140735224465760: barbaz
$ cat foo
DEBUG:root:bar
INFO:my_logger:baz
INFO:my_logger:foobaz

Antwoord 2, autoriteit 9%

Je kunt de standaard handler uit de getLogger() verwijderen door dit te gebruiken:

logging.getLogger().removeHandler(logging.getLogger().handlers[0])

Of wis eerst de bestaande handlers voordat u de gewenste handlers toevoegt:

logging.getLogger().handlers.clear()

Hierna worden deze logboeken niet meer weergegeven, behalve de nieuwe handlers die u hebt toegevoegd:

DEBUG: Do stuff
WARNING: Do stuff

Other episodes