logging模块写盘时报OSError [Errno 22] Invalid argument问题求助
根因分析
- ANSI转义字符导致Windows文件写入失败
从崩溃栈的Message字段可看到日志内容包含\x1b[37m\x1b[1m这类控制台颜色控制转义码,Windows系统的文件流不支持直接写入这类特殊控制字符,在flush阶段触发OSError: [Errno 22] Invalid argument错误。 - 多进程写入日志冲突
栈信息显示你使用了multiprocessing多进程架构,多个进程同时操作同一个日志文件句柄时,会导致文件流状态混乱,也是flush报错的常见诱因。 - 日志调用参数不规范
你调用logger.debug时直接将traceback内容作为第一个格式化参数传入,额外的job_name、address参数没有放到extra字典中,不符合标准logging模块的传参规范,可能引发不可预期的参数解析错误。
修复方案
1. 过滤日志中的ANSI控制字符
如果你的日志需要同时输出带颜色的控制台内容和纯文本的文件内容,给文件日志处理器添加过滤逻辑移除转义字符:
import re import logging def remove_ansi_escape(content: str) -> str: ansi_pattern = re.compile(r'\x1B(?:[@-Z\\-_]|\[.*?[a-zA-Z])') return ansi_pattern.sub('', content) class AnsiFilter(logging.Filter): def filter(self, record: logging.LogRecord) -> bool: record.msg = remove_ansi_escape(str(record.msg)) return True # 初始化文件日志处理器时添加过滤器 file_handler = logging.FileHandler('run.log', encoding='utf-8') file_handler.addFilter(AnsiFilter())
2. 改用多进程安全的日志方案
不要让多个子进程直接写同一个日志文件,推荐两种方案:
- 每个进程独立写入单独的日志文件,文件名带上进程标识
- 使用标准库提供的
QueueHandler+QueueListener方案,由主进程统一消费所有子进程的日志消息写入文件
3. 规范traceback日志写法
不需要手动调用traceback.format_exc(),使用logging内置的exc_info参数即可自动记录异常栈,额外参数统一放到extra字典中:
try: # 你的业务代码 except Exception: self.logger.debug( "RPC调用异常", exc_info=True, extra={"job_name": self.job_name, "address": self.short_wallet_address} )
内容的提问来源于stack exchange,提问作者Netman
相关产品推荐
相关产品推荐

