Implementing an optional logger in code

Few options:

Create a dummy logger (my favorite):

logger = logger or logging.getLogger('dummy') #  without configuring dummy before.

Create a dummy object with one level null effect:

class DummyObject(object):
    def __getattr__(self, name):
        return lambda *x: None

logger = logger or DummyObject()

Nesting every debug statement in a block:

if logger:
    logger.debug("abc")

A do-nothing NullHandler is included in the logging module since Python 2.7:

import logging      
logging.getLogger('foo').addHandler(logging.NullHandler())

See the docs for configuring logging for a library.


Well, that's what the logging module is for. How to use, Cookbook.

If you really want to roll your own, I see a few alternatives:

  • self.logger attribute. Set when constructing the object or inherited from a base class. Each object has its own logger, so you can have selective logging per instance.

  • Logger class with static methods or standalone module. Could have default methods that do nothing, but the user is free to replace them with real handlers whenever the need arises. All classes access the same object or module. Lose granularity, but less work to set up.

  • Decorators. Put a @log('message', LEVEL) above each method you want to be logged and this will automatically call the log when the method is invoked. Considerably cleaner, less flexible.

Tags:

Python

Logging