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