如何在回调中重置Python Logger?线程日志重复写入问题
问题分析与解决方案
问题原因
logging.basicConfig() 是全局日志配置的快捷方法,仅会在第一次调用时生效——它会初始化根日志器的输出文件、级别和格式,后续所有调用都会被直接忽略。
你的代码中每个线程都调用basicConfig,但只有第一个线程的配置会生效,后续线程的filename参数不会被处理。同时,你创建的各个线程专属Logger默认会将日志传播给根日志器,所以所有最终日志都会写入第一个线程创建的文件中,和你给Logger命名无关。
修复方案
放弃使用logging.basicConfig,手动为每个线程的Logger创建独立的FileHandler,确保每个Logger对应单独的日志文件:
def do_work(self, conn, ch, delivery_tag, body): thread_id = threading.get_ident() log_filename = f"{self.dict_config['filelog']}exchange_hashed_{thread_id}_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.log" # 创建线程专属Logger logger = logging.getLogger(f'exchange_hashed{thread_id}') logger.setLevel(logging.INFO) # 关闭日志传播,避免日志同时写入根日志器(可选,根据需求调整) logger.propagate = False # 检查是否已添加Handler,防止重复添加(比如Logger被意外复用的情况) if not logger.handlers: # 创建文件输出Handler file_handler = logging.FileHandler(log_filename) # 设置日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) # 将Handler绑定到当前Logger logger.addHandler(file_handler) # 后续日志逻辑保持不变 logger.info('Thread id: %s Delivery tag: %s', thread_id, delivery_tag) payload = body.decode("utf-8") payload = json.loads(payload) file_content = payload["values"] file_path = file_content["header"]["meta_data"]["file_name"] filename = file_path.split("/")[-1] logger.info(f"Data received for {filename}")
关键说明
- 每个线程的Logger通过
thread_id保证命名唯一,不会重复获取同一个Logger实例 - 手动创建的
FileHandler直接绑定到当前Logger,确保日志输出到指定文件 logger.propagate = False可以避免日志同时被根日志器处理(如果根日志器有其他输出的话,可选添加)- 检查
logger.handlers是否为空,是为了防止Logger被意外复用(比如线程ID重复的极端情况)时重复添加Handler,导致日志重复输出
内容的提问来源于stack exchange,提问作者FrozzenFinger
相关产品推荐
相关产品推荐

