Privacy Policy
Snippets index

  Python logging example (with good practices, in a Django management command and In a standalone Python script)

Quick and dirty ...

import logging
import sys

def set_logger(verbosity, logger_name=__name__):
    logger = logging.getLogger(logger_name)
    levels = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
    loglevel = levels[min(len(levels)-1, verbosity)]  # capped to number of levels
    logger.setLevel(loglevel)
    handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s| %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger

then:

def handle(self, *args, **options):
    self.logger = set_logger(options['verbosity'])
    ...

Other examples ...

# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals

import time
import datetime
import logging
import sys
from django.core.management.base import NoArgsCommand


logger = logging.getLogger(__name__)


class Command(NoArgsCommand):

    def set_logger(self, verbosity):
        """
        Set logger level based on verbosity option
        """
        handler = logging.StreamHandler(sys.stdout)
        formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s| %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)

        if verbosity == 0:
            self.logger.setLevel(logging.WARN)
        elif verbosity == 1:  # default
            self.logger.setLevel(logging.INFO)
        elif verbosity > 1:
            self.logger.setLevel(logging.DEBUG)

        # verbosity 3: also enable all logging statements that reach the root logger
        if verbosity > 2:
            logging.getLogger().setLevel(logging.DEBUG)

    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def elapsed_display(self, t0):
        t = datetime.datetime.now()
        seconds = int((t - t0).total_seconds())
        return time.strftime("%H:%M:%S", time.gmtime(seconds))

    def handle(self, *args, **options):

        tasklist = [sample_task, test_logger_task, ]

        self.set_logger(options.get('verbosity'))

        cron_t0 = datetime.datetime.now()
        self.logger.info('==> cron started.' + '=' * 60)
        for task in tasklist:
            task_t0 = datetime.datetime.now()
            try:
                self.logger.info('--> %s() started.' % task.__name__)
                task()
            except Exception as e:
                logger.error(str(e), exc_info=True)
            finally:
                self.logger.info('<-- %s() finished [%s].' % (
                    task.__name__,
                    self.elapsed_display(task_t0),
                ))
        self.logger.info('<== cron finished [%s]. ' % self.elapsed_display(cron_t0) + '=' * 60)


def sample_task():
    logger.info('work ...')
    logger.info('more work ...')
    logger.info('even more work ...')


def test_logger_task():
    logger.error("boom !")
    logger.debug("This is a debug message")
    logger.info("Informational message")
    logger.error("An error has happened!")
    open('/path/to/does/not/exist', 'rb')

Output:

2017-07-14 12:13:33,803|INFO|aaa| ==> cron started.============================================================
2017-07-14 12:13:33,803|INFO|aaa| --> sample_task() started.
2017-07-14 12:13:33,803|INFO|aaa| work ...
2017-07-14 12:13:33,804|INFO|aaa| more work ...
2017-07-14 12:13:33,804|INFO|aaa| even more work ...
2017-07-14 12:13:33,804|INFO|aaa| <-- sample_task() finished [00:00:00].
2017-07-14 12:13:33,804|INFO|aaa| --> test_logger_task() started.
2017-07-14 12:13:33,804|ERROR|aaa| boom !
2017-07-14 12:13:33,804|INFO|aaa| Informational message
2017-07-14 12:13:33,804|ERROR|aaa| An error has happened!
2017-07-14 12:13:33,804|ERROR|aaa| [Errno 2] No such file or directory: u'/path/to/does/not/exist'
Traceback (most recent call last):
  File "/Users/morlandi/src2/brainstorm/test/test/test/management/commands/aaa.py", line 46, in handle
    task()
  File "/Users/morlandi/src2/brainstorm/test/test/test/management/commands/aaa.py", line 65, in test_logger_task
    open('/path/to/does/not/exist', 'rb')
IOError: [Errno 2] No such file or directory: u'/path/to/does/not/exist'
2017-07-14 12:13:33,805|INFO|aaa| <-- test_logger_task() finished [00:00:00].
2017-07-14 12:13:33,805|INFO|aaa| <== cron finished [00:00:00]. ============================================================

In a standalone Python script

import logging
import sys
import argparse


logger = logging.getLogger(__name__)


def set_logger(verbosity):
    """
    Set logger level based on verbosity option
    """
    handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(module)s| %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    if verbosity == 0:
        logger.setLevel(logging.WARN)
    elif verbosity == 1:  # default
        logger.setLevel(logging.INFO)
    elif verbosity > 1:
        logger.setLevel(logging.DEBUG)

    # verbosity 3: also enable all logging statements that reach the root logger
    if verbosity > 2:
        logging.getLogger().setLevel(logging.DEBUG)

...

def main():

    parser = argparse.ArgumentParser(
        description='Receive messages from an UDP socket'
    )
    parser.add_argument('host', type=str)
    parser.add_argument('port', type=int)
    parser.add_argument('--verbosity', '-v', type=int, default=1,
        help="Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output")
    args = parser.parse_args()

    set_logger(args.verbosity)

    logger.info('udp_receive started ...')
    receive_udp_messages(args.host, args.port)


if __name__ == "__main__":
    main()