Home | History | Annotate | Line # | Download | only in System
      1 #!/usr/bin/ksh
      2 #
      3 # topsyscall - display top syscalls by syscall name.
      4 #              Written using DTrace (Solaris 10 3/05).
      5 #
      6 # This program continually prints a report of the top system calls,
      7 # and refreshes the display every 1 second or as specified at the
      8 # command line.
      9 #
     10 # $Id: topsyscall,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $
     11 #
     12 # USAGE:        topsyscall [-Cs] [interval [count]]
     13 #
     14 #		    -C		# don't clear the screen
     15 #		    -s		# print per second values
     16 #
     17 # FIELDS:
     18 #		load avg	load averages, see uptime(1)
     19 #		syscalls	total syscalls in this interval
     20 #		syscalls/s	syscalls per second
     21 #		SYSCALL		system call name
     22 #		COUNT		total syscalls in this interval
     23 #		COUNT/s		syscalls per second
     24 #
     25 # INSPIRATION:  top(1) by William LeFebvre
     26 #
     27 # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
     28 #
     29 # CDDL HEADER START
     30 #
     31 #  The contents of this file are subject to the terms of the
     32 #  Common Development and Distribution License, Version 1.0 only
     33 #  (the "License").  You may not use this file except in compliance
     34 #  with the License.
     35 #
     36 #  You can obtain a copy of the license at Docs/cddl1.txt
     37 #  or http://www.opensolaris.org/os/licensing.
     38 #  See the License for the specific language governing permissions
     39 #  and limitations under the License.
     40 #
     41 # CDDL HEADER END
     42 #
     43 # 13-Jun-2005	Brendan Gregg	Created this.
     44 # 20-Apr-2006	   "      "	Last update.
     45 #
     46 
     47 ##############################
     48 # --- Process Arguments ---
     49 #
     50 
     51 ### Default variables
     52 count=-1; interval=1; opt_persec=0; opt_clear=1
     53 
     54 ### Process options
     55 while getopts Chs name
     56 do
     57         case $name in
     58         C)      opt_clear=0 ;;
     59         s)      opt_persec=1 ;;
     60         h|?)    cat <<-END >&2
     61 		USAGE: topsyscall [-s] [interval [count]]
     62 		           -C          # don't clear the screen
     63 		           -s          # print per second values
     64 		   eg,
     65 		       topsyscall      # default, 1 second updates
     66 		       topsyscall 5    # 5 second updates
     67 		END
     68 		exit 1
     69         esac
     70 done
     71 shift $(( $OPTIND - 1 ))
     72 
     73 ### option logic
     74 if [[ "$1" > 0 ]]; then
     75         interval=$1; shift
     76 fi
     77 if [[ "$1" > 0 ]]; then
     78         count=$1; shift
     79 fi
     80 if (( opt_clear )); then
     81         clearstr=`clear`
     82 else
     83         clearstr=.
     84 fi
     85 
     86 
     87 
     88 #################################
     89 # --- Main Program, DTrace ---
     90 #
     91 /usr/sbin/dtrace -n '
     92  #pragma D option quiet
     93  #pragma D option destructive
     94 
     95  /* constants */
     96  inline int OPT_clear  = '$opt_clear';
     97  inline int OPT_persec = '$opt_persec';
     98  inline int INTERVAL   = '$interval';
     99  inline int COUNTER    = '$count';
    100  inline int SCREEN     = 20;
    101  inline string CLEAR   = "'$clearstr'";
    102 
    103  /* variables */
    104  dtrace:::BEGIN
    105  {
    106 	secs = INTERVAL;
    107 	counts = COUNTER;
    108 	printf("Tracing... Please wait.\n");
    109  }
    110 
    111  /* record syscall event */
    112  syscall:::entry
    113  {
    114 	@Name[probefunc] = count();
    115 	@Total = count();
    116  }
    117 
    118  /* timer */
    119  profile:::tick-1sec
    120  {
    121         secs--;
    122  }
    123 
    124  /* update screen */
    125  profile:::tick-1sec
    126  /secs == 0/
    127  {
    128         /* fetch load averages */
    129         this->load1a  = `hp_avenrun[0] / 65536;
    130         this->load5a  = `hp_avenrun[1] / 65536;
    131         this->load15a = `hp_avenrun[2] / 65536;
    132         this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
    133         this->load5b  = ((`hp_avenrun[1] % 65536) * 100) / 65536;
    134         this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
    135 
    136 	/* clear screen */
    137 	OPT_clear ? printf("%s", CLEAR) : 1;
    138 
    139         /* print load average */
    140         printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
    141             walltimestamp, this->load1a, this->load1b, this->load5a,
    142             this->load5b, this->load15a, this->load15b);
    143 
    144 	/* calculate per second values if needed */
    145 	OPT_persec ? normalize(@Total, INTERVAL) : 1;
    146 	OPT_persec ? normalize(@Name, INTERVAL) : 1;
    147 
    148 	/* print syscall count */
    149 	printf("   %s: ", OPT_persec ? "syscalls/s" : "syscalls");
    150 	printa("%@d\n",@Total);
    151 
    152 	/* print report */
    153 	trunc(@Name, SCREEN);
    154 	printf("\n   %-25s %12s\n", "SYSCALL", 
    155 	    OPT_persec ? "COUNT/s" : "COUNT");
    156 	printa("   %-25s %@12d\n", @Name);
    157 	printf("\n");
    158 
    159 	/* reset variables */
    160 	trunc(@Name);
    161 	clear(@Total);
    162 	secs = INTERVAL;
    163 	counts--;
    164  }
    165 
    166  /*
    167   * End of program
    168   */
    169  profile:::tick-1sec
    170  /counts == 0/
    171  {
    172 	exit(0);
    173  }
    174 
    175  /*
    176   * Cleanup for Ctrl-C
    177   */
    178  dtrace:::END
    179  {
    180 	trunc(@Name);
    181 	trunc(@Total);
    182  }
    183 '
    184 
    185