from loguru import logger import os from functools import wraps from myutils.ConfigManager import myCongif ''' @logger.catch() 异常捕获注解 ---- TRACE 5 DEBUG 10 INFO 20 SUCCESS 25 WARNING 30 ERROR 40 CRITICAL 50 ---- ''' #singleton--使用装饰器来保障单一实例的好处是能够动态加载,但线程不安全 def singleton(cls): instances = {} @wraps(cls) def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return get_instance @singleton class LogHandler(): def __init__(self, log_dir=myCongif.get_data('log_dir')): # 确保日志目录存在 if not os.path.exists(log_dir): os.makedirs(log_dir) # 清除所有以前的处理器 logger.remove() # 配置控制台输出 logger.add(lambda msg: print(msg, end=""), format="{time:YYYY-MM-DD_HH:mm:ss}-{extra[caller]}-{level}:{message}", level=myCongif.get_data('show_log_level')) # 配置文件输出 logger.add("logs/{time:YYYY-MM-DD}.log", rotation="00:00", retention="90 days", format="{time:YYYY-MM-DD_HH:mm:ss}-{extra[caller]}-{level}:{message}", level=myCongif.get_data('file_log_level')) def get_logger(self, caller): # 返回一个带有调用者信息的logger return logger.bind(caller=caller) # 示例类A class ClassA: def __init__(self): self.logger = LogHandler().get_logger("ClassA") def do_something(self): self.logger.warning("ClassA is doing something.") # 示例类B class ClassB: def __init__(self): self.logger = LogHandler().get_logger("ClassB") def do_something(self): self.logger.error("ClassB is doing something.") if __name__ == "__main__": a = ClassA() b = ClassB() r = myCongif.get_data('url') print(r) a.do_something() b.do_something()