1#!/usr/sbin/dtrace -Zs
2/*
3 * sh_stat.d - Bourne shell operation stats using DTrace.
4 *             Written for the sh DTrace provider.
5 *
6 * $Id: sh_stat.d 52 2007-09-24 04:28:01Z brendan $
7 *
8 * This traces activity from all sh processes on the system that are running
9 * with sh provider support.
10 *
11 * USAGE: sh_stat.d [interval [count]]
12 *
13 * FIELDS:
14 *		EXEC/s		Bourne shells executed per second, including
15 *				those without sh provider support
16 *		FUNC/s		Functions called, per second
17 *		BLTIN/s		Builtins called, per second
18 *		SUB-SH/s	Sub-shells called, per second
19 *		CMD/s		External commands called, per second
20 *
21 * The numbers are counts for the interval specified. The default interval
22 * is 1 second.
23 *
24 * If you see a count in "EXECS" but not in the other columns, then sh
25 * scripts may be running without the DTrace sh provider. See Shell/Readme.
26 *
27 * Filename and function names are printed if available.
28 *
29 * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
30 *
31 * CDDL HEADER START
32 *
33 *  The contents of this file are subject to the terms of the
34 *  Common Development and Distribution License, Version 1.0 only
35 *  (the "License").  You may not use this file except in compliance
36 *  with the License.
37 *
38 *  You can obtain a copy of the license at Docs/cddl1.txt
39 *  or http://www.opensolaris.org/os/licensing.
40 *  See the License for the specific language governing permissions
41 *  and limitations under the License.
42 *
43 * CDDL HEADER END
44 *
45 * 09-Sep-2007	Brendan Gregg	Created this.
46 */
47
48#pragma D option quiet
49#pragma D option defaultargs
50
51inline int SCREEN = 21;
52
53dtrace:::BEGIN
54{
55	execs = funcs = builtins = subs = cmds = 0;
56	lines = SCREEN + 1;
57	interval = $1 ? $1 : 1;
58	counts = $2 ? $2 : -1;
59	secs = interval;
60	first = 1;
61}
62
63profile:::tick-1sec
64{
65	secs--;
66}
67
68/*
69 * Print Header
70 */
71dtrace:::BEGIN,
72profile:::tick-1sec
73/first || (secs == 0 && lines > SCREEN)/
74{
75	printf("%-20s %8s %8s %8s %8s %8s\n", "TIME", "EXEC/s", "FUNCS/s",
76	    "BLTINS/s", "SUB-SH/s", "CMD/s");
77	lines = 0;
78	first = 0;
79}
80
81/*
82 * Tally Data
83 */
84proc:::exec-success
85/execname == "sh"/
86{
87	execs++;
88}
89
90sh*:::function-entry
91{
92	funcs++;
93}
94
95sh*:::builtin-entry
96{
97	builtins++;
98}
99
100sh*:::subshell-entry
101/arg0 != 0/
102{
103	subs++;
104}
105
106sh*:::command-entry
107{
108	cmds++;
109}
110
111/*
112 * Print Output
113 */
114profile:::tick-1sec
115/secs == 0/
116{
117	printf("%-20Y %8d %8d %8d %8d %8d\n", walltimestamp, execs / interval,
118	    funcs / interval, builtins / interval, subs / interval,
119	    cmds / interval);
120	execs = funcs = builtins = subs = cmds = 0;
121	secs = interval;
122	lines++;
123	counts--;
124}
125
126/*
127 * End
128 */
129profile:::tick-1sec
130/counts == 0/
131{
132        exit(0);
133}
134