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

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


By using psutil https://github.com/giampaolo/psutil:

>>> import psutil, os, time>>> p = psutil.Process(os.getpid())>>> p.create_time()1293678383.0799999>>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p.create_time()))'2010-12-30 04:06:23'>>>

...plus it's cross platform, not only Linux.

NB: I am one of the authors of this project.


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 scriptstartTime = 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 sysimport datetimeimport timeimport subprocess# call like this: python startTime.py $PIDpid = sys.argv[1]proc = subprocess.Popen(['ps','-eo','pid,etime'], stdout=subprocess.PIPE)# get data from stdoutproc.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 itelse:    # 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 timesecondsSinceStart = days*24*3600 + hours*3600 + minutes*60 + seconds# unix time (in seconds) of startstartTime = time.time() - secondsSinceStart# final resultprint "Process started on",print datetime.datetime.fromtimestamp(startTime).strftime("%a %b %d at %I:%M:%S %p")


man proc says that the 22nd item in /proc/my_process_id/stat is:

starttime %lu

The time in jiffies the process started after system boot.

Your problem now is, how to determine the length of a jiffy and how to determine when the system booted.

The answer for the latter comes still from man proc: it's in /proc/stat, on a line of its own like this:

btime 1270710844

That's a measurement in seconds since Epoch.


The answer for the former I'm not sure about. man 7 time says:

The Software Clock, HZ, and Jiffies

The accuracy of many system calls and timestamps is limited by the resolution of the software clock, a clock maintained by the kernel which measures time in jiffies. The size of a jiffy is determined by the value of the kernel constant HZ. The value of HZ varies across kernel versions and hardware platforms. On x86 the situation is as follows: on kernels up to and including 2.4.x, HZ was 100, giving a jiffy value of 0.01 seconds; starting with 2.6.0, HZ was raised to 1000, giving a jiffy of 0.001 seconds; since kernel 2.6.13, the HZ value is a kernel configuration parameter and can be 100, 250 (the default) or 1000, yielding a jiffies value of, respectively, 0.01, 0.004, or 0.001 seconds.

We need to find HZ, but I have no idea on how I'd go about that from Python except for hoping the value is 250 (as Wikipedia claims is the default).

ps obtains it thus:

  /* sysinfo.c init_libproc() */  if(linux_version_code > LINUX_VERSION(2, 4, 0)){     Hertz = find_elf_note(AT_CLKTCK);    //error handling  }  old_Hertz_hack(); //ugh

This sounds like a job well done by a very small C module for Python :)