elaspog
elaspog

Reputation: 1709

How to prevent logger printing same information multiple times?

When I instantiate MyClass multiple times, the same records appear in the log multiple times (after the second or third etc. initialization of the class).

This solution is already improved by these suggestions:

Duplicate log output when using Python logging module

Python logging module is printing lines multiple times

My logger solution looks like this:

import logging
import logging.handlers
import os

OUTPUT_DIRECTORY_PATH   = r'..\out'
LOG_DIRECTORY_PATH      = os.path.join(OUTPUT_DIRECTORY_PATH, "logs")

loggers = {}
def PlatformLogger(moduleName):

    global loggers

    if loggers.get(moduleName):

        return loggers.get(moduleName)

    else:

        # create logger with moduleName parameter
        logger = logging.getLogger(moduleName)
        logger.setLevel(logging.DEBUG)

        # create console handler with a higher log level
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)

        # create file handler which logs even debug messages
        fh = logging.FileHandler(os.path.join(LOG_DIRECTORY_PATH, 'error.log'))
        fr = logging.handlers.RotatingFileHandler(os.path.join(LOG_DIRECTORY_PATH, 'event.log'))
        fh.setLevel(logging.WARN)
        fr.setLevel(logging.DEBUG)

        # create formatter and add it to the handlers
        formatter = logging.Formatter('[%(asctime)s] - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        fr.setFormatter(formatter)
        ch.setFormatter(formatter)

        # add the handlers to the logger
        logger.addHandler(fh)
        logger.addHandler(fr)
        logger.addHandler(ch)

        # updating loggers
        loggers.update(dict(name=logger))

        return logger


class MyClass:

    def __init__(self):
        self.logger = PlatformLogger(__name__)

    def doSomething(self, actionName):
        self.logger.info("action: " + actionName)



dm1 = MyClass()
dm1.doSomething("action 1")
dm2 = MyClass()
dm2.doSomething("action 2")  # <- this is prited twice

What is in the log:

[2017-10-30 06:47:45,198] - __main__ - INFO - action: action 1
[2017-10-30 06:47:45,201] - __main__ - INFO - action: action 2
[2017-10-30 06:47:45,201] - __main__ - INFO - action: action 2

What am I doing wrong? What should I do to prevent this behaviour?

Upvotes: 3

Views: 3847

Answers (1)

Aleksandr Borisov
Aleksandr Borisov

Reputation: 2212

Instead of loggers.update(dict(name=logger)) you must write loggers.update({moduleName: logger}).

In line logger = logging.getLogger(moduleName) you always get the same logger by its name. So every time you instantiate your class you add new handlers to the logger and every handler prints a line. You must configure all the logging only once, on the module level.

Upvotes: 1

Related Questions