Consider the following code, where I have created a custom logger class and then in a for loop I am creating logger object multiple times, but instead of adding one log at a time it is adding multiple logs as shown below
import sys
import logging
import os
import configs
class Logger:
def __init__(self, logger_name='logger', log_file_name='logs.log'):
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler(os.path.join(configs.LOGS_DIR, log_file_name))
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
self.logger = logger
def get_logger(self):
return self.logger
for i in range(5):
logger = Logger(logger_name=f'test', log_file_name='test').get_logger()
logger.info(i)
I was expecting this:
2024-12-20 21:17:09,623 - test - INFO - 0
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,642 - test - INFO - 4
but this is the output:
2024-12-20 21:17:09,623 - test - INFO - 0
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
Why this is happening and how to fix this?
I solved this issue by creating Logger class like this:
class Logger:
@staticmethod
def __create_file_handler__(log_file_path, level, formatter):
file_handler = logging.FileHandler(log_file_path)
file_handler.setLevel(level)
file_handler.setFormatter(formatter)
return file_handler
@staticmethod
def get_logger(logger_name='logger', log_file_name='logs.log'):
logger = logging.getLogger(logger_name)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler_file_path = os.path.join(configs.LOGS_DIR, log_file_name)
file_handler_level = logging.INFO
if logger.hasHandlers():
file_handler = [_ for _ in logger.handlers if isinstance(_, logging.FileHandler)]
if file_handler:
file_handler = file_handler[0]
if file_handler.baseFilename != log_file_name:
logger.removeHandler(file_handler)
logger.addHandler(Logger.__create_file_handler__(
file_handler_file_path,
file_handler_level,
formatter
))
return logger
logger.setLevel(logging.DEBUG)
logger.addHandler(Logger.__create_file_handler__(
file_handler_file_path,
file_handler_level,
formatter
))
return logger
And then use logger in the for loop like this
for i in range(5):
logger = Logger.get_logger(logger_name=f'test', log_file_name='test')
logger.info(i)
This solves the problem.
Thank you @john-gordon [John Gordon] For giving me a insight to think about it in another way.