【问题标题】:Using same logger and log files across multiple class instances? Problems/Conflicts?在多个类实例中使用相同的记录器和日志文件?问题/冲突?
【发布时间】:2020-08-23 00:57:34
【问题描述】:

我有 3 个类如下:

Class1 --> 使用 SameClassA --> 使用 SameClassB

Class2 --> 使用 SameClassA --> 使用 SameClassB

表示为“Class1”和“Class2”的继承/实现类使用相同的类“SameClassA”和“SameClassB”,它们没有被继承/实现。

在每个类中,我都使用相同的 initLogger() 函数。 “Class1”和“Class2”的 initLogger() 函数(记录器名称、记录器文件等)的实现是不同的;但是,“SameClassA”和“SameClassB”(相同的记录器名称、相同的记录器文件等)是相同的。

我注意到在实例化多个“SameClassA”时,我的 initLogger() 函数中发生了错误,而此时已经实例化了多个“SameClassA”。不幸的是,由于没有记录器,我没有堆栈跟踪。

但是,我想知道的是,这种配置是否会导致问题,我该如何解决?

这是我的 initLogger 函数:

    def initLogger(self, infoLog=True, debugLog=True, consoleLog=True):
    try: 
        parentLogDir = os.path.join(os.getcwd(), 'UniversalThreadLogs')
        if not os.path.exists(parentLogDir):
            os.mkdir(parentLogDir)
        infoLogDir = os.path.join(parentLogDir, 'INFOLog')
        if not os.path.exists(infoLogDir):
            os.mkdir(infoLogDir)
        errorLogDir = os.path.join(parentLogDir, "ERRORLog")
        if not os.path.exists(errorLogDir):
            os.mkdir(errorLogDir)

        infoLogFilepath = os.path.join(infoLogDir, "UTInfoLog.log")
        debugLogFilepath = os.path.join(errorLogDir, "UTErrorLog.log")

        LOG_FORMAT = ("%(asctime)s [%(levelname)s]: %(message)s in %(pathname)s:%(lineno)d")

        debugHandler = logging.handlers.RotatingFileHandler(filename=debugLogFilepath,maxBytes=5000000, backupCount=100)
        debugHandler.setLevel(logging.ERROR)
        debugHandler.setFormatter(Formatter(LOG_FORMAT))

        infoHandler = logging.handlers.RotatingFileHandler(filename=infoLogFilepath,maxBytes=5000000, backupCount=100)
        infoHandler.setLevel(logging.INFO)
        infoHandler.setFormatter(Formatter(LOG_FORMAT))

        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(logging.INFO)
        stream_handler.setFormatter(Formatter(LOG_FORMAT))

        UTLogger = logging.getLogger("UThread")
        if infoLog is True: 
            UTLogger.addHandler(infoHandler)
        if debugLog is True: 
            UTLogger.addHandler(debugHandler)
        if consoleLog is True: 
            UTLogger.addHandler(stream_handler)
        return UTLogger
    except: 
        return False

如前所述,对于“SameClassA”和“SameClassB”,上述 initLogger() 实现对于各自的类是相同的,例如具有相同的文件/目录和相同的记录器名称“UThread”。

谢谢

【问题讨论】:

    标签: python-3.x logging python-logging


    【解决方案1】:

    您只需要初始化一次日志记录。在程序开始时将initLogger() 作为独立方法调用一次,然后在每个类中获取对记录器的引用。

    import logging
    
    
    def init_logging(infoLog=True, debugLog=True, consoleLog=True):
        # what you currently have
    
        # this is just to create a working demo
        logging.basicConfig(
            format="%(asctime)s [%(levelname)s]: %(message)s in %(pathname)s:%(lineno)d",
            level=logging.DEBUG,
        )
    
    
    class ClassA:
        log = logging.getLogger("UThread")
    
        def say_hello(self):
            self.log.info("hello from class A")
            class_b = ClassB()
            class_b.say_hello()
    
    
    class ClassB:
        log = logging.getLogger("UThread")
    
        def say_hello(self):
            self.log.info("hello from class B")
    
    
    init_logging()
    class_a = ClassA()
    class_a.say_hello()
    

    这将输出

    2020-05-07 18:29:19,642 [INFO]: hello from class A in test.py:16
    2020-05-07 18:29:19,642 [INFO]: hello from class B in test.py:25
    

    【讨论】:

    • 感谢您的回复。我认为这绝对是正确的实施方式。但是,我仍然很好奇这是否会导致导致错误的冲突情况。总的来说,这是 Python 的合法性。
    • logging 就是这样设计的。在代码中的任何位置调用logging.getLogger(...) 都是安全的。在大多数情况下,您只需要配置一次日志记录。
    • 很公平。毫无疑问,您的方法是更好的方法。 FileHandlers 和 loggers 共享同一个日志文件怎么样?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多