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

Installing Lighttpd with Mono support

by kkikta 27. March 2011 18:55

Below are the steps I used to get mono and lighttpd installed on my Ubuntu 10.104 LTS node from linode.com.

First I installed lighttpd using aptitude:

user@li35-84:~$ sudo aptitude install lighttpd

Next I needed support for .Net 2.0

user@li35-84:~$ sudo aptitude install mono-fastcgi-server

Then I created the file /etc/lighttpd/conf-available/15-mono.conf and added the following text using VI

#Mono Stuff
# Add index.aspx and default.aspx to the list of files to check when a
# directory is requested.
index-file.names += (
        "index.aspx",
        "default.aspx"
)


### The directory that contains your Mono installation.
# The "bin" subdir will be added to the PATH and the "lib" subdir will be
# added to the LD_LIBRARY_PATH.
# For a typical system-wide installation on Linux, use:
var.mono_dir = "/usr/"
# For an installation in a user account (lighttpd need read/exec access):
#var.mono_dir = "/home/username/mono-1.2.6/"

### A directory that is writable by the lighttpd process.
# This is where the log file, communication socket, and Mono's .wapi folder
# will be created.
# For a typical system-wide installation on Linux, use:
var.mono_shared_dir = "/tmp/"
# For an installation in a user account (dir must exist and be writable):
#var.mono_shared_dir = "/home/username/lighttpd_scratch/"

### The path to the server to launch to handle FASTCGI requests.
# For ASP.NET 1.1 support use:
#var.mono_fastcgi_server = mono_dir + "bin/" + "fastcgi-mono-server"
# For ASP.NET 2.0 support use:
var.mono_fastcgi_server = mono_dir + "bin/" + "fastcgi-mono-server2"

### The root of your applications
# For apps installed under the lighttpd document root, use:
var.mono_fcgi_root = server.document-root
# For apps installed in a user account, use something like:
#var.mono_fcgi_root = "/home/username/htdocs/"

### Application map
# A comma separated list of virtual directory and real directory
# for all the applications we want to manage with this server. The
# virtual and real dirs. are separated by  a  colon.
var.mono_fcgi_applications = "/:."

Once the mono settings were created I created a file (25-domain.com.conf) for the virtually hosted domain enabeling mono.

        server.modules   += ( "mod_fastcgi" )

        $HTTP["host"] =~ "domain\.com$" {
        server.document-root = "/var/sites/domain.com"
        server.errorlog = "/var/log/lighttpd/domain.com/error.log"
        accesslog.filename = "/var/log/lighttpd/domain.com/access.log"
        fastcgi.server  = (
                ".aspx" => ((
                        "socket" => mono_shared_dir + "fastcgi-mono-server-domain",
                        "bin-path" => mono_fastcgi_server,
                        "bin-environment" => (
                                "PATH" => "/bin:/usr/bin:" + mono_dir + "bin",
                                "LD_LIBRARY_PATH" => mono_dir + "lib:",
                                "MONO_SHARED_DIR" => mono_shared_dir,
                                "MONO_FCGI_LOGLEVELS" => "Standard",
                                "MONO_FCGI_LOGFILE" => mono_shared_dir + "fastcgi.log",
                                "MONO_FCGI_ROOT" => "/var/sites/domain.com",
                                "MONO_FCGI_APPLICATIONS" => "/:/var/sites/domain.com"
                        ),
                        "max-procs" => 1,
                        "check-local" => "disable"
                ))
        )
        fastcgi.map-extensions = (
                ".asmx"   => ".aspx",
                ".ashx"   => ".aspx",
                ".asax"   => ".aspx",
                ".ascx"   => ".aspx",
                ".soap"   => ".aspx",
                ".rem"    => ".aspx",
                ".axd"    => ".aspx",
                ".cs"     => ".aspx",
                ".config" => ".aspx",
                ".dll"    => ".aspx"
        )
}

I had read quite a bit of documentation telling me that I should not map a particular extension and or use the fastcgi.max-extensions and just process everything but I found that doing so prevented web services (axd) files from processing. Next it was time to enable the config changes in lighttpd by linking the files into the conf-enabled folder.

user@li35-84:~$ sudo ln /etc/lighttpd/conf-available/15-mono.conf /etc/lighttpd/conf-enabled/
user@li35-84:~$ sudo ln /etc/lighttpd/conf-available/25-domain.com.conf /etc/lighttpd/conf-enabled/

At this point it was necessary to create the directories where logs would be stored.

user@li35-84:~$ sudo mkdir /var/log/lighttpd/domain.com
user@li35-84:~$ sudo chown -R www-data:www-data /var/log/lighttpd/domain.com

Then create the directory were the website files will be stored

user@li35-84:~$ sudo mkdir /var/sites/
user@li35-84:~$ sudo mkdir /var/sites/domain.com

Last restart lighttpd

user@li35-84:~$ sudo /etc/init.d/lighttpd restart

There ya go now you have a server capable of running Mono compatable applications like this blog.

Tags:

.NET | Blog | BlogEngine.NET | Mono | Ubuntu

Blog migration from DasBlog to BlogEngine.net

by kkikta 25. March 2011 23:32

It has been a bit of a chore but I believe I have successfully migrated this blog. As usual I have over complicated the issue by relaunching the blog on a linode virtual server. That's right from Windows, IIS and Microsoft.Net to Ubuntu, lighttpd and Mono. The migration has not be as smooth as I hoped, it has requiring a few edits to the source. I will try to follow this post with what it took a bit later but for now it works!

Tags:

Lighttpd | Ubuntu | Mono

Month List

Page List