#!/usr/sbin/dtrace -s
/*
* httpdstat.d - realtime httpd statistics. Uses DTrace.
*
* $Id: httpdstat.d 2 2007-08-01 10:01:43Z brendan $
*
* USAGE: httpdstat.d [interval [count]]
*
* interval seconds
* count number of samples
*
* FIELDS:
* TIME Time, string
* NUM Number of connections
* GET Number of "GET"s
* POST Number of "POST"s
* HEAD Number of "HEAD"s
* TRACE Number of "TRACE"s
*
* All of the statistics are printed as a value per interval (not per second).
*
* NOTE: This version does not process subsequent operations on keepalives.
*
* IDEA: Ryan Matteson (who first wrote a solution to this).
*
* COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
*
* 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
*
* 20-Nov-2005 Brendan Gregg Created this.
*/
#pragma D option quiet
#pragma D option defaultargs
inline int SCREEN = 21;
/*
* Program Start
*/
dtrace:::BEGIN
{
num = 0; get = 0; head = 0; post = 0; trac = 0;
lines = SCREEN + 1;
secs = $1 ? $1 : 1;
counts = $2 ? $2 : -1;
first = 1;
}
profile:::tick-1sec
{
secs--;
}
/*
* Print Header
*/
dtrace:::BEGIN,
profile:::tick-1sec
/first || (secs == 0 && lines > SCREEN)/
{
printf("%-20s %6s %6s %5s %5s %5s\n", "TIME",
"NUM", "GET", "POST", "HEAD", "TRACE");
lines = 0;
first = 0;
}
/*
* Track Accept Events
*/
syscall::accept:return
/execname == "httpd"/
{
self->buf = 1;
}
syscall::read:entry
/self->buf/
{
self->buf = arg1;
}
/*
* Tally Data
*/
syscall::read:return
/self->buf && arg0/
{
this->str = (char *)copyin(self->buf, arg0);
this->str[4] = '\0';
get += stringof(this->str) == "GET " ? 1 : 0;
post += stringof(this->str) == "POST" ? 1 : 0;
head += stringof(this->str) == "HEAD" ? 1 : 0;
trac += stringof(this->str) == "TRAC" ? 1 : 0;
num++;
self->buf = 0;
}
/*
* Print Output
*/
profile:::tick-1sec
/secs == 0/
{
printf("%-20Y %6d %6d %5d %5d %5d\n", walltimestamp,
num, get, post, head, trac);
num = 0; get = 0; head = 0; post = 0; trac = 0;
secs = $1 ? $1 : 1;
lines++;
counts--;
}
/*
* End
*/
profile:::tick-1sec
/counts == 0/
{
exit(0);
}