1 1.2 christos #!/bin/ksh 2 1.1 christos # 3 1.1 christos # rwtop - display top read/write bytes by process. 4 1.1 christos # Written using DTrace (Solaris 10 3/05). 5 1.1 christos # 6 1.1 christos # This is measuring reads and writes at the application level. This matches 7 1.1 christos # read and write system calls. 8 1.1 christos # 9 1.2 christos # $Id: rwtop,v 1.2 2016/12/12 16:30:03 christos Exp $ 10 1.1 christos # 11 1.1 christos # USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid] 12 1.1 christos # [-t top] [interval [count]] 13 1.1 christos # 14 1.1 christos # rwtop # default output, 5 second samples 15 1.1 christos # 16 1.1 christos # -C # don't clear the screen 17 1.1 christos # -c # print counts 18 1.1 christos # -j # print project ID 19 1.1 christos # -Z # print zone ID 20 1.1 christos # -n name # this process name only 21 1.1 christos # -p PID # this PID only 22 1.1 christos # -t top # print top number only 23 1.1 christos # eg, 24 1.1 christos # rwtop 1 # 1 second samples 25 1.1 christos # rwtop -t 10 # print top 10 only 26 1.1 christos # rwtop -n bash # monitor processes named "bash" 27 1.1 christos # rwtop -C 5 12 # print 12 x 5 second samples 28 1.1 christos # 29 1.1 christos # FIELDS: 30 1.1 christos # ZONE Zone ID 31 1.1 christos # PROJ Project ID 32 1.1 christos # UID User ID 33 1.1 christos # PID Process ID 34 1.1 christos # PPID Parent Process ID 35 1.1 christos # CMD Process name 36 1.1 christos # D Direction, Read or Write 37 1.1 christos # BYTES Total bytes during sample 38 1.1 christos # app_r total reads during sample, Kbytes 39 1.1 christos # app_w total writes during sample, Kbytes 40 1.1 christos # 41 1.1 christos # SEE ALSO: iotop 42 1.1 christos # 43 1.1 christos # INSPIRATION: top(1) by William LeFebvre 44 1.1 christos # 45 1.1 christos # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. 46 1.1 christos # 47 1.1 christos # CDDL HEADER START 48 1.1 christos # 49 1.1 christos # The contents of this file are subject to the terms of the 50 1.1 christos # Common Development and Distribution License, Version 1.0 only 51 1.1 christos # (the "License"). You may not use this file except in compliance 52 1.1 christos # with the License. 53 1.1 christos # 54 1.1 christos # You can obtain a copy of the license at Docs/cddl1.txt 55 1.1 christos # or http://www.opensolaris.org/os/licensing. 56 1.1 christos # See the License for the specific language governing permissions 57 1.1 christos # and limitations under the License. 58 1.1 christos # 59 1.1 christos # CDDL HEADER END 60 1.1 christos # 61 1.1 christos # Author: Brendan Gregg [Sydney, Australia] 62 1.1 christos # 63 1.1 christos # 24-Jul-2005 Brendan Gregg Created this. 64 1.1 christos # 20-Apr-2006 " " Last update. 65 1.1 christos 66 1.1 christos 67 1.1 christos ############################## 68 1.1 christos # --- Process Arguments --- 69 1.1 christos # 70 1.1 christos 71 1.1 christos ### default variables 72 1.1 christos opt_name=0; opt_pid=0; opt_clear=1; opt_proj=0; opt_zone=0 73 1.1 christos opt_def=1; opt_bytes=1; filter=0; pname=.; pid=0 74 1.1 christos opt_top=0; opt_count=0; interval=5; count=-1; top=0 75 1.1 christos 76 1.1 christos ### process options 77 1.1 christos while getopts Cchn:p:jt:Z name 78 1.1 christos do 79 1.1 christos case $name in 80 1.1 christos C) opt_clear=0 ;; 81 1.1 christos c) opt_count=1; opt_bytes=0 ;; 82 1.1 christos n) opt_name=1; pname=$OPTARG ;; 83 1.1 christos p) opt_pid=1; pid=$OPTARG ;; 84 1.1 christos j) opt_proj=1; opt_def=0 ;; 85 1.1 christos t) opt_top=1; top=$OPTARG ;; 86 1.1 christos Z) opt_zone=1; opt_def=0 ;; 87 1.1 christos h|?) cat <<-END >&2 88 1.1 christos USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid] 89 1.1 christos [-t top] [interval [count]] 90 1.1 christos 91 1.1 christos -C # don't clear the screen 92 1.1 christos -c # print counts 93 1.1 christos -j # print project ID 94 1.1 christos -Z # print zone ID 95 1.1 christos -n name # this process name only 96 1.1 christos -p PID # this PID only 97 1.1 christos -t top # print top number only 98 1.1 christos eg, 99 1.1 christos rwtop # default output, 5 second samples 100 1.1 christos rwtop 1 # 1 second samples 101 1.1 christos rwtop -t 10 # print top 10 only 102 1.1 christos rwtop -n bash # monitor processes named "bash" 103 1.1 christos rwtop -C 5 12 # print 12 x 5 second samples 104 1.1 christos END 105 1.1 christos exit 1 106 1.1 christos esac 107 1.1 christos done 108 1.1 christos 109 1.1 christos shift $(( $OPTIND - 1 )) 110 1.1 christos 111 1.1 christos ### option logic 112 1.1 christos if [[ "$1" > 0 ]]; then 113 1.1 christos interval=$1; shift 114 1.1 christos fi 115 1.1 christos if [[ "$1" > 0 ]]; then 116 1.1 christos count=$1; shift 117 1.1 christos fi 118 1.1 christos if (( opt_proj && opt_zone )); then 119 1.1 christos opt_proj=0 120 1.1 christos fi 121 1.1 christos if (( opt_name || opt_pid )); then 122 1.1 christos filter=1 123 1.1 christos fi 124 1.1 christos if (( opt_clear )); then 125 1.1 christos clearstr=`clear` 126 1.1 christos else 127 1.1 christos clearstr=. 128 1.1 christos fi 129 1.1 christos 130 1.1 christos 131 1.1 christos 132 1.1 christos ################################# 133 1.1 christos # --- Main Program, DTrace --- 134 1.1 christos # 135 1.1 christos /usr/sbin/dtrace -n ' 136 1.1 christos /* 137 1.1 christos * Command line arguments 138 1.1 christos */ 139 1.1 christos inline int OPT_def = '$opt_def'; 140 1.1 christos inline int OPT_proj = '$opt_proj'; 141 1.1 christos inline int OPT_zone = '$opt_zone'; 142 1.1 christos inline int OPT_clear = '$opt_clear'; 143 1.1 christos inline int OPT_bytes = '$opt_bytes'; 144 1.1 christos inline int OPT_count = '$opt_count'; 145 1.1 christos inline int OPT_name = '$opt_name'; 146 1.1 christos inline int OPT_pid = '$opt_pid'; 147 1.1 christos inline int OPT_top = '$opt_top'; 148 1.1 christos inline int INTERVAL = '$interval'; 149 1.1 christos inline int COUNTER = '$count'; 150 1.1 christos inline int FILTER = '$filter'; 151 1.1 christos inline int TOP = '$top'; 152 1.1 christos inline int PID = '$pid'; 153 1.1 christos inline string NAME = "'$pname'"; 154 1.1 christos inline string CLEAR = "'$clearstr'"; 155 1.1 christos 156 1.1 christos #pragma D option quiet 157 1.1 christos 158 1.1 christos /* 159 1.1 christos * Print header 160 1.1 christos */ 161 1.1 christos dtrace:::BEGIN 162 1.1 christos { 163 1.1 christos /* starting values */ 164 1.1 christos counts = COUNTER; 165 1.1 christos secs = INTERVAL; 166 1.1 christos app_r = 0; 167 1.1 christos app_w = 0; 168 1.1 christos 169 1.1 christos printf("Tracing... Please wait.\n"); 170 1.1 christos } 171 1.1 christos 172 1.1 christos /* 173 1.1 christos * Check event is being traced 174 1.1 christos */ 175 1.1 christos sysinfo:::readch, 176 1.1 christos sysinfo:::writech 177 1.1 christos /pid != $pid/ 178 1.1 christos { 179 1.1 christos /* default is to trace unless filtering, */ 180 1.1 christos this->ok = FILTER ? 0 : 1; 181 1.1 christos 182 1.1 christos /* check each filter, */ 183 1.1 christos (OPT_name == 1 && NAME == execname)? this->ok = 1 : 1; 184 1.1 christos (OPT_pid == 1 && PID == pid) ? this->ok = 1 : 1; 185 1.1 christos } 186 1.1 christos 187 1.1 christos /* 188 1.1 christos * Increment tallys 189 1.1 christos */ 190 1.1 christos sysinfo:::readch 191 1.1 christos /this->ok/ 192 1.1 christos { 193 1.1 christos app_r += arg0; 194 1.1 christos } 195 1.1 christos sysinfo:::writech 196 1.1 christos /this->ok/ 197 1.1 christos { 198 1.1 christos app_w += arg0; 199 1.1 christos } 200 1.1 christos 201 1.1 christos /* 202 1.1 christos * Process event 203 1.1 christos */ 204 1.1 christos sysinfo:::readch, 205 1.1 christos sysinfo:::writech 206 1.1 christos /this->ok/ 207 1.1 christos { 208 1.1 christos /* choose statistic to track */ 209 1.1 christos this->value = OPT_bytes ? arg0 : 1; 210 1.1 christos 211 1.1 christos /* 212 1.1 christos * Save details 213 1.1 christos */ 214 1.1 christos OPT_def ? @out[uid, pid, ppid, execname, 215 1.1 christos probename == "readch" ? "R" : "W"] = sum(this->value) : 1; 216 1.1 christos OPT_proj ? @out[curpsinfo->pr_projid, pid, ppid, execname, 217 1.1 christos probename == "readch" ? "R" : "W"] = sum(this->value) : 1; 218 1.1 christos OPT_zone ? @out[curpsinfo->pr_zoneid, pid, ppid, execname, 219 1.1 christos probename == "readch" ? "R" : "W"] = sum(this->value) : 1; 220 1.1 christos 221 1.1 christos this->ok = 0; 222 1.1 christos } 223 1.1 christos 224 1.1 christos /* 225 1.1 christos * Timer 226 1.1 christos */ 227 1.1 christos profile:::tick-1sec 228 1.1 christos { 229 1.1 christos secs--; 230 1.1 christos } 231 1.1 christos 232 1.1 christos /* 233 1.1 christos * Print Report 234 1.1 christos */ 235 1.1 christos profile:::tick-1sec 236 1.1 christos /secs == 0/ 237 1.1 christos { 238 1.1 christos /* fetch 1 min load average */ 239 1.1 christos this->load1a = `hp_avenrun[0] / 65536; 240 1.1 christos this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536; 241 1.1 christos 242 1.1 christos /* convert counters to Kbytes */ 243 1.1 christos app_r /= 1024; 244 1.1 christos app_w /= 1024; 245 1.1 christos 246 1.1 christos /* print status */ 247 1.1 christos OPT_clear ? printf("%s", CLEAR) : 1; 248 1.1 christos printf("%Y, load: %d.%02d, app_r: %6d KB, app_w: %6d KB\n\n", 249 1.1 christos walltimestamp, this->load1a, this->load1b, app_r, app_w); 250 1.1 christos 251 1.1 christos /* print headers */ 252 1.1 christos OPT_def ? printf(" UID ") : 1; 253 1.1 christos OPT_proj ? printf(" PROJ ") : 1; 254 1.1 christos OPT_zone ? printf(" ZONE ") : 1; 255 1.1 christos printf("%6s %6s %-16s %1s", 256 1.1 christos "PID", "PPID", "CMD", "D"); 257 1.1 christos OPT_bytes ? printf(" %16s\n", "BYTES") : 1; 258 1.1 christos OPT_count ? printf(" %16s\n", "COUNT") : 1; 259 1.1 christos 260 1.1 christos /* truncate to top lines if needed */ 261 1.1 christos OPT_top ? trunc(@out, TOP) : 1; 262 1.1 christos 263 1.1 christos /* print data */ 264 1.1 christos printa("%5d %6d %6d %-16s %1s %16@d\n", @out); 265 1.1 christos printf("\n"); 266 1.1 christos 267 1.1 christos /* clear data */ 268 1.1 christos trunc(@out); 269 1.1 christos app_r = 0; 270 1.1 christos app_w = 0; 271 1.1 christos secs = INTERVAL; 272 1.1 christos counts--; 273 1.1 christos } 274 1.1 christos 275 1.1 christos /* 276 1.1 christos * End of program 277 1.1 christos */ 278 1.1 christos profile:::tick-1sec 279 1.1 christos /counts == 0/ 280 1.1 christos { 281 1.1 christos exit(0); 282 1.1 christos } 283 1.1 christos 284 1.1 christos /* 285 1.1 christos * Cleanup for Ctrl-C 286 1.1 christos */ 287 1.1 christos dtrace:::END 288 1.1 christos { 289 1.1 christos trunc(@out); 290 1.1 christos } 291 1.1 christos ' 292 1.1 christos 293