Easier way to enable verbose logging

I want to add a debug print statement test, if I enable --verbose from the command line and if I have the following in the script.

logger.info("test")

I went through the following questions, but couldn't get the answer...

  • How to implement the --verbose or -v option into a script?

  • Python logging - Is there something below DEBUG?


Solution 1:

I find both --verbose (for users) and --debug (for developers) useful. Here's how I do it with logging and argparse:

import argparse
import logging

parser = argparse.ArgumentParser()
parser.add_argument(
    '-d', '--debug',
    help="Print lots of debugging statements",
    action="store_const", dest="loglevel", const=logging.DEBUG,
    default=logging.WARNING,
)
parser.add_argument(
    '-v', '--verbose',
    help="Be verbose",
    action="store_const", dest="loglevel", const=logging.INFO,
)
args = parser.parse_args()    
logging.basicConfig(level=args.loglevel)

So if --debug is set, the logging level is set to DEBUG. If --verbose, logging is set to INFO. If neither, the lack of --debug sets the logging level to the default of WARNING.

Solution 2:

You need to combine the wisdom of the Argparse Tutorial with Python's Logging HOWTO. Here's an example...

> cat verbose.py 
#!/usr/bin/env python

import argparse
import logging

parser = argparse.ArgumentParser(
    description='A test script for http://stackoverflow.com/q/14097061/78845'
)
parser.add_argument("-v", "--verbose", help="increase output verbosity",
                    action="store_true")

args = parser.parse_args()
if args.verbose:
    logging.basicConfig(level=logging.DEBUG)

logging.debug('Only shown in debug mode')

Run the help:

> ./verbose.py -h
usage: verbose.py [-h] [-v]

A test script for http://stackoverflow.com/q/14097061/78845

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  increase output verbosity

Running in verbose mode:

> ./verbose.py -v
DEBUG:root:Only shown in debug mode

Running silently:

> ./verbose.py   
> 

Solution 3:

Here is a more concise method, that does bounds checking, and will list valid values in help:

parser = argparse.ArgumentParser(description='This is a demo.')
parser.add_argument("-l", "--log", dest="logLevel", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], help="Set the logging level")

args = parser.parse_args()
if args.logLevel:
    logging.basicConfig(level=getattr(logging, args.logLevel))

Usage:

demo.py --log DEBUG

Solution 4:

Another variant would be to count the number of -v and use the count as an index to the a list with the actual levels from logging:

import argparse
import logging

parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose', action='count', default=0)
args = parser.parse_args()

levels = [logging.WARNING, logging.INFO, logging.DEBUG]
level = levels[min(len(levels)-1,args.verbose)]  # capped to number of levels

logging.basicConfig(level=level,
                    format="%(asctime)s %(levelname)s %(message)s")

logging.debug("a debug message")
logging.info("a info message")
logging.warning("a warning message")

This works for -vvvv, -vvv, -vv, -v, -v -v , etc, If no -v then logging.WARNING is selected if more -v are provided it will step to INFO and DEBUG