Наследование и синглтон не работают должным образом

#python #python-3.x #logging

#python #python-3.x #ведение журнала

Вопрос:

Имея эту конфигурацию проекта:

 - src/
   |-- classes/
      |-- Logger.py
      |-- Browser.py
   |-- ubigeo.py
- main.py
  

Я пытаюсь использовать python-logstash-logger настройку в Logger.py классе для печати журналов в Browser.py классе ubigeo.py и main.py скриптов:

 #Logger.py
import logging, logstash

class LoggerSingleton:
  _shared_state = {}

  def __init__(self):
    self.__dict__ = self._shared_state

class Logger(LoggerSingleton):
  def __init__(self):
    LoggerSingleton.__init__(self)
    self.logger = self.init_console_logger()

  def init_console_logger(self):
    logger = logging.getLogger('python-logstash-logger')
    logger.setLevel('DEBUG')

    formatter = logging.Formatter('%(asctime)s : %(levelname)s : %(message)s')

    sh = logging.StreamHandler()
    sh.setLevel(logging.INFO)
    sh.setFormatter(formatter)

    logger.addHandler(sh)

    return logger

  def log(self, message):
    self.logger.info(message)
  

Основная проблема заключается в том, что когда у меня есть несколько экземпляров одного и того же класса, журнал печатается несколько раз.

 #main.py
from src.classes import Logger

if __name__ == "__main__":
  logger_handler = Logger()
  logger_handler.log('Checking python version...')

  ubigeo.main()
  
 #Browser.py
from .Logger import Logger

class Browser(Config, Logger):
  def __init__(self):
    self.logger = Logger()
    self.logger.log('Setting up amp; launching a browser')
  
 #ubigeo.py
from .classes.Browser import Browser

def main():
  browser_handler = Browser()
  

Результат регистрации этого прямо сейчас:

 2019-04-21 13:25:12,758 : INFO : Checking python version...
2019-04-21 13:25:12,915 : INFO : Setting up amp; launching a browser
2019-04-21 13:25:12,915 : INFO : Setting up amp; launching a browser
  

и желаемый результат

 2019-04-21 13:25:12,758 : INFO : Checking python version...
2019-04-21 13:25:12,915 : INFO : Setting up amp; launching a browser
  

Комментарии:

1. Ваше определение класса Browser неверно в данном списке. он использует «self» вне контекста любого метода, что не сработало бы.

2. Я только что обновил свой код, так как я скопировал плохую часть, которую хотел показать

3. Вы получаете несколько сообщений, потому что вы вызываете Logger() один раз при каждом создании объекта Browser(). Logger() каждый раз вызывает AddHandler(), поэтому у вас есть несколько обработчиков.

4. Еще один (непрошеный) совет: не используйте «import src.classes.whatever»: src и классы — бесполезные имена для ваших каталогов. Весь ваш код является исходным кодом, и большая часть вашего кода будет классами.

5. Обычно люди используют модуль-глобальный регистратор, но передача его объекту также может работать.