#!/usr/bin/python

__version__ = '0.5'
__author__ = 'Peter Poeml <peter@poeml.de>'
__copyright__ = 'Novell Inc.'
__license__ = 'GPL'

import sys, os, time
import pyrrdtool as rrd
import urllib2
import commands

rrd_db = '/var/log/apache2/server-status.rrd'
rrd_mem_db = '/var/log/apache2/httpd2-memusage.rrd'
reqs_last_file = '/var/log/apache2/server-status.reqs_last'
graph_pidfile = '/var/run/graph_server_status_rrd.pid'
server_status_url = 'http://localhost/server-status?auto'

if len(sys.argv) > 1:
    rrd_db = sys.argv[1]

request = urllib2.Request(server_status_url)
opener = urllib2.build_opener()
request.add_header('User-Agent', '%s/%s' \
                   % (os.path.basename(__file__), __version__))

t = time.time()
s = opener.open(request).readlines()
latency = int((time.time() - t) * 1000)

rps = None
for line in s:
    if line.startswith('ReqPerSec'):
        rps = line.split(':')[1].strip()
    elif line.startswith('BusyWorkers'):
        busy = line.split(':')[1].strip()
    elif line.startswith('IdleWorkers'):
        idle = line.split(':')[1].strip()
    elif line.startswith('Total Accesses'):
        reqs = line.split(':')[1].strip()

try:
    reqs_last = open(reqs_last_file).read().rstrip()
except:
    reqs_last = 0
open(reqs_last_file, 'w').write('%s\n' % reqs)
reqs_delta = (int(reqs) - int(reqs_last)) / 60

if not rps:
    sys.exit('%s: Please set "ExtendedStatus On" so that mod_status provides all data' 
             % os.path.basename(__file__))

r = rrd.RoundRobinDatabase(rrd_db)

if not os.path.exists(rrd_db):
    r.create(rrd.DataSource("reqPerSecSlidingAvg", type=rrd.GaugeDST, heartbeat=120, min=0),
             rrd.DataSource("busyWorkers", type=rrd.GaugeDST, heartbeat=120, min=0),
             rrd.DataSource("idleWorkers", type=rrd.GaugeDST, heartbeat=120, min=0),
             rrd.DataSource("reqPerSec", type=rrd.GaugeDST, heartbeat=120, min=0),
             rrd.DataSource("latency", type=rrd.GaugeDST, heartbeat=120, min=0, max=1000),
             rrd.RoundRobinArchive(cf=rrd.AverageCF, xff=0.5, steps=1, rows=10080),
             rrd.RoundRobinArchive(cf=rrd.AverageCF, xff=0.5, steps=60, rows=8760))

rm = rrd.RoundRobinDatabase(rrd_mem_db)

if not os.path.exists(rrd_mem_db):
    rm.create(rrd.DataSource("memusage", type=rrd.GaugeDST, heartbeat=120, min=0, max=1000),
             rrd.RoundRobinArchive(cf=rrd.AverageCF, xff=0.5, steps=1, rows=10080),
             rrd.RoundRobinArchive(cf=rrd.AverageCF, xff=0.5, steps=60, rows=8760))

# while another rrdtool process is reading the db, it is locked
# we can do nothing than wait a bit
if os.path.exists(graph_pidfile):
    for i in range(10):
        time.sleep(3)
        if not os.path.exists(graph_pidfile):
            break
if os.path.exists(graph_pidfile):
    print '%s still exists after waiting 30 seconds... aborting' % graph_pidfile
    sys.exit(1)


r.update(rrd.Val(rps, busy, idle, reqs_delta, latency), 
         template=('reqPerSecSlidingAvg', 'busyWorkers', 'idleWorkers', 'reqPerSec', 'latency'))

r, out = commands.getstatusoutput('httpd2-memusage')
if r == 0:
    mem_total_mb = out.splitlines()[-1].split(':')[1].split()[0]
    mem_total_mb = int(mem_total_mb.split('.')[0])

    rm.update(rrd.Val(mem_total_mb), template=('memusage',))

