Logging in Python
Abstract
Generally, we need to enable logging in multiple files. So, I prefer following
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.