11

I currently have:

FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(format=FORMAT, datefmt='%d/%m/%Y %H:%M:%S', filename=LOGFILE, level=getattr(logging, options.loglevel.upper()))

... which works great, however I'm trying to do:

FORMAT = '%(MYVAR)s %(asctime)s - %(levelname)s - %(message)s'

and that just throws keyerrors, even though MYVAR is defined.

Is there a workaround? MYVAR is a constant, so it would be a shame of having to pass it everytime I invoke the logger.

Thank you!

1
  • 3
    If MYVAR is going to have always the same value, isn't FORMAT = '{} %(asctime)s - %(levelname)s - %(message)s'.format(MYVAR) a possible alternative? Commented Apr 24, 2013 at 23:43

4 Answers 4

19

You could use a custom filter:

import logging

MYVAR = 'Jabberwocky'


class ContextFilter(logging.Filter):
    """
    This is a filter which injects contextual information into the log.
    """
    def filter(self, record):
        record.MYVAR = MYVAR
        return True

FORMAT = '%(MYVAR)s %(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(format=FORMAT, datefmt='%d/%m/%Y %H:%M:%S')

logger = logging.getLogger(__name__)
logger.addFilter(ContextFilter())

logger.warning("'Twas brillig, and the slithy toves")

yields

Jabberwocky 24/04/2013 20:57:31 - WARNING - 'Twas brillig, and the slithy toves
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you ever so much - that's indeed the correct way to proceed!
Doesn't work form me in python 2.7. The solution is adding the ContextFilter() to a handler instead.
12

You could use a custom Filter, as unutbu says, or you could use a LoggerAdapter:

import logging

logger = logging.LoggerAdapter(logging.getLogger(__name__), {'MYVAR': 'Jabberwocky'})

FORMAT = '%(MYVAR)s %(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(format=FORMAT, datefmt='%d/%m/%Y %H:%M:%S')

logger.warning("'Twas brillig, and the slithy toves")

which gives

Jabberwocky 25/04/2013 07:39:52 - WARNING - 'Twas brillig, and the slithy toves

Alternatively, just pass the information with every call:

import logging

logger = logging.getLogger(__name__)

FORMAT = '%(MYVAR)s %(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(format=FORMAT, datefmt='%d/%m/%Y %H:%M:%S')

logger.warning("'Twas brillig, and the slithy toves", extra={'MYVAR': 'Jabberwocky'})

which gives the same result.

Since MYVAR is practically constant, the LoggerAdapter approach requires less code than the Filter approach in your case.

1 Comment

Does logging.basicConfig(format=FORMAT) change the format for all the loggers? How to change it only for this new logger adapter? Thanks
6

Borrowing from a comment above, I found that the simplest way to do this when the variable is static for all log entries is to simply include it in the formatter itself:

FORMAT = '{} %(asctime)s - %(levelname)s - %(message)s'.format(MYVAR)

With this method, no custom class implementation is required, and you don't have to worry about methods which are not defined for the various classes (LoggerAdapter and CustomAdapter), such as addHandler(). Admittedly, this is probably less Pythonic but it worked as a quick solution for me.

Comments

-1
locals()
FORMAT = '%(MYVAR)s %(asctime)s - %(levelname)s - %(message)s'

locals() should return a dictionary of all variables locally available, then the error. If you don't see it in there, then its not locally available. This will prove its not defined properly. We would need more code to see if it was defined improperly. Alternatively you can try "globals()" to check the global ones.... but you probably arent putting "global MYVAR " in the definition that outputs FORMAT

1 Comment

I tried printing locals and I can see my var as part of the output: 'MYVAR': 'blahblah'

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.