1#!/bin/sh
2# #!/usr/bin/sh
3#
4# topsysproc - display top syscalls by process name.
5#              Written using DTrace (Solaris 10 3/05).
6#
7# This program continually prints a report of the number of system calls
8# by process name, and refreshes the display every 1 second or as specified
9# at the command line. Similar data can be fetched with "prstat -m".
10#
11# 20-Apr-2006, ver 0.81
12#
13# USAGE:        topsysproc [interval]
14#
15# FIELDS:
16#		load avg   load averages, see uptime(1)
17#		syscalls   total number of syscalls in this interval
18#		PROCESS    process name
19#		COUNT      number of occurances in this interval
20#
21# NOTE: There may be several PIDs with the same process name.
22#
23# SEE ALSO:     prstat(1M)
24#
25# INSPIRATION:  top(1) by William LeFebvre
26#
27# Standard Disclaimer: This is freeware, use at your own risk.
28#
29# 13-Jun-2005  Brendan Gregg   Created this.
30#
31
32#
33#  Check options
34#
35if [ "$1" = "-h" -o "$1" = "--help" ]; then
36	cat <<-END
37	USAGE: topsysproc [interval]
38	   eg,
39	       topsysproc            # default, 1 second updates
40	       topsysproc 5          # 5 second updates
41	END
42	exit 1
43fi
44interval=1
45if [ "$1" -gt 0 ]; then
46	interval=$1
47fi
48
49#
50#  Run DTrace
51#
52/usr/sbin/dtrace -n '
53 #pragma D option quiet
54 #pragma D option destructive
55
56 /* constants */
57 inline int INTERVAL = '$interval';
58 inline int SCREEN   = 20;
59
60 /* variables */
61 dtrace:::BEGIN
62 {
63	secs = 0;
64	printf("Tracing... Please wait.\n");
65 }
66
67 /* record syscall event */
68 syscall:::entry
69 {
70	@Name[execname] = count();
71	@Total = count();
72 }
73
74 /* update screen */
75 profile:::tick-1sec
76 /++secs >= INTERVAL/
77 {
78        /* fetch load averages */
79	/* SOLARIS:
80        this->load1a  = `hp_avenrun[0] / 65536;
81        this->load5a  = `hp_avenrun[1] / 65536;
82        this->load15a = `hp_avenrun[2] / 65536;
83        this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
84        this->load5b  = ((`hp_avenrun[1] % 65536) * 100) / 65536;
85        this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
86	*/
87	this->fscale = `averunnable.fscale;
88	this->load1a  = `averunnable.ldavg[0] / this->fscale;
89	this->load5a  = `averunnable.ldavg[1] / this->fscale;
90	this->load15a = `averunnable.ldavg[2] / this->fscale;
91	this->load1b  = ((`averunnable.ldavg[0] % this->fscale) * 100) / this->fscale;
92	this->load5b  = ((`averunnable.ldavg[1] % this->fscale) * 100) / this->fscale;
93	this->load15b = ((`averunnable.ldavg[2] % this->fscale) * 100) / this->fscale;
94
95	/* clear screen */
96	system("clear");
97
98        /* print load average */
99        printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
100            walltimestamp, this->load1a, this->load1b, this->load5a,
101            this->load5b, this->load15a, this->load15b);
102
103	/* print syscall count */
104	printa("   syscalls: %@d\n",@Total);
105
106	/* print report */
107	trunc(@Name, SCREEN);
108	printf("\n   %-25s %12s\n", "PROCESS", "COUNT");
109	printa("   %-25s %@12d\n", @Name);
110
111	/* reset variables */
112	trunc(@Name);
113	clear(@Total);
114	secs = 0;
115 }
116'
117
118