Trying to track cpu usage of a process in python

by kkikta 1. April 2011 05:29

So I am working on my first attempt at python... so far I like it but not that much. The white space thing is actually kinda annoying but whatever. Anyway the idea here was to write a script that would take in a parameter (process name) and track its cpu usage. My main reason for this is mono has been chewing up cpu on a regular basis and I don't feel like logging in to kill the process all the time. Anyway this is just a first pass so I'll probably edit it as I make modifications.

 

'''
Created on Mar 30, 2011

@author: Keith
'''
import os
import psutil
import pickle
import signal
import smtplib

from_addr = 'root'
to_addrs = 'root'
watchFileFormat = 'watchProcess'

def getProcessIds(name):
    processes = psutil.get_pid_list()
    pids = []
    for pid in processes:
        p = psutil.Process(pid)
        if p.name == name:
            pids.append(pid)
    return pids


def checkThreshold(percentage, threshold):
    for utilization in percentage:
        if utilization < threshold:
            return False
    return True

def cleanWatch(pids):
    for file in os.listdir('.'):
        pid = file.split('.')
        if file.startswith(watchFileFormat) and pid[1].isdigit() and int(pid[1]) not in pids :
            print(file)
            os.remove(str.format(watchFileFormat + ".{0}", pid[1]))

def watchProcess(name, threshold = 50):
    util = []
    pids = getProcessIds(name)
    cleanWatch(pids)
    for pid in pids:
        try:
            p = psutil.Process(pid)
            file = str.format(watchFileFormat + ".{0}", str(pid))
            if os.path.exists(file):
                try:
                    util = pickle.load(open(file, "r"))
                except:
                    print(str.format("Unable to file for PID: {0}", str(pid)))
            util.append(p.get_cpu_percent(10.0))
            if (len(util) > 5):
                util.pop(0)
            pickle.dump(util, open(file, "wb"))
            if (len(util) == 5 and checkThreshold(util, threshold)):
                smtpObj = smtplib.SMTP('localhost')
                smtpObj.sendmail(from_addr, to_addrs, str.format("Process killed {0} with pid: {1}", name, pid))
                os.kill(pid, signal.SIGTERM)
        except:
            pass

if __name__ == '__main__':
    import sys
    if (len(sys.argv) > 2):
        watchProcess(sys.argv[1], sys.argv[2])
    else:
        watchProcess(sys.argv[1])
 

I think this script plus the crontab below should keep mono in check:

 

*   *    *   *   *   /usr/bin/python /root/watchProcess.py mono > /dev/null 2>&1

 

Updated: 4/3/2011 had issues with cleanup due to not casting the pid from the file name as an int also moved the isdigit so as to not catch files that end with non-numeric strings. In my case watchProcess.py ;P

Tags:

FreeBSD | Mono | Ubuntu

Comments (2) -

Jared
Jared United States
4/15/2011 4:38:30 AM #

I always wanted to try python. I once fixed a python script that LANDesk was using during the Linux agent installation, but that is all I have ever done.  I think the syntax looks odd.

I am not sure why one would choose python over any other language.

Reply

kkikta
kkikta United States
4/28/2011 4:22:30 PM #

I don't think people choose it for the syntax. I think its the idea that it is easier for most people than PERL and that its an interpreted language. Doing something like this in bash or another language I think would have taken much longer and probably been less readable. That being said I am still writing C# and don't plan on switching over to python any time soon.

Reply

Add comment



  Country flag
biuquote
  • Comment
  • Preview
Loading


Month List

Page List