it-swarm.com.de

Abrufen der Startzeit des Prozesses (oder der Betriebszeit) in Python

Wie kann ich die Startzeit des Prozesses (oder die Betriebszeit) in Python unter Linux abrufen?

Ich weiß nur, ich kann "ps -p my_process_id -f" aufrufen und dann die Ausgabe parsen. Aber es ist nicht cool. 

30
stanleyxu2005

Wenn Sie dies innerhalb des Python-Programms tun, das Sie messen möchten, können Sie Folgendes tun:

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

Ansonsten haben Sie keine andere Wahl als ps zu parsen oder in /proc/pid zu gehen. Eine schöne bashy-Methode zum Abrufen der abgelaufenen Zeit ist:

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

Dadurch wird nur die verstrichene Zeit in folgendem Format gedruckt, sodass das Analysieren ziemlich einfach sein sollte:

days-HH:MM:SS

(Wenn es weniger als einen Tag läuft, ist es nur HH:MM:SS)

Die Startzeit ist wie folgt verfügbar:

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

Wenn Ihr Prozess today nicht gestartet wurde, wird Ihnen leider nur das Datum angezeigt, an dem er gestartet wurde, und nicht die Uhrzeit.

Der beste Weg, dies zu tun, ist, die verstrichene Zeit und die aktuelle Zeit abzurufen und nur ein wenig zu rechnen. Das folgende ist ein Python-Skript, das eine PID als Argument verwendet und das oben genannte für Sie ausführt, indem Sie das Startdatum und die Startzeit des Prozesses ausgeben:

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")
14
Daniel G

Mit 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'
>>>

... und es ist plattformübergreifend, nicht nur Linux.

NB: Ich bin einer der Autoren dieses Projekts.

48

man proc sagt, dass der 22. Eintrag in /proc/my_process_id/stat:

starttime %lu

Die Zeit in wenigen Minuten, in der der Prozess nach dem Systemstart gestartet wurde.

Ihr Problem ist nun, wie Sie die Länge eines Jiffy bestimmen und wie hoch ist, wann das System hochfährt.

Die Antwort für Letzteres stammt noch von man proc: es ist in /proc/stat in einer eigenen Zeile wie folgt:

btime 1270710844

Das ist eine Messung in Sekunden seit Epoche.


Die Antwort auf die erste bin ich nicht sicher. man 7 time sagt:

Die Software Clock, HZ und Jiffies

Die Genauigkeit vieler Systemaufrufe und Zeitstempel ist durch die Auflösung der Software-Uhr begrenzt, einer Uhr, die vom Kernel verwaltet wird und die Zeit in Sekundenschnelle misst. Die Größe eines Jiffys wird durch den Wert der Kernkonstante HZ bestimmt. Der Wert von HZ variiert je nach Kernelversion und Hardwareplattform. Bei x86 ist die Situation wie folgt: Bei den Kerneln bis einschließlich 2.4.x betrug HZ 100, was einen Jiffy-Wert von 0,01 Sekunden ergibt; Beginnend mit 2.6.0 wurde HZ auf 1000 angehoben, was einen Jiffy von 0,001 Sekunden ergibt. Seit dem Kernel 2.6.13 ist der HZ-Wert ein Kernel-Konfigurationsparameter und kann 100, 250 (Standardeinstellung) oder 1000 sein, was einen Jiffies-Wert von 0,01, 0,004 bzw. 0,001 Sekunden ergibt.

Wir müssen HZ finden, aber ich habe keine Ahnung, wie ich das mit Python umgehen würde, es sei denn, der Wert ist 250 (wie Wikipedia behauptet, ist der Standard).

ps erhält es so:

  /* 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

Das hört sich nach einem Job an, der von einem sehr kleinen C-Modul für Python gut gemacht wurde :)

14
badp

Hier ist der Code, der auf der Antwort von badp basiert:

import os
from time import time

HZ = os.sysconf(os.sysconf_names['SC_CLK_TCK'])

def proc_age_secs():
    system_stats = open('/proc/stat').readlines()
    process_stats = open('/proc/self/stat').read().split()
    for line in system_stats:
        if line.startswith('btime'):
            boot_timestamp = int(line.split()[1])
    age_from_boot_jiffies = int(process_stats[21])
    age_from_boot_timestamp = age_from_boot_jiffies / HZ
    age_timestamp = boot_timestamp + age_from_boot_timestamp
    return time() - age_timestamp

Ich bin mir nicht sicher, ob es richtig ist. Ich habe ein Testprogramm geschrieben, das sleep (5) aufruft und dann ausführt. Die Ausgabe ist falsch und variiert von Lauf zu Lauf über einige Sekunden. Dies ist in einer VMware-Workstation-VM:

if __== '__main__':
    from time import sleep
    sleep(5)
    print proc_age_secs()

Die Ausgabe ist:

$ time python test.py
6.19169998169

real    0m5.063s
user    0m0.020s
sys     0m0.036s
4
Dan Benamy
def proc_starttime(pid=os.getpid()):
    # https://Gist.github.com/westhood/1073585
    p = re.compile(r"^btime (\d+)$", re.MULTILINE)
    with open("/proc/stat") as f:
        m = p.search(f.read())
    btime = int(m.groups()[0])

    clk_tck = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
    with open("/proc/%d/stat" % pid) as f:
        stime = int(f.read().split()[21]) / clk_tck

    return datetime.fromtimestamp(btime + stime)
2
Wilfred Hughes

sie können /proc/uptime parsen

>>> uptime, idletime = [float(f) for f in open("/proc/uptime").read().split()]
>>> print uptime
29708.1
>>> print idletime
26484.45

für Windows-Maschinen können Sie wahrscheinlich wmi verwenden. 

import wmi
c = wmi.WMI()
secs_up = int([uptime.SystemUpTime for uptime in c.Win32_PerfFormattedData_PerfOS_System()][0])
hours_up = secs_up / 3600
print hours_up
0
ghostdog74