Python System information

NMBooker NMBooker at googlemail.com
Sun Jan 27 02:48:47 CET 2008


On Jan 26, 2:58 pm, Clement <jeba.r... at gmail.com> wrote:
> Hi friends,
> How can i get system information like CPU load and RAM usage in linux.
> Is there any packages for python

Good question.

I've just had a scout around on Google and found no "ready-made"
libraries, so it looks like you'll have to poke around in the /proc
directory.

Apologies in advance if you already know about /proc and how to parse
files.  I haven't tested the code in this answer on anything but an
AMD Athlon XP, but I would hope it would work on other architectures.
I'm not quite so sure about other UNIXes though.

Reading the manpage for proc is useful for this:-
 $ man proc

You're probably interested in /proc/stat (for calculating CPU usage), /
proc/loadavg (for getting load average and process/thread counts),
and /proc/meminfo (for memory usage).

I've posted all the code from below at http://www.dcs.warwick.ac.uk/~csueda/proc.py
Once I've graduated in the Summer that will disappear though.

meminfo
=======

In meminfo, you're probably most interested in the fields MemTotal and
MemFree (and possibly Buffers and Cached if you want to see how much
of the used memory is in fact cache rather than user programs).  You
might also want to look at SwapTotal and SwapFree.

The following just dumps all the lines from /etc/meminfo into a
dictionary (str:int):

# I thought a regex would be the easiest way to do this.
import re
re_parser = re.compile(r'^(?P<key>\S*):\s*(?P<value>\d*)\s*kB')
def meminfo():
    """-> dict of data from meminfo (str:int).
    Values are in kilobytes.
    """
    result = dict()
    for line in open('/proc/meminfo'):
        match = re_parser.match(line)
        if not match:
            continue  # skip lines that don't parse
        key, value = match.groups(['key', 'value'])
        result[key] = int(value)
    return result


stat
====
/proc/stat contains the CPU info you need.

In stat, you can look at the first four fields of each "cpu" record,
for example on my machine:
$ cat /proc/stat
cpu  63888 1648769 11015 494 998 799 59339 0
cpu0 63888 1648769 11015 494 998 799 59339 0
intr 9483429 148 2 0 0 4 0 0 0 3 0 0 0 4 0 0 321118 105939 0 3 35085
32465 8988658 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 4526886
btime 1201376745
processes 7197
procs_running 2
procs_blocked 0

The cpu record refers to all processor cores, while cpuN refers to
each CPU or CPU core individually.

Unless things are more complicated than they appear, to get the busy
time fraction:

def cpuusage():
    """-> dict of cpuid : (usertime, nicetime, systemtime, idletime)
    cpuid "cpu" means the total for all CPUs.
    cpuid "cpuN" means the value for CPU N.
    """
    wanted_records = [line for line in open('/proc/stat') if
line.startswith('cpu')]
    result = {}
    for cpuline in wanted_records:
        fields = cpuline.split()[:5]
        data = map(int, fields[1:])
        result[fields[0]] = tuple(data)
    return result

The manpage points out that the contents of /proc/stat can vary by
architecture, though I would guess at least the "cpu" line would be
available on all.


loadavg
=======
You can get the load average and the other information in /proc/
loadavg with:

def loadavg():
   """-> 5-tuple containing the following numbers in order:
    - 1-minute load average (float)
    - 5-minute load average (float)
    - 15-minute load average (float)
    - Number of threads/processes currently executing (<= number of
CPUs) (int)
    - Number of threads/processes that exist on the system (int)
    - The PID of the most recently-created process on the system (int)
   """
   loadavgstr = open('/proc/loadavg', 'r').readline().strip()
   data = loadavgstr.split()
   avg1, avg5, avg15 = map(float, data[:3])
   threads_and_procs_running, threads_and_procs_total = map(int,
data[3].split('/'))
   most_recent_pid = int(data[4])
   return avg1, avg5, avg15, threads_and_procs_running,
threads_and_procs_total, most_recent_pid

Hope this solves the problem.

Nick Booker



More information about the Python-list mailing list