Saturday, February 27, 2010

Dstat plugin for squid proxy

I've been using Dag Wieers' excellent system utility Dstat for a little while now and have recently starting exploring the possibility of extending it with my own plugins. Dstat is written in Python and so are its plugins, so that made the possibility all the more likely for me.

In case you don't know what Dstat is:
Dstat is a versatile replacement for vmstat, iostat, netstat, nfsstat and ifstat. Dstat overcomes some of their limitations and adds some extra features, more counters and flexibility. Dstat is handy for monitoring systems during performance tuning tests, benchmarks or troubleshooting.

Dstat allows you to view all of your system resources instantly, you can eg. compare disk usage in combination with interrupts from your IDE controller, or compare the network bandwidth numbers directly with the disk throughput (in the same interval).
Check the Dstat homepage for more details.

I was mostly interested in obtaining some useful metrics on a squid proxy and plugging them into Dstat. Using squidclient, you can get all sorts of interesting info using a command line interface and that's what I'm using to get these stats.

You'll need to ensure you have manager access enabled in your squid.conf like so:
http_access allow manager localhost  
http_access deny manager
The metrics I've chosen to extract are just a proof-of-concept really - I'll eventually tweak them to be somewhat more useful, and this O'Reilly article Eleven Metrics to Monitor for a Happy and Healthy Squid has always proven to be a good reference.

You can check out the dstat_squid.py plugin from my dstat-plugins GitHub repository, or copy it below.
# Dstat plugin for measuring various squid statistics.
# Author: Jason Friedland <thesuperjason@gmail.com>
#
# This plugin has been tested with:
# - Dstat 0.6.7
# - CentOS release 5.4 (Final)
# - Python 2.4.3
# - Squid 2.6 and 2.7
 
global squidclient_options
squidclient_options = os.getenv('DSTAT_SQUID_OPTS') # -p 8080
 
class dstat_squid(dstat):
    def __init__(self):
        self.name = 'squid status'
        self.format = ('s', 8, 100)
        self.vars = ('Number of file desc currently in use',
            'CPU Usage, 5 minute avg',
            'Total accounted',
            'Number of clients accessing cache',
            'Mean Object Size')
        self.nick = ('fdesc',
            'cpu5',
            'mem',
            'clients',
            'objsize')
        self.init(self.vars, 1)
        
    def check(self):
        if not os.access('/usr/sbin/squidclient', os.X_OK):
            raise Exception, 'Needs squidclient binary'
        return True
 
    def extract(self):
        try:
            for line in os.popen('/usr/sbin/squidclient %s mgr:info' 
                    % (squidclient_options), 'r').readlines():
                l = line.split(':')
                for item in self.vars:
                    if l[0].strip() == item:
                        self.val[item] = l[1].strip()
                        break
        except Exception, e:
            if op.debug > 1: print '%s: exception' (self.filename, e)
            for name in self.vars: self.val[name] = -1

0 comments:

Post a Comment