Mastering Python Logging with a Singleton MyLog Class
This guide explains how to encapsulate a powerful, singleton-based logging system in Python using the MyLog class, covering OOP principles, code structure, and practical usage examples for flexible and maintainable log handling.
Effective logging is crucial in software development for debugging and maintenance. This article introduces a Python logging solution built around a custom MyLog class that leverages object‑oriented encapsulation and the Singleton pattern to provide a single, globally accessible logger.
What Is Encapsulation?
Encapsulation, one of the four core OOP principles, bundles data and the methods that operate on that data within a class, hiding internal implementation details and exposing only necessary interfaces. This improves code maintainability and reusability.
Design of the MyLog Class
The MyLog class implements a Singleton to ensure only one logger instance exists throughout the application lifecycle. The full class code is provided, defining constants for log path, name, format, and date format, and overriding __new__ to enforce the Singleton behavior.
import os
import logging
import sys
PATH = './logs'
NAME = 'default_log'
FMT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
DATEFMT = '%Y-%m-%d %H:%M:%S'
class MyLog(object):
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
MyLog._instance = object.__new__(cls)
return MyLog._instance
def __init__(self, config=None):
if config:
path = config.get('logpath')
name = config.get('logname')
else:
path = PATH
name = NAME
if not os.path.exists(path):
os.mkdir(path)
self.logger = logging.getLogger()
self.formatter = logging.Formatter(fmt=FMT, datefmt=DATEFMT)
self.log_filename = '{0}/{1}.log'.format(path, name)
self.logger.addHandler(self.get_file_handler(self.log_filename))
self.logger.addHandler(self.get_console_handler())
self.logger.setLevel(logging.DEBUG)
@classmethod
def get_instance(cls):
return cls._instance
def get_file_handler(self, filename):
filehandler = logging.FileHandler(filename, encoding="utf-8")
filehandler.setFormatter(self.formatter)
return filehandler
def get_console_handler(self):
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(self.formatter)
return console_handlerSingleton Implementation
The overridden __new__ method checks the class variable _instance. If it is None, a new instance is created and stored; otherwise, the existing instance is returned, guaranteeing a single logger object.
Constructor (__init__)
The constructor initializes the logger, allowing an optional configuration dictionary to specify custom log directory and filename. It creates the directory if missing, sets up a formatter, and attaches both file and console handlers.
Encapsulated Handler Creation
Two helper methods, get_file_handler and get_console_handler, encapsulate the creation of a file handler (with UTF‑8 encoding) and a console handler, respectively, each applying the shared formatter.
Usage Example
The following snippet demonstrates how to configure and use the MyLog class:
# Use MyLog class with custom log path and name
config = {
'logpath': './my_log_directory',
'logname': 'my_log_file'
}
logger = MyLog(config).logger
# Example log records
logger.debug("This is a debug message.")
logger.info("This is an info message.")
logger.warning("This is a warning message.")
logger.error("This is an error message.")
logger.critical("This is a critical message.")This example creates a configuration dictionary, initializes MyLog, and logs messages at various severity levels.
Conclusion
By encapsulating logging logic within a Singleton class, developers gain a flexible, reusable, and easily configurable logging system. Mastering these OOP techniques leads to cleaner, more maintainable code in real‑world Python projects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
