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.1.1 2015/09/30 22:01:09 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