xref: /netbsd-src/external/cddl/dtracetoolkit/dist/Apps/httpdstat.d (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
1 #!/usr/sbin/dtrace -s
2 /*
3  * httpdstat.d - realtime httpd statistics. Uses DTrace.
4  *
5  * $Id: httpdstat.d,v 1.1.1.1 2015/09/30 22:01:06 christos Exp $
6  *
7  * USAGE:	httpdstat.d [interval [count]]
8  *
9  *		interval	seconds
10  *		count		number of samples
11  *
12  * FIELDS:
13  *		TIME		Time, string
14  *		NUM		Number of connections
15  *		GET		Number of "GET"s
16  *		POST		Number of "POST"s
17  *		HEAD		Number of "HEAD"s
18  *		TRACE		Number of "TRACE"s
19  *
20  * All of the statistics are printed as a value per interval (not per second).
21  *
22  * NOTE: This version does not process subsequent operations on keepalives.
23  *
24  * IDEA: Ryan Matteson (who first wrote a solution to this).
25  *
26  * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
27  *
28  * CDDL HEADER START
29  *
30  *  The contents of this file are subject to the terms of the
31  *  Common Development and Distribution License, Version 1.0 only
32  *  (the "License").  You may not use this file except in compliance
33  *  with the License.
34  *
35  *  You can obtain a copy of the license at Docs/cddl1.txt
36  *  or http://www.opensolaris.org/os/licensing.
37  *  See the License for the specific language governing permissions
38  *  and limitations under the License.
39  *
40  * CDDL HEADER END
41  *
42  * 20-Nov-2005	Brendan Gregg	Created this.
43  */
44 
45 #pragma D option quiet
46 #pragma D option defaultargs
47 
48 inline int SCREEN = 21;
49 
50 /*
51  * Program Start
52  */
53 dtrace:::BEGIN
54 {
55 	num = 0; get = 0; head = 0; post = 0; trac = 0;
56 	lines = SCREEN + 1;
57 	secs = $1 ? $1 : 1;
58 	counts = $2 ? $2 : -1;
59 	first = 1;
60 }
61 
62 profile:::tick-1sec
63 {
64 	secs--;
65 }
66 
67 /*
68  * Print Header
69  */
70 dtrace:::BEGIN,
71 profile:::tick-1sec
72 /first || (secs == 0 && lines > SCREEN)/
73 {
74 	printf("%-20s %6s %6s %5s %5s %5s\n", "TIME",
75 	    "NUM", "GET", "POST", "HEAD", "TRACE");
76 	lines = 0;
77 	first = 0;
78 }
79 
80 /*
81  * Track Accept Events
82  */
83 syscall::accept:return
84 /execname == "httpd"/
85 {
86 	self->buf = 1;
87 }
88 
89 syscall::read:entry
90 /self->buf/
91 {
92 	self->buf = arg1;
93 }
94 
95 /*
96  * Tally Data
97  */
98 syscall::read:return
99 /self->buf && arg0/
100 {
101 	this->str = (char *)copyin(self->buf, arg0);
102 	this->str[4] = '\0';
103 	get  += stringof(this->str) == "GET " ? 1 : 0;
104 	post += stringof(this->str) == "POST" ? 1 : 0;
105 	head += stringof(this->str) == "HEAD" ? 1 : 0;
106 	trac += stringof(this->str) == "TRAC" ? 1 : 0;
107 	num++;
108 	self->buf = 0;
109 }
110 
111 /*
112  * Print Output
113  */
114 profile:::tick-1sec
115 /secs == 0/
116 {
117 	printf("%-20Y %6d %6d %5d %5d %5d\n", walltimestamp,
118 	    num, get, post, head, trac);
119 	num = 0; get = 0; head = 0; post = 0; trac = 0;
120 	secs = $1 ? $1 : 1;
121 	lines++;
122 	counts--;
123 }
124 
125 /*
126  * End
127  */
128 profile:::tick-1sec
129 /counts == 0/
130 {
131 	exit(0);
132 }
133