#!/usr/bin/perl
#
# Program: Apache Request Viewer By Virtual Server <viewreqsbyserver.pl>
#
# Author: Matty <matty91 at gmail dot com>
#
# Current Version: 0.1a
#
# Revision History:
#  Version 0.1a
#
# Last Updated: 11-25-2005
#
# Purpose: Prints the number of requests processed by each
#          virtual server (requires the Host: header attribute).
#
# Installation:
#   Copy the shell script to a suitable location
#
# CDDL HEADER START
#  The contents of this file are subject to the terms of the
#  Common Development and Distribution License, Version 1.0 only
#  (the "License").  You may not use this file except in compliance
#  with the License.
#
#  You can obtain a copy of the license at Docs/cddl1.txt
#  or http://www.opensolaris.org/os/licensing.
#  See the License for the specific language governing permissions
#  and limitations under the License.
# CDDL HEADER END

# Example:
# $ viewreqsbyserver.pl -d 60
# Sampling virtual server data for 60 seconds...
# Server                     GETs  POSTs  HEADs  TRACEs
# www.foo.com                101   0      0      0     
# www.bar.com                23    0      0      0     

### Standard includes
use Getopt::Std;
use POSIX;

# Process the command line arguments
%options=();
getopts("d:",\%options);

my $delay = $options{d} || 60;

### Global variables
my %server = ( GET   => 0,
               POST  => 0,
               HEAD  => 0,
               TRACE => 0);

$dtrace = <<END;
/usr/sbin/dtrace -Z -q -32 -n'
::apache_log_request:log-request
{
   /* The server (r->hostname) is offset 48-bytes in a 32-bit Apache */
   this->server  = copyinstr(*(uintptr_t *)copyin(arg0 + 48,sizeof(uintptr_t)));

   /* The method (r->method) is offset 72-bytes in a 32-bit Apache */
   this->method  = copyinstr(*(uintptr_t *)copyin(arg0 + 72,sizeof(uintptr_t)));

   \@methods[this->server, this->method] = count();
}

profile:::tick-${delay}sec
{
   printa("%s %s %\@d DONE",\@methods);
   printf("\\n");
   trunc(\@methods);
}'
END

open(DTRACE,"$dtrace |") || die "cannot open dtrace $@\n";

print "Sampling virtual server data for $delay seconds...\n";

while (<DTRACE>) {
    chomp;
    @chunked = split(/DONE/);

    while (@chunked > 0) {
        ($server, $method, $count) = split(' ', shift(@chunked), 3);
        $counts{$server}{$method} += $count;
    }

    printf("%-25s  %-4s  %-5s  %-5s  %-6s\n","Server","GETs","POSTs","HEADs","TRACEs");
    
    foreach $server (sort keys %counts) {
        printf("%-25s  %-4d  %-5d  %-5d  %-6d\n", $server,
                                         $counts{$server}{GET},
                                         $counts{$server}{POST},
                                         $counts{$server}{HEAD},
                                         $counts{$server}{TRACE});
    }

    print "\n";
    undef %counts;
    exit(0);
}

