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