1N/A#!/usr/bin/ksh
1N/A#
1N/A# topsyscall - display top syscalls by syscall name.
1N/A# Written using DTrace (Solaris 10 3/05).
1N/A#
1N/A# This program continually prints a report of the top system calls,
1N/A# and refreshes the display every 1 second or as specified at the
1N/A# command line.
1N/A#
1N/A# $Id: topsyscall 3 2007-08-01 10:50:08Z brendan $
1N/A#
1N/A# USAGE: topsyscall [-Cs] [interval [count]]
1N/A#
1N/A# -C # don't clear the screen
1N/A# -s # print per second values
1N/A#
1N/A# FIELDS:
1N/A# load avg load averages, see uptime(1)
1N/A# syscalls total syscalls in this interval
1N/A# syscalls/s syscalls per second
1N/A# SYSCALL system call name
1N/A# COUNT total syscalls in this interval
1N/A# COUNT/s syscalls per second
1N/A#
1N/A# INSPIRATION: top(1) by William LeFebvre
1N/A#
1N/A# COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
1N/A#
1N/A# CDDL HEADER START
1N/A#
1N/A# The contents of this file are subject to the terms of the
1N/A# Common Development and Distribution License, Version 1.0 only
1N/A# (the "License"). You may not use this file except in compliance
1N/A# with the License.
1N/A#
1N/A# You can obtain a copy of the license at Docs/cddl1.txt
1N/A# or http://www.opensolaris.org/os/licensing.
1N/A# See the License for the specific language governing permissions
1N/A# and limitations under the License.
1N/A#
1N/A# CDDL HEADER END
1N/A#
1N/A# 13-Jun-2005 Brendan Gregg Created this.
1N/A# 20-Apr-2006 " " Last update.
1N/A#
1N/A
1N/A##############################
1N/A# --- Process Arguments ---
1N/A#
1N/A
1N/A### Default variables
1N/Acount=-1; interval=1; opt_persec=0; opt_clear=1
1N/A
1N/A### Process options
1N/Awhile getopts Chs name
1N/Ado
1N/A case $name in
1N/A C) opt_clear=0 ;;
1N/A s) opt_persec=1 ;;
1N/A h|?) cat <<-END >&2
1N/A USAGE: topsyscall [-s] [interval [count]]
1N/A -C # don't clear the screen
1N/A -s # print per second values
1N/A eg,
1N/A topsyscall # default, 1 second updates
1N/A topsyscall 5 # 5 second updates
1N/A END
1N/A exit 1
1N/A esac
1N/Adone
1N/Ashift $(( $OPTIND - 1 ))
1N/A
1N/A### option logic
1N/Aif [[ "$1" > 0 ]]; then
1N/A interval=$1; shift
1N/Afi
1N/Aif [[ "$1" > 0 ]]; then
1N/A count=$1; shift
1N/Afi
1N/Aif (( opt_clear )); then
1N/A clearstr=`clear`
1N/Aelse
1N/A clearstr=.
1N/Afi
1N/A
1N/A
1N/A
1N/A#################################
1N/A# --- Main Program, DTrace ---
1N/A#
1N/A/usr/sbin/dtrace -n '
1N/A #pragma D option quiet
1N/A #pragma D option destructive
1N/A
1N/A /* constants */
1N/A inline int OPT_clear = '$opt_clear';
1N/A inline int OPT_persec = '$opt_persec';
1N/A inline int INTERVAL = '$interval';
1N/A inline int COUNTER = '$count';
1N/A inline int SCREEN = 20;
1N/A inline string CLEAR = "'$clearstr'";
1N/A
1N/A /* variables */
1N/A dtrace:::BEGIN
1N/A {
1N/A secs = INTERVAL;
1N/A counts = COUNTER;
1N/A printf("Tracing... Please wait.\n");
1N/A }
1N/A
1N/A /* record syscall event */
1N/A syscall:::entry
1N/A {
1N/A @Name[probefunc] = count();
1N/A @Total = count();
1N/A }
1N/A
1N/A /* timer */
1N/A profile:::tick-1sec
1N/A {
1N/A secs--;
1N/A }
1N/A
1N/A /* update screen */
1N/A profile:::tick-1sec
1N/A /secs == 0/
1N/A {
1N/A /* fetch load averages */
1N/A this->load1a = `hp_avenrun[0] / 65536;
1N/A this->load5a = `hp_avenrun[1] / 65536;
1N/A this->load15a = `hp_avenrun[2] / 65536;
1N/A this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
1N/A this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536;
1N/A this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
1N/A
1N/A /* clear screen */
1N/A OPT_clear ? printf("%s", CLEAR) : 1;
1N/A
1N/A /* print load average */
1N/A printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
1N/A walltimestamp, this->load1a, this->load1b, this->load5a,
1N/A this->load5b, this->load15a, this->load15b);
1N/A
1N/A /* calculate per second values if needed */
1N/A OPT_persec ? normalize(@Total, INTERVAL) : 1;
1N/A OPT_persec ? normalize(@Name, INTERVAL) : 1;
1N/A
1N/A /* print syscall count */
1N/A printf(" %s: ", OPT_persec ? "syscalls/s" : "syscalls");
1N/A printa("%@d\n",@Total);
1N/A
1N/A /* print report */
1N/A trunc(@Name, SCREEN);
1N/A printf("\n %-25s %12s\n", "SYSCALL",
1N/A OPT_persec ? "COUNT/s" : "COUNT");
1N/A printa(" %-25s %@12d\n", @Name);
1N/A printf("\n");
1N/A
1N/A /* reset variables */
1N/A trunc(@Name);
1N/A clear(@Total);
1N/A secs = INTERVAL;
1N/A counts--;
1N/A }
1N/A
1N/A /*
1N/A * End of program
1N/A */
1N/A profile:::tick-1sec
1N/A /counts == 0/
1N/A {
1N/A exit(0);
1N/A }
1N/A
1N/A /*
1N/A * Cleanup for Ctrl-C
1N/A */
1N/A dtrace:::END
1N/A {
1N/A trunc(@Name);
1N/A trunc(@Total);
1N/A }
1N/A'
1N/A