1235368Sgnn#!/usr/sbin/dtrace -s
2235368Sgnn/*
3235368Sgnn * httpdstat.d - realtime httpd statistics. Uses DTrace.
4235368Sgnn *
5235368Sgnn * $Id: httpdstat.d 2 2007-08-01 10:01:43Z brendan $
6235368Sgnn *
7235368Sgnn * USAGE:	httpdstat.d [interval [count]]
8235368Sgnn *
9235368Sgnn *		interval	seconds
10235368Sgnn *		count		number of samples
11235368Sgnn *
12235368Sgnn * FIELDS:
13235368Sgnn *		TIME		Time, string
14235368Sgnn *		NUM		Number of connections
15235368Sgnn *		GET		Number of "GET"s
16235368Sgnn *		POST		Number of "POST"s
17235368Sgnn *		HEAD		Number of "HEAD"s
18235368Sgnn *		TRACE		Number of "TRACE"s
19235368Sgnn *
20235368Sgnn * All of the statistics are printed as a value per interval (not per second).
21235368Sgnn *
22235368Sgnn * NOTE: This version does not process subsequent operations on keepalives.
23235368Sgnn *
24235368Sgnn * IDEA: Ryan Matteson (who first wrote a solution to this).
25235368Sgnn *
26235368Sgnn * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
27235368Sgnn *
28235368Sgnn * CDDL HEADER START
29235368Sgnn *
30235368Sgnn *  The contents of this file are subject to the terms of the
31235368Sgnn *  Common Development and Distribution License, Version 1.0 only
32235368Sgnn *  (the "License").  You may not use this file except in compliance
33235368Sgnn *  with the License.
34235368Sgnn *
35235368Sgnn *  You can obtain a copy of the license at Docs/cddl1.txt
36235368Sgnn *  or http://www.opensolaris.org/os/licensing.
37235368Sgnn *  See the License for the specific language governing permissions
38235368Sgnn *  and limitations under the License.
39235368Sgnn *
40235368Sgnn * CDDL HEADER END
41235368Sgnn *
42235368Sgnn * 20-Nov-2005	Brendan Gregg	Created this.
43235368Sgnn */
44235368Sgnn
45235368Sgnn#pragma D option quiet
46235368Sgnn#pragma D option defaultargs
47235368Sgnn
48235368Sgnninline int SCREEN = 21;
49235368Sgnn
50235368Sgnn/*
51235368Sgnn * Program Start
52235368Sgnn */
53235368Sgnndtrace:::BEGIN
54235368Sgnn{
55235368Sgnn	num = 0; get = 0; head = 0; post = 0; trac = 0;
56235368Sgnn	lines = SCREEN + 1;
57235368Sgnn	secs = $1 ? $1 : 1;
58235368Sgnn	counts = $2 ? $2 : -1;
59235368Sgnn	first = 1;
60235368Sgnn}
61235368Sgnn
62235368Sgnnprofile:::tick-1sec
63235368Sgnn{
64235368Sgnn	secs--;
65235368Sgnn}
66235368Sgnn
67235368Sgnn/*
68235368Sgnn * Print Header
69235368Sgnn */
70235368Sgnndtrace:::BEGIN,
71235368Sgnnprofile:::tick-1sec
72235368Sgnn/first || (secs == 0 && lines > SCREEN)/
73235368Sgnn{
74235368Sgnn	printf("%-20s %6s %6s %5s %5s %5s\n", "TIME",
75235368Sgnn	    "NUM", "GET", "POST", "HEAD", "TRACE");
76235368Sgnn	lines = 0;
77235368Sgnn	first = 0;
78235368Sgnn}
79235368Sgnn
80235368Sgnn/*
81235368Sgnn * Track Accept Events
82235368Sgnn */
83235368Sgnnsyscall::accept:return
84235368Sgnn/execname == "httpd"/
85235368Sgnn{
86235368Sgnn	self->buf = 1;
87235368Sgnn}
88235368Sgnn
89235368Sgnnsyscall::read:entry
90235368Sgnn/self->buf/
91235368Sgnn{
92235368Sgnn	self->buf = arg1;
93235368Sgnn}
94235368Sgnn
95235368Sgnn/*
96235368Sgnn * Tally Data
97235368Sgnn */
98235368Sgnnsyscall::read:return
99235368Sgnn/self->buf && arg0/
100235368Sgnn{
101235368Sgnn	this->str = (char *)copyin(self->buf, arg0);
102235368Sgnn	this->str[4] = '\0';
103235368Sgnn	get  += stringof(this->str) == "GET " ? 1 : 0;
104235368Sgnn	post += stringof(this->str) == "POST" ? 1 : 0;
105235368Sgnn	head += stringof(this->str) == "HEAD" ? 1 : 0;
106235368Sgnn	trac += stringof(this->str) == "TRAC" ? 1 : 0;
107235368Sgnn	num++;
108235368Sgnn	self->buf = 0;
109235368Sgnn}
110235368Sgnn
111235368Sgnn/*
112235368Sgnn * Print Output
113235368Sgnn */
114235368Sgnnprofile:::tick-1sec
115235368Sgnn/secs == 0/
116235368Sgnn{
117235368Sgnn	printf("%-20Y %6d %6d %5d %5d %5d\n", walltimestamp,
118235368Sgnn	    num, get, post, head, trac);
119235368Sgnn	num = 0; get = 0; head = 0; post = 0; trac = 0;
120235368Sgnn	secs = $1 ? $1 : 1;
121235368Sgnn	lines++;
122235368Sgnn	counts--;
123235368Sgnn}
124235368Sgnn
125235368Sgnn/*
126235368Sgnn * End
127235368Sgnn */
128235368Sgnnprofile:::tick-1sec
129235368Sgnn/counts == 0/
130235368Sgnn{
131235368Sgnn	exit(0);
132235368Sgnn}
133