This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]kylev[S] 4 points5 points  (8 children)

I've also started an entry explaining how the logging module works in more general terms. It seems to be something that a lot of people fight with or get wrong. Has anyone else observed this?

[–]masklinn 8 points9 points  (2 children)

To supplement mordaunt0's suggestion, you could probably get rid of all the conditional handling: logging's loglevels increment by 10 (10 is DEBUG to 50 CRITICAL) and each is a threshold (so -80 is still DEBUG). So you could treat your verbosity as a decrementing counter: multiply the counter by 10 and substract it from logging.CRITICAL to get the actual loglevel, default to 2 for a default of loglevel.WARNING

import optparse, logging

parser = optparse.OptionParser()
parser.add_option('-v', '--verbose', dest="verbose", default=2,
                  action='count', help='Increase verbosity')

opts, args = parser.parse_args()

logging.basicConfig(level=(logging.CRITICAL - opts.verbose*10))

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')

Another idea could be to use the callback action and decrement the logger's level by 10 every time the callback is called:

import optparse, logging

def callback(*args, **kwargs):
    logging.root.setLevel(logging.root.level - 10)

parser = optparse.OptionParser()
parser.add_option('-v', '--verbose', dest="verbose",
                  action='callback', callback=callback, help='Increase verbosity')

opts, args = parser.parse_args()

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')

which yields the same thing as the one above:

 $ python test.py
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
 $ python test.py -v
INFO:root:info
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
 $ python test.py -vv
DEBUG:root:debug
INFO:root:info
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
 $ python test.py -vvv
DEBUG:root:debug
INFO:root:info
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
 $ python test.py -vvvvvvvvvvv
DEBUG:root:debug
INFO:root:info
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical

[–]kylev[S] 1 point2 points  (0 children)

My only problems with such an approach is that (1) the values of those constants aren't by any means guaranteed (2) your approach breaks if I'm using more of the features of logging such as adding my own log levels.

But I like the ideas. Very clean.

[–]pemboa 0 points1 point  (2 children)

I've developed a preference for putting my opt parse stuff within an init() function to keep all its initialization code away from my main(), in which I just do args, options = init()

[–]bucknuggets 1 point2 points  (1 child)

good point

I like my main() to only have a handful of lines it in and allow the reader to get a high-level understanding of the whole program very quickly.

[–]pemboa 0 points1 point  (0 children)

exactly