views:

866

answers:

5

I need to detect when a program crashes or is not running using python and restart it. I need a method that doesn't necessarily rely on the python module being the parent process.

I'm considering implementing a while loop that essentially does

ps -ef | grep process name

and when the process isn't found it starts another. Perhaps this isn't the most efficient method. I'm new to python so possibly there is a python module that does this already.

A: 

I haven't tried it myself, but there is a Python System Information module that can be used to find processes and get information about them. AFAIR there is a ProcessTable class that can be used to inspect the running processes, but it doesn't seem to be very well documented...

sth
Thanks! I'll look into this.
Caedis
A: 

I'd go the command-line route (it's just easier imho) as long as you only check every second or two the resource usage should be infintesimal compared to the available processing on any system less than 10 years old.

SpliFF
I probably will, either by parsing the ps command or searcing the /proc directory.
Caedis
+2  A: 

Why implement it yourself? An existing utility like daemon or Debian's start-stop-daemon is more likely to get the other difficult stuff right about running long-living server processes.

Anyway, when you start the service, put its pid in /var/run/<name>.pid and then make your ps command just look for that process ID, and check that it is the right process. On Linux you can simply look at /proc/<pid>/exe to check that it points to the right executable.

Jouni K. Seppänen
Due to the unique nature of the program set being monitored they can not be made into daemons. Thus conventional monitoring methods are unavailable to me. Additionally I need certain features that I would feel more comfortable implementing myself in one nice neat module rather than relying on outside code.Thanks for the /proc/<pid/exe tip! I think I'll implement it in this way unless someone comes up with another method.
Caedis
+2  A: 

Please don't reinvent init. Your OS has capabilities to do this that require nearly no system resources and will definitely do it better and more reliably than anything you can reproduce.

Classic Linux has /etc/inittab

Ubuntu has /etc/event.d (upstart)

OS X has launchd

Solaris has smf

Dustin
Again, the unique nature of the processes I'm monitoring require them to be handled differently than a simple daemon. I can't simply have the processes restart, database locks, client data corruption. Data must be validate before restarting the server process. So I need to custom code this into python to prevent serious issues.
Caedis
You either want automated restarts or you don't. If you do, you want your OS to do it via init, etc... If you don't, then your entire question and title expresses the opposite of your intentions.
Dustin
A: 

The following code checks a given process in a given interval, and restarts it.

#Restarts a given process if it is finished.
#Compatible with Python 2.5, tested on Windows XP.
import threading
import time
import subprocess

class ProcessChecker(threading.Thread):
    def __init__(self, process_path, check_interval):
        threading.Thread.__init__(self)
        self.process_path = process_path
        self.check_interval = check_interval

    def run (self):
        while(1):
            time.sleep(self.check_interval)
            if self.is_ok():
                self.make_sure_process_is_running()

    def is_ok(self):
        ok = True
        #do the database locks, client data corruption check here,
        #and return true/false
        return ok

    def make_sure_process_is_running(self):
        #This call is blocking, it will wait for the
        #other sub process to be finished.
        retval = subprocess.call(self.process_path)

def main():
    process_path = "notepad.exe"
    check_interval = 1 #In seconds
    pm = ProcessChecker(process_path, check_interval)
    pm.start()
    print "Checker started..."

if __name__ == "__main__":
    main()
Caglar Toklu