3

I'm using the python logging module with an YAML config file. In there I define 2 formatters. How can I access these formatters dynamically? I want to overwrite the standard formatter attached to one of my handlers dynamically, if a certain event occurs.

As requested, a small example:

my logging config:

version: 1
disable_existing_loggers: False
formatters:
    console:
        class: colorlog.ColoredFormatter
        format: "%(log_color)s[%(asctime)s] [%(levelname)-8s] --- %(message)s (%(filename)s:%(lineno)s)"
        datefmt: "%Y-%m-%d %H:%M:%S"
    console_user:
        class: colorlog.ColoredFormatter
        format: "%(log_color)s[%(levelname)-8s] --- %(message)s"
handlers:
    console:
        class: logging.StreamHandler
        level: INFO
        formatter: console
        stream: ext://sys.stdout
root:
    level: DEBUG
    handlers: [console]

in my script I have something like:

    import logging
    logging.config.dictConfig(logging_config)
    logger = logging.getLogger()

Now I'd like to do something like

    logger.handlers[0].setFormatter('console_user')

however, there seems to be no reference to any formatters not associated with a handler.

1

2 Answers 2

1

While writing up the example I actually came up with a solution. It's not that nice, since it relies on creating dummy handlers for each formatter not associated with a handler yet, but seems to work.

So, basically for every formatter one could just add a dummy NullHandler, e.g.:

version: 1
disable_existing_loggers: False
formatters:
    simple:
        format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    info:
        format: "[%(asctime)s] [%(levelname)-8s] --- %(message)s (%(filename)s:%(lineno)s)"
        datefmt: "%Y-%m-%d %H:%M:%S"
    console:
        class: colorlog.ColoredFormatter
        format: "%(log_color)s[%(asctime)s] [%(levelname)-8s] --- %(message)s (%(filename)s:%(lineno)s)"
        datefmt: "%Y-%m-%d %H:%M:%S"
    console_user:
        class: colorlog.ColoredFormatter
        format: "%(log_color)s[%(levelname)-8s] --- %(message)s"
handlers:
    console:
        class: logging.StreamHandler
        level: INFO
        formatter: console
        stream: ext://sys.stdout
    dummy:
        class: logging.NullHandler
        formatter: console_user


root:
    level: DEBUG
    handlers: [console, dummy]

and then later on set

logger.handlers[0].setFormatter(logger.handlers[1].formatter)
Sign up to request clarification or add additional context in comments.

Comments

0

You cad dynamically create handler with proper formatter and attach it to your logger

logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create file handler which logs even debug messages
file_handler = logging.FileHandler('spam.log')
file_handler.setLevel(logging.DEBUG)

# create console handler with a higher log level
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR)

# create formatter and add it to the handlers
formatter = logging.Formatter('%(levelname)s - %(asctime)s - %(name)s: %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# add the handlers to logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# or remove corent handlers and set new
# logger.handlers = [console_handler, file_handler]

Or even change formatter in your logger handler:

formatter = logging.Formatter('%(levelname)s - %(asctime)s - %(name)s: %(message)s')
for handler in my_logger.handers:
    handler.setFormatter(formatter)

# also you may need to do it in logger parent logger
if my_logger.parent
for handler in my_logger.parent.handers:
    handler.setFormatter(formatter)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.