251 lines
6.0 KiB
Bash
Executable File
251 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/sh
|
|
#
|
|
# dvmstat - vmstat by PID/name/command.
|
|
# Written using DTrace (Solaris 10 3/05).
|
|
#
|
|
# This program provides vmstat like data for one particular PID, a
|
|
# process name, or when running a command. It prints statistics
|
|
# every second.
|
|
#
|
|
# $Id: dvmstat 3 2007-08-01 10:50:08Z brendan $
|
|
#
|
|
# USAGE: dvmstat { -p PID | -n name | command }
|
|
# eg,
|
|
# dvmstat -p 1871 # examine PID 1871
|
|
# dvmstat -n tar # examine processes called "tar"
|
|
# dvmstat df -h # run and examine "df -h"
|
|
#
|
|
# FIELDS:
|
|
# re page reclaims Kbytes
|
|
# maj major faults Kbytes
|
|
# mf minor faults Kbytes
|
|
# fr page frees Kbytes
|
|
# epi executable page ins Kbytes
|
|
# epo executable page out Kbytes
|
|
# api anonymous page ins Kbytes
|
|
# apo anonymous page outs Kbytes
|
|
# fpi filesystem page ins Kbytes
|
|
# fpo filesystem page outs Kbytes
|
|
# sy system calls number
|
|
#
|
|
# SEE ALSO: vmstat(1M)
|
|
#
|
|
# NOTES:
|
|
#
|
|
# When using dvmstat to run a command - if the command takes some time
|
|
# to execute, dvmstat will print output every second. If the command runs
|
|
# in less than a second, then the only one line of output will be printed.
|
|
#
|
|
# COPYRIGHT: Copyright (c) 2005 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]
|
|
#
|
|
# 12-Jun-2005 Brendan Gregg Created this.
|
|
# 08-Jan-2006 " " Last update.
|
|
#
|
|
|
|
##############################
|
|
# --- Process Arguments ---
|
|
#
|
|
|
|
### Default variables
|
|
opt_pid=0; opt_name=0; pid=0; pname="."; opt_command=0; command=""
|
|
|
|
### Process options
|
|
while getopts hn:p: name
|
|
do
|
|
case $name in
|
|
p) opt_pid=1; pid=$OPTARG ;;
|
|
n) opt_name=1; pname=$OPTARG ;;
|
|
h|?) cat <<-END >&2
|
|
USAGE: dvmstat [-h] { -p PID | -n name | command }
|
|
-p PID # examine this PID
|
|
-n name # examine this process name
|
|
eg,
|
|
dvmstat -p 1871 # examine PID 1871
|
|
dvmstat -n tar # examine processes called "tar"
|
|
dvmstat df -h # run and examine "df -h"
|
|
END
|
|
exit 1
|
|
esac
|
|
done
|
|
shift `expr $OPTIND - 1`
|
|
|
|
|
|
### Option logic
|
|
if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then
|
|
opt_command=1
|
|
if [ "$*" = "" ]; then
|
|
$0 -h
|
|
exit
|
|
fi
|
|
command="$*"
|
|
fi
|
|
|
|
|
|
#################################
|
|
# --- Main Program, DTrace ---
|
|
#
|
|
dtrace='
|
|
#pragma D option quiet
|
|
|
|
/*
|
|
* Command line arguments
|
|
*/
|
|
inline int OPT_pid = '$opt_pid';
|
|
inline int OPT_name = '$opt_name';
|
|
inline int OPT_command = '$opt_command';
|
|
inline int PID = '$pid';
|
|
inline string NAME = "'$pname'";
|
|
inline string COMMAND = "'$command'";
|
|
inline int SCREEN = 21;
|
|
|
|
/*
|
|
* Initialise variables
|
|
*/
|
|
dtrace:::BEGIN
|
|
{
|
|
epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
|
|
re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
|
|
lines = SCREEN + 1;
|
|
header = 0;
|
|
}
|
|
|
|
/*
|
|
* Print header
|
|
*/
|
|
dtrace:::BEGIN,
|
|
dtrace:::END,
|
|
profile:::tick-1sec
|
|
/(OPT_command && probename == "END") ||
|
|
(!(OPT_command && probename == "BEGIN") && lines++ > SCREEN)/
|
|
{
|
|
printf("%6s %5s %5s %4s %4s %4s %4s %4s %4s %4s %6s\n",
|
|
"re", "maj", "mf", "fr", "epi", "epo", "api", "apo",
|
|
"fpi", "fpo", "sy");
|
|
lines = 0;
|
|
}
|
|
|
|
/*
|
|
* Probe events
|
|
*
|
|
* this intentionally does not use an associative array for storing data,
|
|
* for reasons of performance.
|
|
*/
|
|
|
|
vminfo:::execpgin
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ epi += arg0; }
|
|
|
|
vminfo:::execpgout
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ epo += arg0; }
|
|
|
|
vminfo:::anonpgin
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ api += arg0; }
|
|
|
|
vminfo:::anonpgout
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ apo += arg0; }
|
|
|
|
vminfo:::fspgin
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ fpi += arg0; }
|
|
|
|
vminfo:::fspgout
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ fpo += arg0; }
|
|
|
|
vminfo:::pgrec
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ re += arg0; }
|
|
|
|
vminfo:::as_fault
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ mf += arg0; }
|
|
|
|
vminfo:::maj_fault
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ maj += arg0; }
|
|
|
|
vminfo:::dfree
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ fr += arg0; }
|
|
|
|
syscall:::entry
|
|
/(OPT_pid && pid == PID) ||
|
|
(OPT_name && execname == NAME) ||
|
|
(OPT_command && pid == $target)/
|
|
{ sy++; }
|
|
|
|
/*
|
|
* Print output line
|
|
*/
|
|
profile:::tick-1sec,
|
|
dtrace:::END
|
|
{
|
|
/* convert to Kbytes */
|
|
re *= `_pagesize / 1024;
|
|
maj *= `_pagesize / 1024;
|
|
mf *= `_pagesize / 1024;
|
|
fr *= `_pagesize / 1024;
|
|
epi *= `_pagesize / 1024;
|
|
epo *= `_pagesize / 1024;
|
|
api *= `_pagesize / 1024;
|
|
apo *= `_pagesize / 1024;
|
|
fpi *= `_pagesize / 1024;
|
|
fpo *= `_pagesize / 1024;
|
|
|
|
/* print line */
|
|
printf("%6d %5d %5d %4d %4d %4d %4d %4d %4d %4d %6d\n",
|
|
re, maj, mf, fr, epi, epo, api, apo, fpi, fpo, sy);
|
|
|
|
/* clear counters */
|
|
epi = 0; epo = 0; api = 0; apo = 0; fpi = 0; fpo = 0;
|
|
re = 0; mf = 0; maj = 0; fr = 0; sy = 0;
|
|
}
|
|
'
|
|
|
|
### Run DTrace
|
|
if [ $opt_command -eq 1 ]; then
|
|
/usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2
|
|
else
|
|
/usr/sbin/dtrace -n "$dtrace" >&2
|
|
fi
|
|
|