How to get process info from python

Jean Brouwers mrjean1 at comcast.net
Sat Jun 12 22:45:05 CEST 2004


If your OS supports the /proc pseudo file system, you can get all
process info from that.

Below is an example for the memory usage and stack size of the current
process.  See the man page for proc for more details.

/Jean Brouwers
 ProphICy Semiconductor, Inc.

<pre>

import os

_proc_status = '/proc/%d/status' % os.getpid()  # Linux only?
_scale = {'kB': 1024.0, 'mB': 1024.0*1024.0,
           'KB': 1024.0, 'MB': 1024.0*1024.0}

def _VmB(VmKey):
    global _scale
    try: # get the /proc/<pid>/status pseudo file
        t = open(_proc_status)
        v = [v for v in t.readlines() if v.startswith(VmKey)]
        t.close()
         # convert Vm value to bytes
        if len(v) == 1:
           t = v[0].split()  # e.g. 'VmRSS:  9999  kB'
           if len(t) == 3:  ## and t[0] == VmKey:
               return float(t[1]) * _scale.get(t[2], 0.0)
    except:
        pass
    return 0.0
 
def memory(since=0.0):
    '''Return process memory usage in bytes.
    '''
    return _VmB('VmSize:') - since
 
def stacksize(since=0.0):
    '''Return process stack size in bytes.
    '''
    return _VmB('VmStk:') - since

</pre>



In article <mailman.735.1086739623.6949.python-list at python.org>,
Gardner Pomper <gardner at networknow.org> wrote:

