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