# log.py import os from datetime import datetime import logging from logging.handlers import RotatingFileHandler from PubLibrary.InifileHelper import IniRead console_output = IniRead('system', 'console_output', '1') log_level = IniRead('system', 'algo_log_level', 'INFO') # 新增:日志去重缓存,key为日志内容,value为是否已打印 log_once_cache = set() def init_module_logger(): """ 初始化指定模块的日志器 :return: 对应模块的logger实例 """ # 缓存命中则直接返回 log_dir = './logs/' # 确保日志目录存在 os.makedirs(log_dir, exist_ok=True) log_file = os.path.join(log_dir, f'algo_log_{datetime.now().strftime("%Y-%m-%d")}.log') # 初始化logger logger = logging.getLogger('decoderLogger') logger.setLevel(log_level) if logger.handlers: return logger # 设置日志轮转,最大10个文件,每个10MB file_handler = RotatingFileHandler( log_file, maxBytes=10*1024*1024, backupCount=10, encoding='utf-8' ) # 日志格式 formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) file_handler.setFormatter(formatter) logger.setLevel(log_level) logger.addHandler(file_handler) if console_output: console_handler = logging.StreamHandler() console_handler.setFormatter(formatter) logger.addHandler(console_handler) return logger def algo_log(content, level="INFO", record_once=False): """ 通用日志函数,支持按模块输出到不同日志文件 :param content: 日志内容 :param level: 日志级别(DEBUG/INFO/WARNING/ERROR/FATAL) :param record_once: 是否只打印一次该日志内容,默认False """ # 初始化模块日志器 logger = init_module_logger() # 新增:处理只打印一次的逻辑 if record_once: # 生成唯一标识(可根据需要调整,比如拼接level增强唯一性) log_key = f"{level.upper()}_{content}" if log_key in log_once_cache: return # 已打印过,直接返回 log_once_cache.add(log_key) # 未打印过,加入缓存 # 根据级别输出日志 level_upper = level.upper() if level_upper == "DEBUG": logger.debug(content) elif level_upper == "WARNING": logger.warning(content) elif level_upper == "ERROR": logger.error(content) elif level_upper == "FATAL": logger.fatal(content) else: # 默认INFO级别 logger.info(content)