#!/bin/sh
opt_filter=0; opt_pid=0; opt_name=0; pid=0; pname=".";
opt_elapsed=0; opt_cpu=0; opt_counts=0; opt_totals=0
opt_command=0; command="";
while getopts acehn:op:T name
do
case $name in
p) opt_filter=1; opt_pid=1; pid=$OPTARG ;;
n) opt_filter=1; opt_name=1; pname=$OPTARG ;;
a) opt_totals=1; opt_elapsed=1; opt_cpu=1; opt_counts=1 ;;
e) opt_elapsed=1 ;;
c) opt_counts=1 ;;
o) opt_cpu=1 ;;
T) opt_totals=1 ;;
h|?) cat <<-END >&2
USAGE: procsystime [-aceho] [ -p PID | -n name | command ]
-p PID -n name -a -e -c -o -T eg,
procsystime -p 1871 procsystime -n tar procsystime -aTn bash procsystime df -h END
exit 1
esac
done
shift `expr $OPTIND - 1`
if [ $opt_pid -eq 0 -a $opt_name -eq 0 -a "$*" != "" ]; then
opt_filter=1
opt_command=1
command="$*"
fi
if [ $opt_elapsed -eq 0 -a $opt_cpu -eq 0 -a $opt_counts -eq 0 ]; then
opt_elapsed=1;
fi
dtrace='
/*
* Command line arguments
*/
inline int OPT_elapsed = '$opt_elapsed';
inline int OPT_cpu = '$opt_cpu';
inline int OPT_counts = '$opt_counts';
inline int OPT_filter = '$opt_filter';
inline int OPT_pid = '$opt_pid';
inline int OPT_name = '$opt_name';
inline int OPT_totals = '$opt_totals';
inline int OPT_command = '$opt_command';
inline int PID = '$pid';
inline string NAME = "'"$pname"'";
inline string COMMAND = "'"$command"'";
dtrace:::BEGIN
{
self->start = 0;
self->vstart = 0;
}
dtrace:::BEGIN
/! OPT_command/
{
printf("Hit Ctrl-C to stop sampling...\n");
}
/*
* Set start timestamp and counts
*/
syscall:::entry
/(! OPT_filter) ||
(OPT_pid && pid == PID) ||
(OPT_name && NAME == strstr(NAME, execname)) ||
(OPT_name && execname == strstr(execname, NAME)) ||
(OPT_command && pid == $target)/
{
self->ok = 1;
}
syscall:::entry
/self->ok/
{
OPT_counts ? @Counts[probefunc] = count() : 1;
(OPT_counts && OPT_totals) ? @Counts["TOTAL:"] = count() : 1;
OPT_elapsed ? self->start = timestamp : 1;
OPT_cpu ? self->vstart = vtimestamp : 1;
self->ok = 0;
}
/*
* Calculate time deltas
*/
syscall:::return
/self->start/
{
this->elapsed = timestamp - self->start;
@Elapsed[probefunc] = sum(this->elapsed);
OPT_totals ? @Elapsed["TOTAL:"] = sum(this->elapsed) : 1;
self->start = 0;
}
syscall:::return
/self->vstart/
{
this->cpu = vtimestamp - self->vstart;
@CPU[probefunc] = sum(this->cpu);
OPT_totals ? @CPU["TOTAL:"] = sum(this->cpu) : 1;
self->vstart = 0;
}
/*
* Elapsed time report
*/
dtrace:::END
/OPT_elapsed/
{
printf("\nElapsed Times for ");
OPT_pid ? printf("PID %d,\n\n",PID) : 1;
OPT_name ? printf("processes %s,\n\n",NAME) : 1;
OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
(! OPT_filter) ? printf("all processes,\n\n") : 1;
printf("%16s %18s\n","SYSCALL","TIME (ns)");
printa("%16s %@18d\n",@Elapsed);
}
/*
* CPU time report
*/
dtrace:::END
/OPT_cpu/
{
printf("\nCPU Times for ");
OPT_pid ? printf("PID %d,\n\n",PID) : 1;
OPT_name ? printf("processes %s,\n\n",NAME) : 1;
OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
(! OPT_filter) ? printf("all processes,\n\n") : 1;
printf("%16s %18s\n","SYSCALL","TIME (ns)");
printa("%16s %@18d\n",@CPU);
}
/*
* Syscall count report
*/
dtrace:::END
/OPT_counts/
{
printf("\nSyscall Counts for ");
OPT_pid ? printf("PID %d,\n\n",PID) : 1;
OPT_name ? printf("processes %s,\n\n",NAME) : 1;
OPT_command ? printf("command %s,\n\n",COMMAND) : 1;
(! OPT_filter) ? printf("all processes,\n\n") : 1;
printf("%16s %18s\n","SYSCALL","COUNT");
OPT_counts ? printa("%16s %@18d\n",@Counts) : 1;
}
'
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