Skip to content

Logging in Python

Abstract

Generally, we need to enable logging in multiple files. So, I prefer following

  1. Create a class for logger
  2. Set it as a variable in __init__.py
  3. Import logger in my code files and use it

Create a class for logger

I usually create a file inside a separate directory like logger/project_logger.py and define a Logger class.

Here are few examples

import logging


class Logger:
    def __init__(self) -> None:

        # Get logger
        self._logger = logging.getLogger()

        # Logging format
        log_formatter = logging.Formatter(
            '%(levelname)10s | %(funcName)40s() | %(message)s'
        )

        # Logs stream handler
        stream_handler = logging.StreamHandler()

        # Set logging format for handlers
        stream_handler.setFormatter(log_formatter)

        # Add handlers to loggers
        self._logger.addHandler(stream_handler)

        # Set log level
        self._logger.setLevel(logging.INFO)

    def get_logger(self) -> logging.RootLogger:
        """Returns Logger

        Returns:
            [type]: Logger
        """

        return self._logger
import logging
from datetime import datetime


class Logger:
    def __init__(self) -> None:

        # Get logger
        self._logger = logging.getLogger()

        # Logging format
        log_formatter = logging.Formatter(
            '%(levelname)10s | %(funcName)40s() | %(message)s'
        )

        # Logs file handler
        current_time = datetime.now()
        log_file = f"logs-{current_time.strftime('%m-%d-%Y-%HH%MM%SS')}.log"
        file_handler = logging.FileHandler(log_file)

        # Set logging format for handlers
        file_handler.setFormatter(log_formatter)

        # Add handlers to loggers
        self._logger.addHandler(file_handler)

        # Set log level
        self._logger.setLevel(logging.INFO)

    def get_logger(self) -> logging.RootLogger:
        """Returns Logger

        Returns:
            [type]: Logger
        """

        return self._logger
import logging
from datetime import datetime


class Logger:
    def __init__(self) -> None:

        # Get logger
        self._logger = logging.getLogger()

        # Logging format
        log_formatter = logging.Formatter(
            '%(levelname)10s | %(funcName)40s() | %(message)s'
        )

        # Logs stream handler
        stream_handler = logging.StreamHandler()

        # Logs file handler
        current_time = datetime.now()
        log_file = f"logs-{current_time.strftime('%m-%d-%Y-%HH%MM%SS')}.log"
        file_handler = logging.FileHandler(log_file)

        # Set logging format for handlers
        stream_handler.setFormatter(log_formatter)
        file_handler.setFormatter(log_formatter)

        # Add handlers to loggers
        self._logger.addHandler(stream_handler)
        self._logger.addHandler(file_handler)

        # Set log level
        self._logger.setLevel(logging.INFO)

    def get_logger(self) -> logging.RootLogger:
        """Returns Logger

        Returns:
            [type]: Logger
        """

        return self._logger

Note

Instead of defining get_logger() and using it to fetch LOGGER, we can also use @property decorator.

    @property
    def logger(self) -> logging.RootLogger:
    """Returns Logger

    Returns:
        [type]: Logger
    """

    return self._logger

Accessing it

    LOGGER = Logger().logger

Set it as a variable in logger/__init__.py file

Now we can create an object for Logger class inside __init__.py file and assign it to a variable.

from .project_logger import Logger

LOGGER = Logger().get_logger()

Tip

It will allow us to easily import this variable in our code and use it for logging.

Import logger in my code files and use it

Now we can use it for logging

from logger import LOGGER

LOGGER.info("This is some information")

LOGGER.error("This is some error")

Tip

Here, we are actually creating a python package called logger. When we import logger, __init__.py inside logger directory gets executed and variables defined in it can be imported.

Back to top