维护记录和/或标准输出/标准错误在Python守护进程(Maintaining Logging an

2019-07-03 12:02发布

我发现了在Python中创建一个守护进程,每个配方包括分叉两次(对于Unix),然后关闭所有打开的文件描述符。 (参见http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/的示例)。

这一切都是很简单的,但我似乎有一个问题。 在生产机器,我设置了,我的守护进程中止 - 默默的,因为所有打开的文件描述符被关闭。 我有一个棘手的时间正在调试的问题,我想知道如何捕捉和记录这些错误是正确的方式。

什么是设置日志记录以正确的方式,使得它继续daemonizing后,开始工作? 难道我只是叫logging.basicConfig()第二次daemonizing后? 什么是捕捉到的正确方法stdoutstderr ? 我对为什么所有的文件被关闭的细节模糊。 理想情况下,我主要的代码可能只是调用daemon_start(pid_file)和记录会继续工作。

Answer 1:

我用的是python-daemon库我的系统守护进程的行为。

接口描述这里:

  • http://www.python.org/dev/peps/pep-3143/

实现此:

  • http://pypi.python.org/pypi/python-daemon/

它允许指定files_preserve的说法,表示任何文件描述符daemonizing时应该被关闭。

如果需要通过相同的日志Handler之前和daemonizing后,您可以实例:

  1. 首先使用设置你的日志处理程序basicConfigdictConfig或什么的。
  2. 日志的东西
  3. 确定哪些文件描述符的Handler小号依赖。 不幸的是,这是依赖于Handler的子类。 如果第一安装Handler是一个StreamHandler ,它的值logging.root.handlers[0].stream.fileno() ; 如果你的第二个安装的HandlerSyslogHandler ,你想要的值logging.root.handlers[1].socket.fileno() ; 等等,这是凌乱:-(
  4. 通过创建一个守护进程的过程DaemonContextfiles_preserve等于你在步骤3中确定的文件描述符的列表。
  5. 继续记录; 你的日志文件不应该被双叉期间关闭。

另一种可能是,作为@Exelian建议,实际使用不同的Handler之前和之后daemonziation实例。 daemonizing后,立即销毁现存的处理器(由del向ING他们logger.root.handlers ?),并创建相同的新的; 你不能只是重新调用basicConfig因为这个问题的是@戴夫- mankoff指出。



Answer 2:

您可以简化这个代码,如果你设置你的日志处理程序从根记录对象单独的对象,然后作为一个独立的步骤中添加的处理程序对象,而不是做这一切在同一时间。 以下应为你工作。

import daemon
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler("./foo.log")
logger.addHandler(fh)

context = daemon.DaemonContext(
   files_preserve = [
      fh.stream,
   ],
)

logger.debug( "Before daemonizing." )
context.open()
logger.debug( "After daemonizing." )


Answer 3:

我们刚刚也有类似的问题,因为我无法控制的一些东西,守护的东西是从东西创造了记录器分开。 然而,记录仪具有.handlers和.parent属性,使它们能够与类似:

    self.files_preserve = self.getLogFileHandles(self.data.logger)

def getLogFileHandles(self,logger):
    """ Get a list of filehandle numbers from logger
        to be handed to DaemonContext.files_preserve
    """
    handles = []
    for handler in logger.handlers:
        handles.append(handler.stream.fileno())
    if logger.parent:
        handles += self.getLogFileHandles(logger.parent)
    return handles


文章来源: Maintaining Logging and/or stdout/stderr in Python Daemon