1#!/bin/ksh 2# #!/usr/bin/ksh 3# 4# topsyscall - display top syscalls by syscall name. 5# Written using DTrace (Solaris 10 3/05). 6# 7# This program continually prints a report of the top system calls, 8# and refreshes the display every 1 second or as specified at the 9# command line. 10# 11# 20-Apr-2006, ver 0.91 12# 13# USAGE: topsyscall [-Cs] [interval [count]] 14# 15# -C # don't clear the screen 16# -s # print per second values 17# 18# FIELDS: 19# load avg load averages, see uptime(1) 20# syscalls total syscalls in this interval 21# syscalls/s syscalls per second 22# SYSCALL system call name 23# COUNT total syscalls in this interval 24# COUNT/s syscalls per second 25# 26# INSPIRATION: top(1) by William LeFebvre 27# 28# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. 29# 30# CDDL HEADER START 31# 32# The contents of this file are subject to the terms of the 33# Common Development and Distribution License, Version 1.0 only 34# (the "License"). You may not use this file except in compliance 35# with the License. 36# 37# You can obtain a copy of the license at Docs/cddl1.txt 38# or http://www.opensolaris.org/os/licensing. 39# See the License for the specific language governing permissions 40# and limitations under the License. 41# 42# CDDL HEADER END 43# 44# 13-Jun-2005 Brendan Gregg Created this. 45# 46 47############################## 48# --- Process Arguments --- 49# 50 51### Default variables 52count=-1; interval=1; opt_persec=0; opt_clear=1 53 54### Process options 55while getopts Chs name 56do 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 70done 71shift $(( $OPTIND - 1 )) 72 73### option logic 74if [[ "$1" > 0 ]]; then 75 interval=$1; shift 76fi 77if [[ "$1" > 0 ]]; then 78 count=$1; shift 79fi 80if (( opt_clear )); then 81 clearstr=`clear` 82else 83 clearstr=. 84fi 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 /* SOLARIS: 130 this->load1a = `hp_avenrun[0] / 65536; 131 this->load5a = `hp_avenrun[1] / 65536; 132 this->load15a = `hp_avenrun[2] / 65536; 133 this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536; 134 this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536; 135 this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536; 136 */ 137 this->fscale = `averunnable.fscale; 138 this->load1a = `averunnable.ldavg[0] / this->fscale; 139 this->load5a = `averunnable.ldavg[1] / this->fscale; 140 this->load15a = `averunnable.ldavg[2] / this->fscale; 141 this->load1b = ((`averunnable.ldavg[0] % this->fscale) * 100) / this->fscale; 142 this->load5b = ((`averunnable.ldavg[1] % this->fscale) * 100) / this->fscale; 143 this->load15b = ((`averunnable.ldavg[2] % this->fscale) * 100) / this->fscale; 144 145 /* clear screen */ 146 OPT_clear ? printf("%s", CLEAR) : 1; 147 148 /* print load average */ 149 printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d", 150 walltimestamp, this->load1a, this->load1b, this->load5a, 151 this->load5b, this->load15a, this->load15b); 152 153 /* calculate per second values if needed */ 154 OPT_persec ? normalize(@Total, INTERVAL) : 1; 155 OPT_persec ? normalize(@Name, INTERVAL) : 1; 156 157 /* print syscall count */ 158 printf(" %s: ", OPT_persec ? "syscalls/s" : "syscalls"); 159 printa("%@d\n",@Total); 160 161 /* print report */ 162 trunc(@Name, SCREEN); 163 printf("\n %-25s %12s\n", "SYSCALL", 164 OPT_persec ? "COUNT/s" : "COUNT"); 165 printa(" %-25s %@12d\n", @Name); 166 printf("\n"); 167 168 /* reset variables */ 169 trunc(@Name); 170 clear(@Total); 171 secs = INTERVAL; 172 counts--; 173 } 174 175 /* 176 * End of program 177 */ 178 profile:::tick-1sec 179 /counts == 0/ 180 { 181 exit(0); 182 } 183 184 /* 185 * Cleanup for Ctrl-C 186 */ 187 dtrace:::END 188 { 189 trunc(@Name); 190 trunc(@Total); 191 } 192' 193 194