topsyscall revision 1.1 1 #!/usr/bin/ksh
2 #
3 # topsyscall - display top syscalls by syscall name.
4 # Written using DTrace (Solaris 10 3/05).
5 #
6 # This program continually prints a report of the top system calls,
7 # and refreshes the display every 1 second or as specified at the
8 # command line.
9 #
10 # $Id: topsyscall,v 1.1 2015/09/30 22:01:07 christos Exp $
11 #
12 # USAGE: topsyscall [-Cs] [interval [count]]
13 #
14 # -C # don't clear the screen
15 # -s # print per second values
16 #
17 # FIELDS:
18 # load avg load averages, see uptime(1)
19 # syscalls total syscalls in this interval
20 # syscalls/s syscalls per second
21 # SYSCALL system call name
22 # COUNT total syscalls in this interval
23 # COUNT/s syscalls per second
24 #
25 # INSPIRATION: top(1) by William LeFebvre
26 #
27 # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
28 #
29 # CDDL HEADER START
30 #
31 # The contents of this file are subject to the terms of the
32 # Common Development and Distribution License, Version 1.0 only
33 # (the "License"). You may not use this file except in compliance
34 # with the License.
35 #
36 # You can obtain a copy of the license at Docs/cddl1.txt
37 # or http://www.opensolaris.org/os/licensing.
38 # See the License for the specific language governing permissions
39 # and limitations under the License.
40 #
41 # CDDL HEADER END
42 #
43 # 13-Jun-2005 Brendan Gregg Created this.
44 # 20-Apr-2006 " " Last update.
45 #
46
47 ##############################
48 # --- Process Arguments ---
49 #
50
51 ### Default variables
52 count=-1; interval=1; opt_persec=0; opt_clear=1
53
54 ### Process options
55 while getopts Chs name
56 do
57 case $name in
58 C) opt_clear=0 ;;
59 s) opt_persec=1 ;;
60 h|?) cat <<-END >&2
61 USAGE: topsyscall [-s] [interval [count]]
62 -C # don't clear the screen
63 -s # print per second values
64 eg,
65 topsyscall # default, 1 second updates
66 topsyscall 5 # 5 second updates
67 END
68 exit 1
69 esac
70 done
71 shift $(( $OPTIND - 1 ))
72
73 ### option logic
74 if [[ "$1" > 0 ]]; then
75 interval=$1; shift
76 fi
77 if [[ "$1" > 0 ]]; then
78 count=$1; shift
79 fi
80 if (( opt_clear )); then
81 clearstr=`clear`
82 else
83 clearstr=.
84 fi
85
86
87
88 #################################
89 # --- Main Program, DTrace ---
90 #
91 /usr/sbin/dtrace -n '
92 #pragma D option quiet
93 #pragma D option destructive
94
95 /* constants */
96 inline int OPT_clear = '$opt_clear';
97 inline int OPT_persec = '$opt_persec';
98 inline int INTERVAL = '$interval';
99 inline int COUNTER = '$count';
100 inline int SCREEN = 20;
101 inline string CLEAR = "'$clearstr'";
102
103 /* variables */
104 dtrace:::BEGIN
105 {
106 secs = INTERVAL;
107 counts = COUNTER;
108 printf("Tracing... Please wait.\n");
109 }
110
111 /* record syscall event */
112 syscall:::entry
113 {
114 @Name[probefunc] = count();
115 @Total = count();
116 }
117
118 /* timer */
119 profile:::tick-1sec
120 {
121 secs--;
122 }
123
124 /* update screen */
125 profile:::tick-1sec
126 /secs == 0/
127 {
128 /* fetch load averages */
129 this->load1a = `hp_avenrun[0] / 65536;
130 this->load5a = `hp_avenrun[1] / 65536;
131 this->load15a = `hp_avenrun[2] / 65536;
132 this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
133 this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536;
134 this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
135
136 /* clear screen */
137 OPT_clear ? printf("%s", CLEAR) : 1;
138
139 /* print load average */
140 printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
141 walltimestamp, this->load1a, this->load1b, this->load5a,
142 this->load5b, this->load15a, this->load15b);
143
144 /* calculate per second values if needed */
145 OPT_persec ? normalize(@Total, INTERVAL) : 1;
146 OPT_persec ? normalize(@Name, INTERVAL) : 1;
147
148 /* print syscall count */
149 printf(" %s: ", OPT_persec ? "syscalls/s" : "syscalls");
150 printa("%@d\n",@Total);
151
152 /* print report */
153 trunc(@Name, SCREEN);
154 printf("\n %-25s %12s\n", "SYSCALL",
155 OPT_persec ? "COUNT/s" : "COUNT");
156 printa(" %-25s %@12d\n", @Name);
157 printf("\n");
158
159 /* reset variables */
160 trunc(@Name);
161 clear(@Total);
162 secs = INTERVAL;
163 counts--;
164 }
165
166 /*
167 * End of program
168 */
169 profile:::tick-1sec
170 /counts == 0/
171 {
172 exit(0);
173 }
174
175 /*
176 * Cleanup for Ctrl-C
177 */
178 dtrace:::END
179 {
180 trunc(@Name);
181 trunc(@Total);
182 }
183 '
184
185