3 # rwtop - display top read/write bytes by process.
4 # Written using DTrace (Solaris 10 3/05).
6 # This is measuring reads and writes at the application level. This matches
7 # read and write system calls.
9 # $Id: rwtop 3 2007-08-01 10:50:08Z brendan $
11 # USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid]
12 # [-t top] [interval [count]]
14 # rwtop # default output, 5 second samples
16 # -C # don't clear the screen
18 # -j # print project ID
20 # -n name # this process name only
21 # -p PID # this PID only
22 # -t top # print top number only
24 # rwtop 1 # 1 second samples
25 # rwtop -t 10 # print top 10 only
26 # rwtop -n bash # monitor processes named "bash"
27 # rwtop -C 5 12 # print 12 x 5 second samples
34 # PPID Parent Process ID
36 # D Direction, Read or Write
37 # BYTES Total bytes during sample
38 # app_r total reads during sample, Kbytes
39 # app_w total writes during sample, Kbytes
43 # INSPIRATION: top(1) by William LeFebvre
45 # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
49 # The contents of this file are subject to the terms of the
50 # Common Development and Distribution License, Version 1.0 only
51 # (the "License"). You may not use this file except in compliance
54 # You can obtain a copy of the license at Docs/cddl1.txt
55 # or http://www.opensolaris.org/os/licensing.
56 # See the License for the specific language governing permissions
57 # and limitations under the License.
61 # Author: Brendan Gregg [Sydney, Australia]
63 # 24-Jul-2005 Brendan Gregg Created this.
64 # 20-Apr-2006 " " Last update.
67 ##############################
68 # --- Process Arguments ---
72 opt_name=0; opt_pid=0; opt_clear=1; opt_proj=0; opt_zone=0
73 opt_def=1; opt_bytes=1; filter=0; pname=.; pid=0
74 opt_top=0; opt_count=0; interval=5; count=-1; top=0
77 while getopts Cchn:p:jt:Z name
81 c) opt_count=1; opt_bytes=0 ;;
82 n) opt_name=1; pname=$OPTARG ;;
83 p) opt_pid=1; pid=$OPTARG ;;
84 j) opt_proj=1; opt_def=0 ;;
85 t) opt_top=1; top=$OPTARG ;;
86 Z) opt_zone=1; opt_def=0 ;;
88 USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid]
89 [-t top] [interval [count]]
91 -C # don't clear the screen
95 -n name # this process name only
96 -p PID # this PID only
97 -t top # print top number only
99 rwtop # default output, 5 second samples
100 rwtop 1 # 1 second samples
101 rwtop -t 10 # print top 10 only
102 rwtop -n bash # monitor processes named "bash"
103 rwtop -C 5 12 # print 12 x 5 second samples
109 shift $(( $OPTIND - 1 ))
112 if [[ "$1" > 0 ]]; then
115 if [[ "$1" > 0 ]]; then
118 if (( opt_proj && opt_zone )); then
121 if (( opt_name || opt_pid )); then
124 if (( opt_clear )); then
132 #################################
133 # --- Main Program, DTrace ---
135 /usr/sbin/dtrace -n '
137 * Command line arguments
139 inline int OPT_def = '$opt_def';
140 inline int OPT_proj = '$opt_proj';
141 inline int OPT_zone = '$opt_zone';
142 inline int OPT_clear = '$opt_clear';
143 inline int OPT_bytes = '$opt_bytes';
144 inline int OPT_count = '$opt_count';
145 inline int OPT_name = '$opt_name';
146 inline int OPT_pid = '$opt_pid';
147 inline int OPT_top = '$opt_top';
148 inline int INTERVAL = '$interval';
149 inline int COUNTER = '$count';
150 inline int FILTER = '$filter';
151 inline int TOP = '$top';
152 inline int PID = '$pid';
153 inline string NAME = "'$pname'";
154 inline string CLEAR = "'$clearstr'";
156 #pragma D option quiet
163 /* starting values */
169 printf("Tracing... Please wait.\n");
173 * Check event is being traced
179 /* default is to trace unless filtering, */
180 this->ok = FILTER ? 0 : 1;
182 /* check each filter, */
183 (OPT_name == 1 && NAME == execname)? this->ok = 1 : 1;
184 (OPT_pid == 1 && PID == pid) ? this->ok = 1 : 1;
208 /* choose statistic to track */
209 this->value = OPT_bytes ? arg0 : 1;
214 OPT_def ? @out[uid, pid, ppid, execname,
215 probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
216 OPT_proj ? @out[curpsinfo->pr_projid, pid, ppid, execname,
217 probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
218 OPT_zone ? @out[curpsinfo->pr_zoneid, pid, ppid, execname,
219 probename == "readch" ? "R" : "W"] = sum(this->value) : 1;
238 /* fetch 1 min load average */
239 this->load1a = `hp_avenrun[0] / 65536;
240 this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
242 /* convert counters to Kbytes */
247 OPT_clear ? printf("%s", CLEAR) : 1;
248 printf("%Y, load: %d.%02d, app_r: %6d KB, app_w: %6d KB\n\n",
249 walltimestamp, this->load1a, this->load1b, app_r, app_w);
252 OPT_def ? printf(" UID ") : 1;
253 OPT_proj ? printf(" PROJ ") : 1;
254 OPT_zone ? printf(" ZONE ") : 1;
255 printf("%6s %6s %-16s %1s",
256 "PID", "PPID", "CMD", "D");
257 OPT_bytes ? printf(" %16s\n", "BYTES") : 1;
258 OPT_count ? printf(" %16s\n", "COUNT") : 1;
260 /* truncate to top lines if needed */
261 OPT_top ? trunc(@out, TOP) : 1;
264 printa("%5d %6d %6d %-16s %1s %16@d\n", @out);