1235368Sgnn#!/usr/bin/sh
2235368Sgnn#
3235368Sgnn# topsysproc - display top syscalls by process name.
4235368Sgnn#              Written using DTrace (Solaris 10 3/05).
5235368Sgnn#
6235368Sgnn# This program continually prints a report of the number of system calls
7235368Sgnn# by process name, and refreshes the display every 1 second or as specified
8235368Sgnn# at the command line. Similar data can be fetched with "prstat -m".
9235368Sgnn#
10235368Sgnn# $Id: topsysproc 19 2007-09-12 07:47:59Z brendan $
11235368Sgnn#
12235368Sgnn# USAGE:        topsysproc [interval]
13235368Sgnn#
14235368Sgnn# FIELDS:
15235368Sgnn#		load avg   load averages, see uptime(1)
16235368Sgnn#		syscalls   total number of syscalls in this interval
17235368Sgnn#		PROCESS    process name
18235368Sgnn#		COUNT      number of occurances in this interval
19235368Sgnn#
20235368Sgnn# NOTE: There may be several PIDs with the same process name.
21235368Sgnn#
22235368Sgnn# SEE ALSO:     prstat(1M)
23235368Sgnn#
24235368Sgnn# INSPIRATION:  top(1) by William LeFebvre
25235368Sgnn#
26235368Sgnn# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
27235368Sgnn#
28235368Sgnn# CDDL HEADER START
29235368Sgnn#
30235368Sgnn#  The contents of this file are subject to the terms of the
31235368Sgnn#  Common Development and Distribution License, Version 1.0 only
32235368Sgnn#  (the "License").  You may not use this file except in compliance
33235368Sgnn#  with the License.
34235368Sgnn#
35235368Sgnn#  You can obtain a copy of the license at Docs/cddl1.txt
36235368Sgnn#  or http://www.opensolaris.org/os/licensing.
37235368Sgnn#  See the License for the specific language governing permissions
38235368Sgnn#  and limitations under the License.
39235368Sgnn#
40235368Sgnn# CDDL HEADER END
41235368Sgnn#
42235368Sgnn# 13-Jun-2005	Brendan Gregg	Created this.
43235368Sgnn# 20-Apr-2006	   "      "	Last update.
44235368Sgnn#
45235368Sgnn
46235368Sgnn#
47235368Sgnn#  Check options
48235368Sgnn#
49235368Sgnnif [ "$1" = "-h" -o "$1" = "--help" ]; then
50235368Sgnn	cat <<-END
51235368Sgnn	USAGE: topsysproc [interval]
52235368Sgnn	   eg,
53235368Sgnn	       topsysproc            # default, 1 second updates
54235368Sgnn	       topsysproc 5          # 5 second updates
55235368Sgnn	END
56235368Sgnn	exit 1
57235368Sgnnfi
58235368Sgnninterval=1
59235368Sgnnif [ "$1" -gt 0 ]; then
60235368Sgnn	interval=$1
61235368Sgnnfi
62235368Sgnn
63235368Sgnn#
64235368Sgnn#  Run DTrace
65235368Sgnn#
66235368Sgnn/usr/sbin/dtrace -n '
67235368Sgnn #pragma D option quiet
68235368Sgnn #pragma D option destructive
69235368Sgnn
70235368Sgnn /* constants */
71235368Sgnn inline int INTERVAL = '$interval';
72235368Sgnn inline int SCREEN   = 20;
73235368Sgnn
74235368Sgnn /* variables */
75235368Sgnn dtrace:::BEGIN
76235368Sgnn {
77235368Sgnn	secs = 0;
78235368Sgnn	printf("Tracing... Please wait.\n");
79235368Sgnn }
80235368Sgnn
81235368Sgnn /* record syscall event */
82235368Sgnn syscall:::entry
83235368Sgnn {
84235368Sgnn	@Name[execname] = count();
85235368Sgnn	@Total = count();
86235368Sgnn }
87235368Sgnn
88235368Sgnn /* update screen */
89235368Sgnn profile:::tick-1sec
90235368Sgnn /++secs >= INTERVAL/
91235368Sgnn {
92235368Sgnn        /* fetch load averages */
93235368Sgnn        this->load1a  = `hp_avenrun[0] / 65536;
94235368Sgnn        this->load5a  = `hp_avenrun[1] / 65536;
95235368Sgnn        this->load15a = `hp_avenrun[2] / 65536;
96235368Sgnn        this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
97235368Sgnn        this->load5b  = ((`hp_avenrun[1] % 65536) * 100) / 65536;
98235368Sgnn        this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536;
99235368Sgnn
100235368Sgnn	/* clear screen */
101235368Sgnn	system("clear");
102235368Sgnn
103235368Sgnn        /* print load average */
104235368Sgnn        printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d",
105235368Sgnn            walltimestamp, this->load1a, this->load1b, this->load5a,
106235368Sgnn            this->load5b, this->load15a, this->load15b);
107235368Sgnn
108235368Sgnn	/* print syscall count */
109235368Sgnn	printa("   syscalls: %@d\n",@Total);
110235368Sgnn
111235368Sgnn	/* print report */
112235368Sgnn	trunc(@Name, SCREEN);
113235368Sgnn	printf("\n   %-25s %12s\n", "PROCESS", "COUNT");
114235368Sgnn	printa("   %-25s %@12d\n", @Name);
115235368Sgnn
116235368Sgnn	/* reset variables */
117235368Sgnn	trunc(@Name);
118235368Sgnn	clear(@Total);
119235368Sgnn	secs = 0;
120235368Sgnn }
121235368Sgnn'
122