12

I am using logging module of python. How can I access the handlers defined in config file from the code. As an example, I have a logger defined and two handlers - one for screen and other for file. I want to use appropriate handler based on user preference (whether they want to log on screen or to a file). How can I dynamically add and remove handlers defined in config file from loggers defined in config file?

[loggers]

keys=root,netmap

[handlers]
keys=fil,screen

[logger_root]
level=NOTSET
handlers=

[logger_netmap]
level=INFO
handlers=fil,screen
qualname=netmap

[formatters]
keys = simple

[formatter_simple]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

[handler_fil]
class=handlers.RotatingFileHandler
args=('file.log','a','maxBytes=10000','backupCount=5')
formatter=simple

[handler_screen]
class=StreamHandler
args = (sys.stdout,)
formatter=simple

Depending on whether user runs the program with -v or not I need to use one of File or Screen Handler. How can I add or delete fil or screen handlers from netmap logger?

3
  • 1
    Please indent your config file sample 4 spaces so that it looks like code. Commented Dec 7, 2010 at 11:43
  • Or select it all and use the Code Sample button above the Answer text box or the ctrl-k shortcut key to indent it for you. Commented Dec 7, 2010 at 11:48
  • Does this config file load without errors? I get unorderable type str() > int() when trying to use the RotatingFileHandler section. In the end I ended up using args=('file.log', 'a', 1000, 5) Commented Aug 18, 2016 at 0:43

3 Answers 3

5

Instead of having to dynamically change the config file, just use Logger.addHandler(handler).

fileHandler = logging.handlers.RotatingFileHandler('file.log', mode='a', maxBytes=10000, backupCount=5)
logger = logging.getLogger('netmap')

if LOG_TO_FILE:
    logger.addHandler(fileHandler)

Then to load in formatting from perhaps the same file;

import ConfigParser
configParser = ConfigParser.ConfigParser()
config.read('config.ini')

format = config.get('formatter_simple', 'format')
fileHandler.setFormatter(format)
Sign up to request clarification or add additional context in comments.

7 Comments

This is of course an option. But suppose the user needs to change the format of the handler. If I do it this way, the code would have to be changed, which wud defeat the purpose of having a config file.
Is there no way to reference the handlers defined in the configuration file. Say we define the two handlers but do not associate them with any logger in the config file. At run time we somehow obtain the handlers and use addHandler? I know that logger.handlers is alist of all handlers associated with logger. Is there any list of all defined handlers?
The only way you can reference the handlers in the config file is to use a ConfigParser. How about if you took it back a level, and used two different loggers instead of two different handles?
Yes that wud be gud. If the program is huge and uses multiple loggers(for multiple modules), wudn't it become a bit untidy?
It could become messy, just keep all your loggers in the config file. For parsing the Handlers from the config file, just write a function that creates a new handler object for each handler entry.
|
1

From the logging module's documentation it looks like logging objects have these two methods:

Logger.addHandler(hdlr)

  Adds the specified handler hdlr to this logger.

Logger.removeHandler(hdlr)

  Removes the specified handler hdlr from this logger.

So it seems like you ought be able to use them to add or change the netmap logger handler to be whatever you want based on what's in the config file.

3 Comments

Yes bt how do I get the "hdlr" part required for calling the methods. I mean how can the handlers defined be referenced. E.g. For the above example, suppose we don't associate any handler with logger. Now if we need to add handler_fil, hw do we call addHandler - logger.addHandler('handler_fil')??
@RedBaron: In your question you said "I have a logger defined and two handlers" so I assumed all you wanted to know how to associate the proper handler with your logger. From your comment here it sounds like what you really want to know how to create a logging handler from the information in the config file in the [handler_fil] and [handler_screen] sections. Is that correct?
kind of...bt I also want to know that even if I already have two handlers associated with my logger in the config file, how can dissasociate one of them from the code. That is why I am asking what would be filled in the (hdlr) part of function call
0

Ok So I found an elegant way through a gud soul on the python google group. It works like charm. Here's the code

import logging
import getopt
import sys
import logging.config

def stop(m,handl):
    consoleHand=[h for h in m.handlers if h.__class__ is handl]
    print consoleHand
    if consoleHand:
        h1=consoleHand[0]
        h1.filter=lambda x: False


logging.config.fileConfig('log.conf')
my_log = logging.getLogger('netmap')
args=sys.argv[1:]
opt,arg = getopt.gnu_getopt(args,'v')
l=''
for o,a in opt:
    if o=='-v':
        l='verbose'
        stop(my_log,logging.handlers.RotatingFileHandler)
if not l:
    stop(my_log,logging.StreamHandler)
my_log.debug('Starting.....')
my_log.warning('Unstable')
my_log.error('FIles Missing')
my_log.critical('BlowOut!!')

The config file is still the same. I can now easily activate or deactivate handlers.

2 Comments

FWIW, the .handlers member of a logging instance is undocumented (although not marked private with a leading '_' on its name). As written this code is fragile in the sense that it will break if the class of you file handler named in the config file is changed but this code is not. If would be better if the class passed to stop() was also determined by reading the same file.
And how would that be done? Also there is no way to access handlers by the name defined in the config file as far as I can see

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.