diff options
Diffstat (limited to 'cddl/contrib/dtracetoolkit/rwtop')
-rwxr-xr-x | cddl/contrib/dtracetoolkit/rwtop | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/rwtop b/cddl/contrib/dtracetoolkit/rwtop new file mode 100755 index 0000000..ed0a6fa --- /dev/null +++ b/cddl/contrib/dtracetoolkit/rwtop @@ -0,0 +1,292 @@ +#!/usr/bin/ksh +# +# rwtop - display top read/write bytes by process. +# Written using DTrace (Solaris 10 3/05). +# +# This is measuring reads and writes at the application level. This matches +# read and write system calls. +# +# $Id: rwtop 3 2007-08-01 10:50:08Z brendan $ +# +# USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid] +# [-t top] [interval [count]] +# +# rwtop # default output, 5 second samples +# +# -C # don't clear the screen +# -c # print counts +# -j # print project ID +# -Z # print zone ID +# -n name # this process name only +# -p PID # this PID only +# -t top # print top number only +# eg, +# rwtop 1 # 1 second samples +# rwtop -t 10 # print top 10 only +# rwtop -n bash # monitor processes named "bash" +# rwtop -C 5 12 # print 12 x 5 second samples +# +# FIELDS: +# ZONE Zone ID +# PROJ Project ID +# UID User ID +# PID Process ID +# PPID Parent Process ID +# CMD Process name +# D Direction, Read or Write +# BYTES Total bytes during sample +# app_r total reads during sample, Kbytes +# app_w total writes during sample, Kbytes +# +# SEE ALSO: iotop +# +# INSPIRATION: top(1) by William LeFebvre +# +# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# Author: Brendan Gregg [Sydney, Australia] +# +# 24-Jul-2005 Brendan Gregg Created this. +# 20-Apr-2006 " " Last update. + + +############################## +# --- Process Arguments --- +# + +### default variables +opt_name=0; opt_pid=0; opt_clear=1; opt_proj=0; opt_zone=0 +opt_def=1; opt_bytes=1; filter=0; pname=.; pid=0 +opt_top=0; opt_count=0; interval=5; count=-1; top=0 + +### process options +while getopts Cchn:p:jt:Z name +do + case $name in + C) opt_clear=0 ;; + c) opt_count=1; opt_bytes=0 ;; + n) opt_name=1; pname=$OPTARG ;; + p) opt_pid=1; pid=$OPTARG ;; + j) opt_proj=1; opt_def=0 ;; + t) opt_top=1; top=$OPTARG ;; + Z) opt_zone=1; opt_def=0 ;; + h|?) cat <<-END >&2 + USAGE: rwtop [-cC] [-j|-Z] [-n name] [-p pid] + [-t top] [interval [count]] + + -C # don't clear the screen + -c # print counts + -j # print project ID + -Z # print zone ID + -n name # this process name only + -p PID # this PID only + -t top # print top number only + eg, + rwtop # default output, 5 second samples + rwtop 1 # 1 second samples + rwtop -t 10 # print top 10 only + rwtop -n bash # monitor processes named "bash" + rwtop -C 5 12 # print 12 x 5 second samples + END + exit 1 + esac +done + +shift $(( $OPTIND - 1 )) + +### option logic +if [[ "$1" > 0 ]]; then + interval=$1; shift +fi +if [[ "$1" > 0 ]]; then + count=$1; shift +fi +if (( opt_proj && opt_zone )); then + opt_proj=0 +fi +if (( opt_name || opt_pid )); then + filter=1 +fi +if (( opt_clear )); then + clearstr=`clear` +else + clearstr=. +fi + + + +################################# +# --- Main Program, DTrace --- +# +/usr/sbin/dtrace -n ' + /* + * Command line arguments + */ + inline int OPT_def = '$opt_def'; + inline int OPT_proj = '$opt_proj'; + inline int OPT_zone = '$opt_zone'; + inline int OPT_clear = '$opt_clear'; + inline int OPT_bytes = '$opt_bytes'; + inline int OPT_count = '$opt_count'; + inline int OPT_name = '$opt_name'; + inline int OPT_pid = '$opt_pid'; + inline int OPT_top = '$opt_top'; + inline int INTERVAL = '$interval'; + inline int COUNTER = '$count'; + inline int FILTER = '$filter'; + inline int TOP = '$top'; + inline int PID = '$pid'; + inline string NAME = "'$pname'"; + inline string CLEAR = "'$clearstr'"; + + #pragma D option quiet + + /* + * Print header + */ + dtrace:::BEGIN + { + /* starting values */ + counts = COUNTER; + secs = INTERVAL; + app_r = 0; + app_w = 0; + + printf("Tracing... Please wait.\n"); + } + + /* + * Check event is being traced + */ + sysinfo:::readch, + sysinfo:::writech + /pid != $pid/ + { + /* default is to trace unless filtering, */ + this->ok = FILTER ? 0 : 1; + + /* check each filter, */ + (OPT_name == 1 && NAME == execname)? this->ok = 1 : 1; + (OPT_pid == 1 && PID == pid) ? this->ok = 1 : 1; + } + + /* + * Increment tallys + */ + sysinfo:::readch + /this->ok/ + { + app_r += arg0; + } + sysinfo:::writech + /this->ok/ + { + app_w += arg0; + } + + /* + * Process event + */ + sysinfo:::readch, + sysinfo:::writech + /this->ok/ + { + /* choose statistic to track */ + this->value = OPT_bytes ? arg0 : 1; + + /* + * Save details + */ + OPT_def ? @out[uid, pid, ppid, execname, + probename == "readch" ? "R" : "W"] = sum(this->value) : 1; + OPT_proj ? @out[curpsinfo->pr_projid, pid, ppid, execname, + probename == "readch" ? "R" : "W"] = sum(this->value) : 1; + OPT_zone ? @out[curpsinfo->pr_zoneid, pid, ppid, execname, + probename == "readch" ? "R" : "W"] = sum(this->value) : 1; + + this->ok = 0; + } + + /* + * Timer + */ + profile:::tick-1sec + { + secs--; + } + + /* + * Print Report + */ + profile:::tick-1sec + /secs == 0/ + { + /* fetch 1 min load average */ + this->load1a = `hp_avenrun[0] / 65536; + this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536; + + /* convert counters to Kbytes */ + app_r /= 1024; + app_w /= 1024; + + /* print status */ + OPT_clear ? printf("%s", CLEAR) : 1; + printf("%Y, load: %d.%02d, app_r: %6d KB, app_w: %6d KB\n\n", + walltimestamp, this->load1a, this->load1b, app_r, app_w); + + /* print headers */ + OPT_def ? printf(" UID ") : 1; + OPT_proj ? printf(" PROJ ") : 1; + OPT_zone ? printf(" ZONE ") : 1; + printf("%6s %6s %-16s %1s", + "PID", "PPID", "CMD", "D"); + OPT_bytes ? printf(" %16s\n", "BYTES") : 1; + OPT_count ? printf(" %16s\n", "COUNT") : 1; + + /* truncate to top lines if needed */ + OPT_top ? trunc(@out, TOP) : 1; + + /* print data */ + printa("%5d %6d %6d %-16s %1s %16@d\n", @out); + printf("\n"); + + /* clear data */ + trunc(@out); + app_r = 0; + app_w = 0; + secs = INTERVAL; + counts--; + } + + /* + * End of program + */ + profile:::tick-1sec + /counts == 0/ + { + exit(0); + } + + /* + * Cleanup for Ctrl-C + */ + dtrace:::END + { + trunc(@out); + } +' + |