Search code examples
pythonlinuxprocessuptime

How to retrieve the process start time (or uptime) in python


How to retrieve the process start time (or uptime) in python in Linux?

I only know, I can call "ps -p my_process_id -f" and then parse the output. But it is not cool.


Solution

  • If you are doing it from within the python program you're trying to measure, you could do something like this:

    import time
    # at the beginning of the script
    startTime = time.time()
    # ...
    def getUptime():
        """
        Returns the number of seconds since the program started.
        """
        # do return startTime if you just want the process start time
        return time.time() - startTime
    

    Otherwise, you have no choice but to parse ps or go into /proc/pid. A nice bashy way of getting the elapsed time is:

    ps -eo pid,etime | grep $YOUR_PID | awk '{print $2}'
    

    This will only print the elapsed time in the following format, so it should be quite easy to parse:

    days-HH:MM:SS
    

    (if it's been running for less than a day, it's just HH:MM:SS)

    The start time is available like this:

    ps -eo pid,stime | grep $YOUR_PID | awk '{print $2}'
    

    Unfortunately, if your process didn't start today, this will only give you the date that it started, rather than the time.

    The best way of doing this is to get the elapsed time and the current time and just do a bit of math. The following is a python script that takes a PID as an argument and does the above for you, printing out the start date and time of the process:

    import sys
    import datetime
    import time
    import subprocess
    
    # call like this: python startTime.py $PID
    
    pid = sys.argv[1]
    proc = subprocess.Popen(['ps','-eo','pid,etime'], stdout=subprocess.PIPE)
    # get data from stdout
    proc.wait()
    results = proc.stdout.readlines()
    # parse data (should only be one)
    for result in results:
        try:
            result.strip()
            if result.split()[0] == pid:
                pidInfo = result.split()[1]
                # stop after the first one we find
                break
        except IndexError:
            pass # ignore it
    else:
        # didn't find one
        print "Process PID", pid, "doesn't seem to exist!"
        sys.exit(0)
    pidInfo = [result.split()[1] for result in results
               if result.split()[0] == pid][0]
    pidInfo = pidInfo.partition("-")
    if pidInfo[1] == '-':
        # there is a day
        days = int(pidInfo[0])
        rest = pidInfo[2].split(":")
        hours = int(rest[0])
        minutes = int(rest[1])
        seconds = int(rest[2])
    else:
        days = 0
        rest = pidInfo[0].split(":")
        if len(rest) == 3:
            hours = int(rest[0])
            minutes = int(rest[1])
            seconds = int(rest[2])
        elif len(rest) == 2:
            hours = 0
            minutes = int(rest[0])
            seconds = int(rest[1])
        else:
            hours = 0
            minutes = 0
            seconds = int(rest[0])
    
    # get the start time
    secondsSinceStart = days*24*3600 + hours*3600 + minutes*60 + seconds
    # unix time (in seconds) of start
    startTime = time.time() - secondsSinceStart
    # final result
    print "Process started on",
    print datetime.datetime.fromtimestamp(startTime).strftime("%a %b %d at %I:%M:%S %p")