3

我有许多用 Python 2.6 编写的脚本,可以任意运行。我想要一个中央脚本来收集输出并将其显示在单个日志中。

理想情况下,它将满足以下要求:

  • 每个脚本都将其消息发送到同一个“接收器”进行显示。
  • 如果在第一个脚本尝试发送消息时接收器未运行,则启动它。
  • 接收器也可以手动启动和结束。(虽然如果结束,如果另一个脚本尝试发送消息,它将重新启动。)
  • 脚本可以按任何顺序运行,甚至可以同时运行。
  • 在Windows上运行。多平台更好,但至少它需要在 Windows 上工作。

我遇到了一些提示:

从这些碎片中,我想我可以拼凑出一些东西。只是想知道是否有明显“正确”的方法可以做到这一点,或者我是否可以从任何人的错误中吸取教训。

4

3 回答 3

5

我会考虑将logging.handlers.SocketHandler其用于消息传递部分,听起来您已经想到了一个日志记录类型的用例。

标准库日志记录工具非常灵活且配置驱动,因此您应该能够根据您的要求调整它们。

这不处理您问题的自动重新启动部分。对于 UNIX,您可能只使用 pid 文件并os.kill(pid, 0)检查它是否正在运行,但我不知道它们在 Windows 世界中的等价物是什么。

于 2010-05-18T00:39:50.367 回答
1

我使用以下关键代码构建了一个服务器以使用 Windows 命名管道:

    def run( self ):
        # This is the main server loop for the Win32 platform
        import win32pipe
        import win32file
        self.pipeHandle = win32pipe.CreateNamedPipe(
            '\\\\.\\pipe\\myapp_requests',
            win32pipe.PIPE_ACCESS_DUPLEX,
            win32pipe.PIPE_TYPE_BYTE |
            win32pipe.PIPE_READMODE_BYTE |
            win32pipe.PIPE_WAIT,
            1,
            4096,
            4096,
            10000,
            None)
        if self.pipeHandle == win32file.INVALID_HANDLE_VALUE:
            print 'Failed to create named pipe %s!' % self.pipeName
            print 'Exiting...'
            sys.exit(1)
        while True:
            # Open file connection
            win32pipe.ConnectNamedPipe( self.pipeHandle )

            # Run the main message loop until it exits, usually because
            # of a loss of communication on the pipe
            try:
                self.messageLoop()
            except ServerKillSignal:
                break

            # Return the pipes to their disconnected condition and try again
            try: win32pipe.DisconnectNamedPipe( self.pipeHandle )
            except: pass
        win32file.CloseHandle( self.pipeHandle )
        print "Exiting server"

该方法messageLoop()使用 , 从管道读取数据win32file.ReadFile(),直到抛出 win32file.error。然后它退出,允许 run() 重新启动它。

在我的实现中,用户不太可能具有管理员访问权限,因此无法将其作为系统服务启动。相反,我对客户端进行了编码,以检查 '\.\pipe\pyccf_requests' 处的管道是否存在。如果它不存在,则客户端启动一个新的服务器进程。

于 2010-05-18T00:10:21.347 回答
0

Dan Head 的答案正是您想要的。

项目 #2,“如果在第一个脚本尝试发送消息时接收器没有运行,它就会启动”,可能不会工作。必须运行某些东西才能接收消息。我建议编写一个在启动时启动的恶魔进程,并告诉 Windows 如果它死了就重新启动它。

于 2010-05-25T02:19:15.233 回答