Skip to main content

Python logging example

The native logging class in Python can be a little cumbersome and daunting to use. I've combined the use of ArgParse along with some simple use of logging as an example that solves a lot of problems I often want to solve:

#! /usr/bin/env python
import logging
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-v', '--verbose', dest='verbose', action='count', help='Enable debugging - multiple uses prints more messages')
group.add_argument('--loglevel', dest='loglevel', action='store', help='Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL')
args = parser.parse_args()
logging.basicConfig(format='%(asctime)s %(levelname)s %(pathname)s:%(lineno)d %(msg)s')
log = logging.getLogger()
log.setLevel(args.loglevel or (logging.WARNING - (args.verbose or 0) * 10))
log.debug('This is a debugging message')
log.info('This is an informational message')
log.warn('This is a warning message')
log.error('This is an error message')
log.fatal('This is a fatal/critical message')
view raw log_example hosted with ❤ by GitHub
I figure I'll refer to this example when I want to make use of logging in scripts in the future.

This example does the following:

  • Default logging level is to print warning, error, and fatal/critical error messages. Debugging and warning messages are not printed
  • Using one -v option prints all of the messages above including informational messages
  • Using two -v options prints all of the messages above including debugging messages
  • Using three or more -v options does not change the behavior from using two options. There is no error but there is no benefit to additional options either
  • You can specify an explicit log level and even reduce messages using -loglevel LEVEL where LEVEL must be one of:
    • DEBUG
    • INFO
    • WARNING
    • ERROR
    • CRITICAL
    The script support the use of FATAL which is just synonymous with CRITICAL.
    The -loglevel LEVEL and -v options are mutually exclusive.
  • There's no way to dispose of messages altogether through the options but it can be done by redirecting stderr to /dev/null
  • A custom format includes elements of the error that I want printed
  • Logging messages go to stderr

Usage

Here's the script in action:

$ ./log_example
2019-01-18 08:26:31,929 WARNING ./log_example:16 This is a warning message
2019-01-18 08:26:31,929 ERROR ./log_example:17 This is an error message
2019-01-18 08:26:31,929 CRITICAL ./log_example:18 This is a fatal/critical message
$ ./log_example -v
2019-01-18 08:26:33,893 INFO ./log_example:15 This is an informational message
2019-01-18 08:26:33,893 WARNING ./log_example:16 This is a warning message
2019-01-18 08:26:33,893 ERROR ./log_example:17 This is an error message
2019-01-18 08:26:33,894 CRITICAL ./log_example:18 This is a fatal/critical message
$ ./log_example -vv
2019-01-18 08:26:35,603 DEBUG ./log_example:14 This is a debugging message
2019-01-18 08:26:35,603 INFO ./log_example:15 This is an informational message
2019-01-18 08:26:35,603 WARNING ./log_example:16 This is a warning message
2019-01-18 08:26:35,603 ERROR ./log_example:17 This is an error message
2019-01-18 08:26:35,603 CRITICAL ./log_example:18 This is a fatal/critical message
$ ./log_example -vvvvvvvvv
2019-01-18 08:26:38,438 DEBUG ./log_example:14 This is a debugging message
2019-01-18 08:26:38,438 INFO ./log_example:15 This is an informational message
2019-01-18 08:26:38,438 WARNING ./log_example:16 This is a warning message
2019-01-18 08:26:38,438 ERROR ./log_example:17 This is an error message
2019-01-18 08:26:38,438 CRITICAL ./log_example:18 This is a fatal/critical message
$

Comments

Popular posts from this blog

Dynamic Python script loading

I have a bunch of toys and tools in a Git repository - I affectionately call this my toys repo . Most are just scripts that I use from a Unix (Cygwin or Git bash on Windoze) command line but there are some Python classes that I sometimes use in another script. Today at work, I was coming up with a new Python script that made use of a couple of my public classes. The script is good enough to share with my colleagues but I'm faced with the problem of my public classes: I imagine that most of my colleagues haven't even heard of my public classes and I don't expect them to download the entire repo just to get a couple of classes If I'm going to distribute the classes as separate files I introduce new problems: It could be confusing to have the files tag along. What is the user supposed to do with them? The answer is nothing - they should leave them alone and make sure they are in the same directory as the main script in case they decide to move th...

Git-based version information from Python script

I had this idea of generating version information for a Python script that uses ArgParse . The code is a little more than I was expecting but I think it works well. Here is the code: Usage Here is an example of its usage if the script is part of a git repository: $ ./version-example --version b92798, master, 2019-01-18 10:35:02, ['origin:https://github.com/pfuntner/gists.git'] $ It contains: The SHA1 of last git commit that changed the script The current branch of the repository The date of the commit - I think the timezone element is present in this but I didn't want to deal with timezones so I'm ignoring it A list of the remote repositories This is printed on two lines but that's something that ArgParse is doing, not me. Here is an example of its usage if the script is not part of a git repository - we don't have much information to work from but we can at least get the timestamp of the script: $ ~/tmp/version-example --version 2019-01-...