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 3 2007-08-01 10:50:08Z brendan $ 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 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 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