> Nick,
> 
> AIX does not seem to support the -o format syntax. What I am using is
> "ps -lf" which seems to give me as much information as possible. I also,
> optionally, add "-u user" if I need to get all the information for a user,
> instead of just for the current tty process tree.
> 
> Currently, all I am using is the cmd line, but since there doesn't seem to
> be any other way to get the memory information for the process from python,
> I will need to start using the SZ column. Here is what I have so far
> (hopefully 129 lines of code is not too much to post in the group. If it is,
> I apologize)
> 
> #!/usr/bin/env python
> import string
> import commands
> import emea
> from optparse import OptionParser
> #
> class ProcessStatus :
>     def __init__(self,header,status):
>         self.uid = ''
>         self.pid = ''
>         self.ppid = ''
>         self.priority = ''
>         self.nice = ''
>         self.size = ''
>         self.start = ''
>         self.time = ''
>         self.cmd = ''
>         headings = header.split()
>         headings.remove('WCHAN')
>         #
>         # ----- find the char position of the WCHAN, STIME
>         # ----- TTY and CMD headings
>         #
>         wchan_pos = string.index(header,'WCHAN')
>         stime_pos = string.index(header,'STIME')
>         tty_pos = string.index(header,'TTY')
>         cmd_pos = string.index(header,'CMD',stime_pos)
>         #
>         # ----- cut the status line before WCHAN because
>         #       -----   that is often blank
>         #
>         n = string.rindex(status,' ',0,wchan_pos)
>         status1 = status[:n-1]
>         fields = status1.split()
> 
>         if string.find(status,'<defunct>') < 0 :
>             #
>             #   ----- the stime is all the chars between
>             #       -----   STIME and TTY
>             #
>             x = string.rindex(status,' ',0,stime_pos)
>             y = string.rindex(status,' ',stime_pos,tty_pos)
>             sTime = string.strip(status[x:y])
>             fields.append( sTime)
>             #
>             #   ----- the TTY and TIME fields are all the chars
>             #       -----   between TTY and CMD
>             #
>             max_pos = cmd_pos + 5
>             if max_pos > len(status)-1 :
>                 max_pos = len(status) - 1
>             m = string.rindex(status,':',tty_pos,max_pos)
>             n = string.index(status,' ',m)
>             status2 = status[y+1:n].strip()
>             fields.extend(status2.split())
>             #
>             #   ----- CMD is the rest of the line
>             #
>             status3 = status[n:].strip()
>             fields.append(status3)
> 
>         try :
>             for h,y in map(None,headings,fields) :
>                 if h == 'UID' :
>                     self.uid = y
>                 elif h == 'PID' :
>                     self.pid = y
>                 elif h == 'PPID' :
>                     self.ppid = y
>                 elif h == 'PRI' :
>                     self.priority = y
>                 elif h == 'NI':
>                     self.nice = y
>                 elif h == 'SZ' :
>                     self.size = y
>                 elif h == 'STIME' :
>                     self.start = y
>                 elif h == 'TIME' :
>                     self.time = y
>                 elif h == 'CMD' :
>                     if string.find(status,'<defunct>') >= 0 :
>                         self.cmd = '<defunct>'
>                     else:
>                         self.cmd = y
> 
>         except Exception, error :
>             logger = emea.get_logger()
>             logger.exception(error)
>             raise Exception(error)
> 
>     def __str__(self) :
>         return "UID %s PID %s PPID %s PRI %s NI %s SZ %s STIME %s TIME %s
> CMD %s" \
>               %(self.uid,self.pid,self.ppid,self.priority,self.nice,
>                 self.size,self.start,self.time,self.cmd)
> 
> def ps(user=None) :
>     options = ''
>     if user == 'all' :
>         options += ' -e'
>     elif user != None :
>         options += ' -u ' + user
>     cmd = 'ps -lf ' + options
>     ps_result = commands.getoutput(cmd)
>     lines = ps_result.splitlines()
>     psList = []
>     for l in lines[1:] :
>         psList.append(ProcessStatus(lines[0],l))
>     return psList
> #
> #
> #   -----
> #
> if __name__ == "__main__" :
>     parser = OptionParser()
>     parser.add_option("", "--user",action="store",dest="user",
>                       help="user to do ps for")
>     parser.add_option("","--log",action="store",dest="log",
>                       default="emea_auto.log",help="name of log file")
>     parser.add_option("","--verbose",action="store_true",dest="verbose",
>                       help="verbose mode (for debugging)")
>     (options,args) = parser.parse_args()
>     #
>     # ----- define logging
>     #
>     emea.set_logger('process_status',options.log,options.verbose)
>     psList = ps(options.user)
>     for p in psList:
>         print p
> 
> 
> 
> > -----Original Message-----
> > From: python-list-bounces+gardner=networknow.org at python.org
> > [mailto:python-list-bounces+gardner=networknow.org at python.org]On Behalf
> > Of Nick Vargish
> > Sent: Tuesday, June 08, 2004 10:52 AM
> > To: python-list at python.org
> > Subject: Re: How to get process info from python
> >
> >
> > "Gardner Pomper" <gardner at networknow.org> writes:
> >
> > > On a related issue, I was very surprise to see that
> > os.loadavg() had been
> > > added in version 2.3. This seems just as OS specific as the ps
> > functionality
> > > I want, so that raised my hopes.
> >
> > Gardner,
> >
> > I've had to work with process data in the past, and you're right, a
> > module to handle accessing ps data would be quite useful. Just for
> > fun, I've started writing something to help. All the systems that I
> > use "ps" on support a "-o format" for extracting specific information,
> > is this option supported on AIX?[*]
> >
> > What sort of information do you need from ps? I'll try to work it into
> > the module's functionality.
> >
> > I can't promise when it will be ready, but you seem to be rolling your
> > own solution anyway.
> >
> > Nick
> >
> > [*] Linux, OS X, and Tru64 (nee DEC Unix nee OSF/1). I don't have
> >     access to an AIX system right now.
> >
> > --
> > #  sigmask  ||  0.2  ||  20030107  ||  public domain  ||  feed
> > this to a python
> > print reduce(lambda x,y:x+chr(ord(y)-1),'
> > Ojdl!Wbshjti!=obwAcboefstobudi/psh?')
> > --
> > http://mail.python.org/mailman/listinfo/python-list
> 
>



More information about the Python-list mailing list