You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Logger已配置时,Daemon线程日志记录出现文件描述符错误

问题分析与解决方案

这个错误的核心原因是daemon包的DaemonContext默认会关闭所有非标准输入输出的文件描述符,而主程序通过logging.basicConfig打开的日志文件句柄会被这个操作关闭。当主程序后续尝试写入日志时,就会触发OSError: [Errno 9] Bad file descriptor错误——因为对应的文件已经被daemon的初始化流程关掉了。

下面是两种可行的解决方案:

方案1:让DaemonContext保留主程序的日志文件描述符

你可以在创建DaemonContext时,通过files_preserve参数指定需要保留的文件描述符,这样主程序的日志文件句柄就不会被关闭。

步骤如下:

  • 先获取主程序日志文件的文件描述符
  • 将它和守护进程的日志文件描述符一起加入files_preserve列表

示例代码:

import logging
import daemon
from daemon import pidfile

# 主程序配置日志
logging.basicConfig(level='DEBUG', filename="/some/directory/cstash.log")

# 获取主程序日志文件的文件描述符
main_log_fd = None
for handler in logging.root.handlers:
    if isinstance(handler, logging.FileHandler):
        main_log_fd = handler.stream.fileno()
        break

# 初始化守护进程上下文
with daemon.DaemonContext(
    pidfile=pidfile.PIDLockFile(self.pid_file),
    stderr=self.log_file,
    stdout=self.log_file,
    # 保留主程序和守护进程的日志文件描述符
    files_preserve=[main_log_fd, self.log_file.fileno()] if main_log_fd else [self.log_file.fileno()]
):
    self.watch_files()

方案2:在守护进程内部重新配置日志

既然daemon会关闭原来的文件句柄,那我们可以在守护进程启动后,重新初始化日志系统,让守护进程使用独立的日志配置,和主程序完全隔离。

示例代码(在watch_files方法内):

import logging

def watch_files(self):
    # 清空主程序遗留的日志handler,避免无效句柄
    root_logger = logging.getLogger()
    root_logger.handlers = []
    
    # 配置守护进程自己的日志
    daemon_handler = logging.FileHandler("/path/to/daemon-specific.log")
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    daemon_handler.setFormatter(formatter)
    
    root_logger.addHandler(daemon_handler)
    root_logger.setLevel(logging.DEBUG)
    
    # 后续的日志操作就会写入守护进程的独立文件
    logging.debug("Daemon started successfully")
    # ... 你的守护进程逻辑

两种方案对比:

  • 方案1适合需要主程序和守护进程共享部分日志上下文的场景,但需要确保文件描述符正确获取
  • 方案2更彻底,两者日志完全独立,避免了文件描述符冲突的问题,推荐用于日志分离的场景

内容的提问来源于stack exchange,提问作者Afraz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:32:57