Python3 module logging

In Python there exists logging module. You should use it instead of print function. In this article I’ll show you how use logging in sub-modules.

# parent.py
import logging
import sys
from child import Child


class Parent:
    def __init__(self):
        log.debug("this is a parent debug message")
        log.info("this is a parent info message")
        log.warning("this is a parent warning message")
        log.error("this is a parent error message")
        Child()


if __name__ == '__main__':
    # handler = logging.FileHandler("parent.log")
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    handler.setFormatter(logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    ))

    log = logging.getLogger()
    log.setLevel(logging.DEBUG)
    log.addHandler(handler)

    Parent()
else:
    log = logging.getLogger(__name__)
# child.py
import sys
import logging


class Child:
    def __init__(self):
        log.debug("this is a child debug message")
        log.info("this is a child info message")
        log.warning("this is a child warning message")
        log.error("this is a child error message")


if __name__ == '__main__':
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    ))
    handler.setLevel(logging.WARNING)

    log = logging.getLogger("custom-child-name")
    log.addHandler(handler)

    Child()
else:
    log = logging.getLogger(__name__)

If you run parent.py you will see all log messages from the parent and the child because the parent sets log level to DEBUG and the child inherrits from the parent. Parent’s logger names “root” (by default) and children’s logger names “child” (by module name).

If you run child.py you will see only warning and error messages because standalone run creates new logger with log level WARNING.

The magic is in getting the logger. logging.getLogger() returns root logger and logging.getLogger(__name__) creates new hierarchical structured logger. Of course you can use logging.getLogger(‘parent’) and then logging.getLogger(‘parent.child’) for the same effect.

Be aware of logging if you use some module with stdout (in example Urwid). Printing nor logging on sys.stdout will not work properly and you should log into file.

Leave a Reply

Your email address will not be published.