summaryrefslogtreecommitdiff
path: root/src/pmview/front-ends
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmview/front-ends')
-rw-r--r--src/pmview/front-ends/GNUmakefile25
-rwxr-xr-xsrc/pmview/front-ends/clustervis331
-rw-r--r--src/pmview/front-ends/config.clustervis13
-rwxr-xr-xsrc/pmview/front-ends/config.dkvis14
-rwxr-xr-xsrc/pmview/front-ends/config.mpvis13
-rwxr-xr-xsrc/pmview/front-ends/config.nfsvis12
-rwxr-xr-xsrc/pmview/front-ends/config.osvis31
-rwxr-xr-xsrc/pmview/front-ends/config.weblogvis20
-rwxr-xr-xsrc/pmview/front-ends/config.webpingvis8
-rw-r--r--src/pmview/front-ends/config.webvis51
-rwxr-xr-xsrc/pmview/front-ends/dkvis572
-rwxr-xr-xsrc/pmview/front-ends/mpvis452
-rwxr-xr-xsrc/pmview/front-ends/nfsvis244
-rw-r--r--src/pmview/front-ends/osvis651
-rw-r--r--src/pmview/front-ends/pmview-args625
-rwxr-xr-xsrc/pmview/front-ends/weblogvis451
-rwxr-xr-xsrc/pmview/front-ends/weblogvis.load103
-rw-r--r--src/pmview/front-ends/weblogvis.rgbbin0 -> 206570 bytes
-rw-r--r--src/pmview/front-ends/webpingvis372
-rw-r--r--src/pmview/front-ends/webpingvis.rgbbin0 -> 365706 bytes
-rwxr-xr-xsrc/pmview/front-ends/webvis707
-rw-r--r--src/pmview/front-ends/webvis.rgbbin0 -> 502112 bytes
22 files changed, 4695 insertions, 0 deletions
diff --git a/src/pmview/front-ends/GNUmakefile b/src/pmview/front-ends/GNUmakefile
new file mode 100644
index 0000000..c67f02b
--- /dev/null
+++ b/src/pmview/front-ends/GNUmakefile
@@ -0,0 +1,25 @@
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+#VIEWDIR = $(PCP_VAR_DIR)/config/pmview
+VIEWDIR = $(PCP_BIN_DIR)
+LOGDIR = $(PCP_VAR_DIR)/config/pmlogger
+ARGSDIR = $(PCP_SHARE_DIR)/lib
+
+VIEWS = clustervis dkvis mpvis nfsvis osvis weblogvis webpingvis webvis
+LOGGERS = config.dkvis config.mpvis config.nfsvis config.osvis \
+ config.weblogvis config.webpingvis config.webvis
+
+LSRCFILES = $(VIEWS) $(LOGGERS) pmview-args
+
+default build-me:
+
+include $(BUILDRULES)
+
+install: default
+ #$(INSTALL) -m 755 -d $(VIEWDIR)
+ $(INSTALL) -m 755 $(VIEWS) $(VIEWDIR)
+ $(INSTALL) -m 755 -d $(LOGDIR)
+ $(INSTALL) -m 444 $(LOGGERS) $(LOGDIR)
+ $(INSTALL) -m 755 -d $(ARGSDIR)
+ $(INSTALL) -m 755 pmview-args $(ARGSDIR)/pmview-args
diff --git a/src/pmview/front-ends/clustervis b/src/pmview/front-ends/clustervis
new file mode 100755
index 0000000..6cab7aa
--- /dev/null
+++ b/src/pmview/front-ends/clustervis
@@ -0,0 +1,331 @@
+#!/bin/sh
+#
+# Copyright (c) 2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+debug=false
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+# --- scaling parameters ---
+#
+
+# maximum packets per second
+max=750
+
+# maximum req rate (default: 5% of packet rate)
+maxreq=`expr $max / 20`
+
+# milliseconds per CPU
+maxcpu=1000
+
+#
+# clustervis tolerates multiple hosts or archives
+_pmview_multiple_sources_are_ok
+
+# --- define usage message ---
+#
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options]
+
+Default hosts are specified in /etc/nodes (or /etc/ace/nodes)
+or specify the file specifying cluster hosts with the -H flag.
+The -h flag may be used to specify multiple hosts or the -a flag
+may be used to specify multiple archives. The -h, -a and -H flags
+are all mutually exclusive.
+
+options:
+ -H nodes file specifying hosts in cluster
+ [default $PCP_CLUSTER_CONFIG or /etc/nodes or /etc/ace/nodes]
+ -m max maximum expected packets sent or received per sec [default 750]
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+
+ _pmview_usage >> $tmp.msg
+ echo >> $tmp.msg
+ echo >> $tmp.msg 'Default title is: Web Server Activity'
+ echo >> $tmp.msg '
+ By default all network interfaces are shown, with a maximum packet rate
+ of '$max' packets per second. The maximum request rate is 5% (of the
+ maximum packet rate) and the maximum error rate is 20% of the maximum
+ request rate.
+
+ If given, the [interface ...] regular expressions restrict
+ the network statistics displayed to matching network interface names only.'
+
+ _pmview_info -f $tmp.msg
+}
+
+# --- build WM_COMMAND X(1) property for restart after login/logout ---
+#
+echo -n "pmview Version 2.1 \"$prog\"" > $tmp.pmview
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.pmview
+done
+echo >> $tmp.pmview
+
+# --- parse command line arguments ---
+#
+verbose=false
+argInterfaces=""
+hosts=""
+interfaces=""
+numsource=1
+if [ -z "$PCP_CLUSTER_CONFIG" ]
+then
+ nodesfile=/etc/nodes
+ [ ! -f "$nodesfile" ] && nodesfile=/etc/ace/nodes
+else
+ nodesfile="$PCP_CLUSTER_CONFIG"
+ if [ ! -f "$nodesfile" ]
+ then
+ echo "Error: \"$nodesfile\" specified in \$PCP_CLUSTER_CONFIG: file not found"
+ _usage
+ exit 1
+ fi
+fi
+
+livemode=false
+for f in $*
+do
+ [ $f = "-h" ] && livemode=true
+done
+
+_pmview_args "$@"
+$debug && echo "DEBUG msource=\"$msource\""
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?H:m:v:V" c $otherArgs
+ do
+ case $c
+ in
+ H)
+ nodesfile=$OPTARG
+ if [ ! -f "$nodesfile" ]
+ then
+ _pmview_error "$prog: \"$nodesfile\" for -H file not found"
+ #NOTREACHED
+ fi
+ ;;
+ m)
+ max=$OPTARG
+ if [ "X-$max" != "X`expr 0 + -$max 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -m must have a positive integral argument"
+ #NOTREACHED
+ fi
+ maxreq=`expr $max / 20`
+ ;;
+
+ V)
+ verbose=true
+ ;;
+
+ '?')
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+fi
+
+if [ $numsource -eq 0 ]
+then
+ if [ -f $nodesfile ]
+ then
+ livemode=true
+ sourcelist=`sed -e '/^#/d' $nodesfile`
+ numsource=`echo $sourcelist | wc -w`
+ else
+ _pmview_error "$prog: -H, -a or -h must be given"
+ fi
+fi
+
+$debug && echo DEBUG sourcelist=\"$sourcelist\"
+hostcols=`echo "sqrt($numsource)" | bc`
+$debug && echo hostcols=$hostcols
+
+
+# --- set the window title ---
+#
+if [ -z "$titleArg" ]
+then
+ titleArg="SGI PCP : Cluster Node Activity"
+fi
+
+
+# ---- the real config starts here ---
+# pmview Version 2.1
+#
+cat << end-of-file >> $tmp.pmview
+
+_stackLength 26
+_marginWidth 4
+_marginDepth 4
+
+_colorList net_colors (
+ rgbi:0.8/0.0/0.0
+ rgbi:0.0/0.8/0.8
+ rgbi:1.0/0.5/0.0
+)
+
+_colorList cpu_colors ( red2 blue2 blue2 )
+
+# main grid
+_grid _show (
+
+end-of-file
+
+hostrow=0
+hostcol=0
+for source in $sourcelist
+do
+ if $livemode
+ then
+ host=$source
+ msource="-h $source"
+ else
+ host=`pmdumplog -l $source | $PCP_AWK_PROG '/^Performance/ {print $NF}'`
+ msource="-a $source"
+ fi
+
+ nice=`pmprobe $msource -i kernel.all.cpu.nice | $PCP_AWK_PROG '{print $2; exit}'`
+ if [ "$nice" = 1 ]
+ then
+ nicemetric=kernel.percpu.cpu.nice
+ else
+ nicemetric=""
+ fi
+
+ _pmview_cache_fetch -v \
+ kernel.percpu.cpu.user $nicemetric \
+ network.interface.in.packets \
+ network.interface.out.packets
+
+ # --- how many CPUs on this system? ---
+ #
+ if _pmview_fetch -I kernel.percpu.cpu.user
+ then
+ ncpu=`wc -l <$tmp.pmview_result`
+ else
+ _pmview_fetch_fail "get the number of CPUs"
+ fi
+
+ _pmview_cache_fetch -I network.interface.total.bytes
+
+ # --- how many network interfaces on this system? ---
+ #
+ if _pmview_fetch -I network.interface.in.packets
+ then
+ nnet=`grep -v '^lo' $tmp.pmview_result | wc -l`
+ else
+ _pmview_fetch_fail "get the number of network interfaces"
+ fi
+
+ rows=`echo "sqrt($ncpu + $ncpu + $nnet + $nnet)" | bc`
+ [ $rows -lt 4 ] && rows=4
+ row=0
+ col=0
+
+ echo "# grid for host $host" >>$tmp.pmview
+ echo "_baseHeight 8" >>$tmp.pmview
+ echo "_grid $hostcol $hostrow _hide (" >>$tmp.pmview
+
+ echo " _baseColor rgbi:0.4/0.4/0.6" >>$tmp.pmview
+ echo " _label 0 0 _down _large \"$host\"" >>$tmp.pmview
+ echo " _grid 1 0 _show (" >>$tmp.pmview
+
+ _pmview_fetch -I kernel.percpu.cpu.user
+ for cpu in `cat $tmp.pmview_result`
+ do
+ echo " _label $row $col _west \"$cpu\"" >>$tmp.pmview
+ echo " _stack `expr $row + 1` $col _hide (" >>$tmp.pmview
+ echo " _metrics (" >>$tmp.pmview
+ echo " $host:kernel.percpu.cpu.sys[$cpu] $maxcpu" >>$tmp.pmview
+ if [ ! -z "$nicemetric" ]
+ then
+ echo " $host:kernel.percpu.cpu.nice[$cpu] $maxcpu" >>$tmp.pmview
+ fi
+ echo " $host:kernel.percpu.cpu.user[$cpu] $maxcpu" >>$tmp.pmview
+ echo " )" >>$tmp.pmview
+ echo " _colorlist cpu_colors" >>$tmp.pmview
+ echo " )" >>$tmp.pmview
+
+ $debug && echo stack at row=`expr $row + 1` col=$col \"$cpu\"
+ $debug && echo label at row=$row col=$col
+
+ col=`expr $col + 1`
+ if [ $col -ge $rows ]
+ then
+ col=0
+ row=`expr $row + 2`
+ fi
+ done
+
+ _pmview_fetch -I network.interface.in.packets
+ grep -v '^lo' $tmp.pmview_result >$tmp.net
+ for net in `cat $tmp.net`
+ do
+ echo " _label $row $col _west \"$net\"" >>$tmp.pmview
+ echo " _stack `expr $row + 1` $col _hide (" >>$tmp.pmview
+ echo " _metrics (" >>$tmp.pmview
+ echo " $host:network.interface.total.errors[$net] $max" >>$tmp.pmview
+ echo " $host:network.interface.in.packets[$net] $max" >>$tmp.pmview
+ echo " $host:network.interface.out.packets[$net] $max" >>$tmp.pmview
+ echo " )" >>$tmp.pmview
+ echo " _colorlist net_colors" >>$tmp.pmview
+ echo " )" >>$tmp.pmview
+
+ $debug && echo stack at row=`expr $row + 1` col=$col \"$net\"
+ $debug && echo label at row=$row col=$col
+
+ col=`expr $col + 1`
+ if [ $col -ge $rows ]
+ then
+ col=0
+ row=`expr $row + 2`
+ fi
+
+ done
+ echo " )" >>$tmp.pmview
+ row=`expr $row + 1`
+ echo "# end of host grid" >>$tmp.pmview
+ echo ")" >>$tmp.pmview
+
+ hostcol=`expr $hostcol + 1`
+ if [ $hostcol -ge $hostcols ]
+ then
+ hostcol=0
+ hostrow=`expr $hostrow + 1`
+ fi
+
+done
+
+echo "" >>$tmp.pmview
+echo "# end of main grid" >>$tmp.pmview
+echo ")" >>$tmp.pmview
+
+$verbose && cat $tmp.pmview
+
+eval $PMVIEW <$tmp.pmview $args -title "'$titleArg'" -xrm "'*iconName: $prog'"
+
+exit
+
diff --git a/src/pmview/front-ends/config.clustervis b/src/pmview/front-ends/config.clustervis
new file mode 100644
index 0000000..118cb34
--- /dev/null
+++ b/src/pmview/front-ends/config.clustervis
@@ -0,0 +1,13 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with clustervis(1)
+#
+
+log advisory on default {
+ kernel.percpu.cpu.sys
+ kernel.percpu.cpu.user
+ network.interface.in.packets
+ network.interface.out.packets
+ network.interface.total.bytes
+ network.interface.total.errors
+}
diff --git a/src/pmview/front-ends/config.dkvis b/src/pmview/front-ends/config.dkvis
new file mode 100755
index 0000000..03e0e31
--- /dev/null
+++ b/src/pmview/front-ends/config.dkvis
@@ -0,0 +1,14 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with dkvis(1)
+#
+
+log advisory on default {
+ disk.dev.total
+ disk.dev.read
+ disk.dev.write
+ disk.dev.bytes
+ disk.dev.read_bytes
+ disk.dev.write_bytes
+ disk.dev.total_bytes
+}
diff --git a/src/pmview/front-ends/config.mpvis b/src/pmview/front-ends/config.mpvis
new file mode 100755
index 0000000..f28ce84
--- /dev/null
+++ b/src/pmview/front-ends/config.mpvis
@@ -0,0 +1,13 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with mpvis(1)
+#
+
+log advisory on default {
+ kernel.percpu.cpu.idle
+ kernel.percpu.cpu.intr
+ kernel.percpu.cpu.sys
+ kernel.percpu.cpu.sxbrk
+ kernel.percpu.cpu.user
+ kernel.percpu.cpu.wait.total
+}
diff --git a/src/pmview/front-ends/config.nfsvis b/src/pmview/front-ends/config.nfsvis
new file mode 100755
index 0000000..f8ab0fb
--- /dev/null
+++ b/src/pmview/front-ends/config.nfsvis
@@ -0,0 +1,12 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with nfsvis(1)
+#
+
+log advisory on default {
+ nfs
+}
+
+log advisory on default {
+ nfs3
+}
diff --git a/src/pmview/front-ends/config.osvis b/src/pmview/front-ends/config.osvis
new file mode 100755
index 0000000..629a3a4
--- /dev/null
+++ b/src/pmview/front-ends/config.osvis
@@ -0,0 +1,31 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with osvis(1)
+#
+log mandatory on once {
+ hinv.ncpu
+ hinv.ndisk
+ hinv.physmem
+ mem.physmem
+}
+
+log advisory on default {
+ disk.all.avg_disk.active
+ disk.all.read
+ disk.all.write
+ disk.ctl.avg_disk.active
+ kernel.all.load
+ kernel.all.cpu.intr
+ kernel.all.cpu.sys
+ kernel.all.cpu.user
+ kernel.all.cpu.wait.total
+ mem.freemem
+ mem.util
+ network.interface.in.bytes
+ network.interface.in.packets
+ network.interface.in.errors
+ network.interface.out.bytes
+ network.interface.out.packets
+ network.interface.out.errors
+}
+
diff --git a/src/pmview/front-ends/config.weblogvis b/src/pmview/front-ends/config.weblogvis
new file mode 100755
index 0000000..1d3453f
--- /dev/null
+++ b/src/pmview/front-ends/config.weblogvis
@@ -0,0 +1,20 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with weblogvis(1)
+#
+
+log advisory on default {
+ web.perserver.logidletime
+ web.perserver.requests.total
+ web.perserver.bytes.total
+ web.perserver.requests.size.unknown
+ web.perserver.requests.size.gt3m
+ web.perserver.requests.size.le3m
+ web.perserver.requests.size.le1m
+ web.perserver.requests.size.le300k
+ web.perserver.requests.size.le100k
+ web.perserver.requests.size.le30k
+ web.perserver.requests.size.le10k
+ web.perserver.requests.size.le3k
+ web.perserver.requests.size.zero
+}
diff --git a/src/pmview/front-ends/config.webpingvis b/src/pmview/front-ends/config.webpingvis
new file mode 100755
index 0000000..078ab3c
--- /dev/null
+++ b/src/pmview/front-ends/config.webpingvis
@@ -0,0 +1,8 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with webpingvis(1)
+#
+
+log advisory on default {
+ webpingvis
+}
diff --git a/src/pmview/front-ends/config.webvis b/src/pmview/front-ends/config.webvis
new file mode 100644
index 0000000..08394fc
--- /dev/null
+++ b/src/pmview/front-ends/config.webvis
@@ -0,0 +1,51 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with webvis(1)
+#
+
+# file system and hinv stats
+# (log these once so they _definitely_ exist at start of archive)
+log advisory on once {
+ hinv.ncpu
+ hinv.physmem
+ hinv.ndisk
+ mem.physmem
+ disk.dev.read
+}
+
+log advisory on 60 seconds {
+ # Kernel, disk and swap and paging metrics
+ disk.all.read
+ disk.all.write
+ disk.all.avg_disk.active
+ kernel.all.cpu.idle
+ kernel.all.cpu.intr
+ kernel.all.cpu.sys
+ kernel.all.cpu.user
+ kernel.all.cpu.wait.total
+ mem.freemem
+ mem.util.kernel
+ mem.util.fs_ctl
+ mem.util.fs_dirty
+ mem.util.fs_clean
+ mem.util.user
+ swap.pagesout
+ network.interface.out.drops
+ network.interface.out.errors
+ network.interface.out.packets
+ network.interface.in.drops
+ network.interface.in.errors
+ network.interface.in.packets
+ network.interface.total.bytes
+ # Network data rates and error conditions
+ network.tcp.drops
+ network.tcp.conndrops
+ network.tcp.timeoutdrop
+ network.tcp.sndrexmitpack
+ network.tcp.rcvbadsum
+ network.tcp.rexmttimeo
+ network.mbuf.failed
+ network.mbuf.waited
+ # Web logs - both frequent and infrequent samples
+ web.allservers
+}
diff --git a/src/pmview/front-ends/dkvis b/src/pmview/front-ends/dkvis
new file mode 100755
index 0000000..5cf7267
--- /dev/null
+++ b/src/pmview/front-ends/dkvis
@@ -0,0 +1,572 @@
+#! /bin/sh
+#
+# Copyright (c) 1997-2005 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options] [diskid ...]
+
+options:
+ -b display data throughput (Kbytes/sec) rather than IOPs
+ -m maxrate maximum activity expected (integer)
+ [default 150 IOPs (without -b) or 2048 Kbytes/sec (with -b)]
+ -r display only the read activity
+ -V verbose/diagnostic output
+ -w display only the write activity
+ -X ndisk limit layout to at most this many disks per row, set
+ to 0 for no limit [default 12]
+ -Y nctl limit layout to at most this many controllers per column
+ before starting a new group of controllers, set to 0
+ for no limit [default 16]
+
+pmview(1) options:'
+
+ _pmview_usage >> $tmp.msg
+ echo >> $tmp.msg
+ echo 'Default title is: Total Disk Activity (IOPS) for Host' >> $tmp.msg
+ _pmview_info -f $tmp.msg
+}
+
+verbose=false
+type=total
+Type=Total
+Thru=IOPS
+max=''
+force=false
+maxnctl=16
+maxndisk=12
+diskargs=
+debug=false
+
+# build WM_COMMAND X(1) property for restart after login/logout
+#
+echo -n "pmview Version 2.1 \"dkvis\"" >$tmp.conf
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.conf
+done
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?bdm:R:rv:VX:Y:w" c $otherArgs
+ do
+ case $c
+ in
+ b)
+ Thru="Kbytes/sec"
+ ;;
+ d)
+ debug=true
+ ;;
+ m)
+ _pmview_unsigned $c
+ max=$OPTARG
+ ;;
+ r)
+ if [ $type != total ]
+ then
+ _pmview_error "$prog: only one -r or -w option may be specified"
+ # NOTREACHED
+ fi
+ type=read
+ Type=Read
+ ;;
+
+ v)
+ if [ $OPTARG = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ elif [ $OPTARG != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+
+ V)
+ verbose=true
+ ;;
+ w)
+ if [ $type != total ]
+ then
+ _pmview_error "$prog: only one -r or -w option may be specified"
+ # NOTREACHED
+ fi
+ type=write
+ Type=Write
+ ;;
+ X)
+ _pmview_unsigned $c
+ maxndisk=$OPTARG
+ ;;
+ [YR])
+ # used to be -R, so support both for backwards compatibility
+ _pmview_unsigned $c
+ maxnctl=$OPTARG
+ force=true
+ ;;
+ ?)
+ _usage
+ exit 1
+ ;;
+
+ esac
+ done
+ set -- $otherArgs
+ shift `expr $OPTIND - 1`
+
+ [ $# -gt 0 ] && diskargs=$@
+fi
+
+if [ "$Thru" != "IOPS" ]
+then
+ case $type
+ in
+ read)
+ type=read_bytes
+ ;;
+ write)
+ type=write_bytes
+ ;;
+ *)
+ if pminfo $msource disk.dev.total_bytes >/dev/null 2>&1
+ then
+ type=total_bytes
+ else
+ type=bytes
+ fi
+ ;;
+ esac
+fi
+
+# default max depends on -b or not
+#
+if [ "$Thru" != "IOPS" ]
+then
+ [ -z "$max" ] && max=2048
+else
+ [ -z "$max" ] && max=150
+fi
+
+pminfo -f $msource $namespace disk.dev.$type >$tmp.info 2>$tmp.err
+if [ -s $tmp.err ]
+then
+ cat $tmp.err | _pmview_fetch_mesg >> $tmp.msg
+ echo "$prog: Failed to get disk inventory from host \"$host\"" | fmt >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+fi
+
+$PCP_AWK_PROG < $tmp.info -F'"' '/inst/ { print $2 }' > $tmp.disks
+
+if [ ! -s $tmp.disks ]
+then
+ cat $tmp.info | _pmview_fetch_mesg >> $tmp.msg
+ echo "$prog: Failed to get disk inventory from host \"$host\"" | fmt >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+fi
+
+if [ ! -z "$diskargs" ]
+then
+ rm -f $tmp.tmp $tmp.msg
+ for dk in $diskargs
+ do
+ if echo "$dk" | grep '[.[^]' >/dev/null
+ then
+ # assume egrep(1) regular expression
+ #
+ if egrep "$dk" $tmp.disks >>$tmp.tmp
+ then
+ # found some matches
+ #
+ :
+ else
+ echo "$prog: pattern \"$dk\" does not match any disks ..." >$tmp.msg
+ fi
+ elif grep "^$dk\$" $tmp.disks >/dev/null
+ then
+ echo $dk >>$tmp.tmp
+ else
+ echo "$prog: disk \"$dk\" not in the disk inventory ..." >$tmp.msg
+ fi
+ done
+ if [ -s $tmp.msg ]
+ then
+ echo "Disks on host \"$host\" are:" >> $tmp.msg
+ fmt $tmp.disks | sed -e 's/^/ /' >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+ fi
+ mv $tmp.tmp $tmp.disks
+fi
+
+if $debug
+then
+ echo "Disks ..."
+ cat $tmp.disks
+fi
+
+ndisk=`wc -l <$tmp.disks | sed -e 's/ //g'`
+
+if [ "$ndisk" -lt 1 ]
+then
+ echo "$prog: Cannot get disk inventory for host \"$host\"\n" > $tmp.msg
+ cat $tmp.info >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+fi
+
+cat << end-of-file >> $tmp.conf
+
+#
+# dkvis
+#
+end-of-file
+
+if $verbose
+then
+ echo "# Disk Inventory:" >> $tmp.conf
+ fmt <$tmp.disks | sed -e 's/^/# /' >> $tmp.conf
+fi
+cp $tmp.disks $tmp.in
+
+# get controller-based order
+#
+# the mapping is controlled by the here-is document below, where each
+# (non-comment) line contains three fields separated by tabs:
+# 1. pattern to match disk names (must match the start of a disk indom name)
+# - don't bother escaping / (fixed up later)
+# - <n> is expanded to \([0-9][0-9]*\) later
+# - <h> is expanded to \([0-9a-f][0-9a-f]*\) later
+# 2. controller-tag ... construction from literals and substrings (in sed
+# syntax, so \1, \2, etc) from the pattern
+# 3. sort field order ... constructed from the ordinal labels of the
+# substrings in the pattern (comma separated) ... "n" is appended
+# for numerical sorting
+#
+# so the control line
+# dks<n>d<n>l*\([0-9]*\) dks\1 1n,2n,3n
+#
+# will first turn disk indom names like dks14d3, dks14d3l2, dks14d3l10,
+# dks14d2, dks10d7, dks10d10 and dks10d1 into records like
+#
+# dks14 14 3 dks14d3
+# dks14 14 3 2 dks14d3l2
+# dks14 14 3 10 dks14d3l10
+# dks14 14 2 dks14d2
+# dks10 10 7 dks10d7
+# dks10 10 1 10 dks10d110
+# dks10 10 1 dks10d1
+# --+-- -+ -+ -+ ----+----
+# | | | | |
+# | | | | +-- full disk name
+# | | | +-- 3rd sort key (lun, may be missing)
+# | | +-- 2nd sort key (target)
+# | +-- 1st sort key (controller)
+# +-- controller-tag for dkvis scene and used for grouping "related"
+# disks
+#
+# and generate a sort(1) key of the form "+1n -2 +2n -3 +3n -4"
+#
+# after sorting this list becomes
+#
+# dks10 10 1 dks10d1
+# dks10 10 1 10 dks10d110
+# dks10 10 7 dks10d7
+# dks14 14 2 dks14d2
+# dks14 14 3 dks14d3
+# dks14 14 3 2 dks14d3l2
+# dks14 14 3 10 dks14d3l10
+#
+# and after grouping based on the common controller-tag and stripping
+# the sort fields this becomes
+#
+# dks10 dks10d1 dks10d110 dks10d7
+# dks14 dks14d2 dks14d3 dks14d3l2 dks14d3l10
+#
+sed >$tmp.ctl <<'End-of-File' \
+ -e '/^#/d' \
+ -e 's/ */ /g' \
+ -e 's/\//\\\//g' \
+ -e 's/<n>/\\([0-9][0-9]*\\)/g' \
+ -e 's/<h>/\\([0-9a-f][0-9a-f]*\\)/g' \
+ -e 's/^/^/'
+# Linux 2.2, no sard, IDE and SCSI
+sd\([a-z]\)+hd\([abcd]\) sd+hd 1
+# Linux IDE, no devfs
+hd\([abcd]\) hd 1
+# Linux IDE, with devfs
+ide/host<n>/bus<n>/target<n>/lun<n> ide\1b\2 1n,2n,3n,4n
+# Linux SCSI, no devfs
+sd\([a-z]\) sd 1
+# Linux XSCSI, dual port HBA, with devfs
+# e.g. xscsi/pci00.01.0-1/target2/lun0/disc (and similar for fabric device)
+xscsi/pci<h>\.<h>\.<n>-<n>/target<n>/lun<n> xscsi\1.\2 1,2,3n,4n,5n,6n
+xscsi/pci<h>\.<h>\.<n>-<n>/node<h>/lun<n> xscsi\1.\2 1,2,3n,4n,5,6n
+# Linux XSCSI, single port HBA, with devfs
+# e.g. xscsi/pci05.01.0/target2/lun0/disc (and similar for fabric device)
+xscsi/pci<h>\.<h>\.<n>/target<n>/lun<n> xscsi\1.\2 1,2,3n,4n,5n
+xscsi/pci<h>\.<h>\.<n>/node<h>/lun<n> xscsi\1.\2 1,2,3n,4,5n
+# Linux SCSI, with devfs
+scsi/host<n>/bus<n>/target<n>/lun<n> scsi\1b\2 1n,2n,3n,4n
+# Linux Mylex RAID, no devfs
+rd/c<n>d<n> dac 1n,2n
+# Linux Mylex RAID, with devfs (old style)
+dac960/c<n>d<n> dac 1n,2n
+# Linux Mylex RAID, with devfs (new style)
+dac960/host<n>/disc<n> dac 1n,2n
+# IRIX Firewire
+# two name formats: first is IRIX before 6.5.11, second is 6.5.11 or later
+/hw/rdisk/1394/\([^/]*\)/lun<n>vol/c<n>p<n> 1394c\3 3n,2n,1,2n
+1394/\([^/]*\)/lun<n>vol/c<n>p<n> 1394c\3 3n,2n,1,2n
+# IRIX SCSI, note l<n> is missing for LUN 0, so pattern is a little different
+# at the end
+dks<n>d<n>l*\([0-9]*\) dks\1 1n,2n,3n
+# IRIX FC
+\(................\)/lun<n>/c<n>p<n> fc\3p\4 3n,4n,1,2n
+# Linux direct attach xscsi
+# e.g. xscsi/pci15.01.0-2/target4/lun0/disc
+xscsi/pci<n>\.\(..\)\.\(.*\)/target<n>/lun<n> xscsi\1b\2 1n,2,3,4n,5n
+# Linux fabric attach xscsi
+# e.g. xscsi/pci04.01.0/node50060946700083e9/port1/lun0/disc
+xscsi/pci<n>\.\(..\)\.\(.*\)/node\(................\)/port<n>/lun<n> xfc\1b\2 1n,2,3,4,5n,6n
+# Linux IDA, with devfs
+ida/disc<n> ida 1n
+# Old style IRIX Jaguar drives
+jag<n>d<n> jag\1 1n,2n
+# Old style IRIX RAID drives
+rad<n>d<n> rad\1 1n,2n
+End-of-File
+
+if $debug
+then
+ echo "Control lines ..."
+ cat $tmp.ctl
+fi
+
+nctl=`wc -l <$tmp.ctl | sed -e 's/ //g'`
+i=1
+
+# loop once per contol line in $tmp.ctl ...
+# - select matching disks
+# - generate the sort keys with the disk names
+# - sort and group by the controller-tag
+# - remove the matching lists from consideration
+#
+while [ $i -le $nctl ]
+do
+ $PCP_AWK_PROG -F' ' <$tmp.ctl '
+NR == '$i' { print "/" $1 "/p" >"'$tmp.sed-in'"
+ print "/" $1 "/!p" >"'$tmp.sed-out'"
+ nfld = split($3,fld,/,/)
+ maxfld = 1
+ for (i = 1; i <= nfld; i++) {
+ if (fld[i] > maxfld) maxfld = fld[i]
+ printf "+%s -%d ",fld[i],fld[i]+1 >"'$tmp.sort-arg'"
+ }
+ print "" >"'$tmp.sort-arg'"
+ printf "%s","s/" $1 "/" $2 >"'$tmp.sed-key'"
+ for (i = 1; i <= maxfld; i++) {
+ printf " \\%d",i >"'$tmp.sed-key'"
+ }
+ print " &/" >"'$tmp.sed-key'"
+ exit
+ }'
+
+ sed -n -f $tmp.sed-in <$tmp.in \
+ | sed -f $tmp.sed-key >$tmp.key
+ sort `cat $tmp.sort-arg` $tmp.key \
+ | $PCP_AWK_PROG >>$tmp.order '
+BEGIN { ctl = "" }
+$1 != ctl { if (NR > 1) print ""
+ ctl = $1
+ ndisk = 0
+ printf "%s",ctl
+ }
+ { ndisk++
+ if ('"$maxndisk"' > 0 && ndisk > '"$maxndisk"') {
+ print ""
+ printf "%s",ctl
+ ndisk = 1
+ }
+ printf " %s",$NF
+ }
+END { if (NR > 0) print "" }'
+ sed -n -f $tmp.sed-out <$tmp.in >$tmp.out
+ mv $tmp.out $tmp.in
+
+ i=`expr $i + 1`
+done
+
+# any leftovers do not match any control pattern
+#
+if [ -s $tmp.in ]
+then
+ echo "$prog: The following disk names do not match a known controller pattern," >$tmp.warn
+ echo "and they will be ungrouped in the scene:" >>$tmp.warn
+ fmt <$tmp.in | sed -e 's/^/ /' >>$tmp.warn
+ _pmview_warning -f $tmp.warn
+ sed -e 's/.*/& &/' <$tmp.in >>$tmp.order
+fi
+
+nctl=`wc -l <$tmp.order | sed -e 's/ //g'`
+
+# shape the base geometry for the scene ... there are groups, each with
+# $maxnctl controller rows, and the groups are arranged in a grid that
+# is $nrow groups deep and $ncol groups across
+#
+if [ $nctl -le $maxnctl ]
+then
+ # less than $maxnctl controller rows, so just one group
+ #
+ ncol=1
+ nrow=1
+else
+ # have some shaping to do ... assume each group is $maxnctl controller
+ # rows deep and as wide as the maximum number of disks per controller
+ # row, then square up the scene and maybe adjust $maxnctl
+ #
+ eval `$PCP_AWK_PROG <$tmp.order '
+START { maxdk = 0 }
+ { if (NF - 1 > maxdk) maxdk = NF - 1 }
+END {
+ if ('"$nctl"' % "'$maxnctl'" == 0)
+ ngrp = '"$nctl"' / "'$maxnctl'"
+ else
+ ngrp = int('"$nctl"' / "'$maxnctl'") + 1
+ # add 2 to maxdk as an estimate of the label length in units of
+ # displayed blocks, i.e. the label is about as long as the width
+ # of 2 blocks
+ ncol = int(0.5 + sqrt(ngrp)*'"$maxnctl"'/(maxdk + 2))
+ if (ncol < 1) ncol = 1
+ if (ngrp % ncol == 0)
+ nrow = ngrp / ncol
+ else
+ nrow = int(ngrp / ncol) + 1
+ # use all of the space in the base layout
+ ngrp = nrow * ncol
+ # make all the groups have the same number of controller rows
+ if ('"$nctl"' % ngrp == 0)
+ maxnctl = '"$nctl"' / ngrp
+ else
+ maxnctl = int('"$nctl"' / ngrp) + 1
+ print "ncol=" ncol " nrow=" nrow " maxnctl=" maxnctl
+ }'`
+fi
+
+#DEBUG echo "nctl=$nctl maxnctl=$maxnctl ncol=$ncol nrow=$nrow"
+
+# heuristic hack for pmlaunch
+#
+if [ "$nctl" -gt 6 ]
+then
+ group="_groupByInst"
+else
+ group="_groupByMetric"
+fi
+
+if [ -z "$titleArg" ]
+then
+ titleArg="$Type Disk Activity ($Thru) for Host $host"
+fi
+
+#
+# pmview 2.0
+#
+
+echo '
+_grid (' >> $tmp.conf
+
+$PCP_AWK_PROG -v io=$Type -v max=$max -v group=$group -v thru="$Thru" <$tmp.order '
+BEGIN { row = 0; col = 0; cnt = 0; type = ""; ctl = ""
+ start_ctl = ""; label = ""; last_label = ""; last_ctl = ""
+ color[0] = "green"
+ color[1] = "blue"
+ color[2] = "red"
+ color[3] = "cyan"
+ color[4] = "violet"
+ color[5] = "yellow"
+ ncol = 5
+ colorlist = ""
+ }
+
+function dumpLabel(start, last)
+{
+ printf(" _baseLabel \"%s Activity for Disks on ", io)
+ if (start != last)
+ printf("Controllers %s to %s", start, last)
+ else
+ printf("Controller %s", start)
+ printf("\\nNormalized to %s %s\"\n", max, thru)
+ printf(" _colorlist (%s )\n", colorlist )
+ colorlist = ""
+}
+
+ { if (cnt % '"$maxnctl"' == 0) {
+ if (cnt > 0) {
+ print " )"
+ dumpLabel(start_ctl, last_ctl)
+ print " )"
+ }
+ printf("\n _bar %d %d north %s (\n", 2*col, 2*row, group)
+ print " _metrics ("
+ start_ctl = $1
+ row++
+ if (row >= '"$nrow"') {
+ col++
+ row = 0
+ }
+ }
+ printf(" disk.dev.'$type'[")
+
+ for (d = 2; d <= NF; d++) {
+ if (d == 2)
+ printf("%s", $d)
+ else
+ printf(",%s", $d)
+ }
+ printf("] %s \"%s\"\n", max, $1)
+ if ($1 != last_ctl) {
+ # new controller, change colors
+ ncol++
+ if (ncol > 5)
+ ncol = 0
+ }
+ colorlist = colorlist " " color[ncol]
+ last_ctl = $1
+ cnt++
+ }
+END { if (cnt > 0) {
+ print " )"
+ dumpLabel(start_ctl, last_ctl)
+ print " )"
+ }
+ print ")"
+ }' >> $tmp.conf
+
+$verbose && cat $tmp.conf
+
+eval $PMVIEW <$tmp.conf $args -title "'$titleArg'" # -xrm "'*iconName:dkvis'"
+
+exit
diff --git a/src/pmview/front-ends/mpvis b/src/pmview/front-ends/mpvis
new file mode 100755
index 0000000..dd7db78
--- /dev/null
+++ b/src/pmview/front-ends/mpvis
@@ -0,0 +1,452 @@
+#!/bin/sh
+# Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+gridspace=120
+cpuargs=
+
+algorithm="k"
+default_layout=true
+force=false
+maxrowlen=16
+verbose=false
+showinst=false
+version=2
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: mpvis [options] [cpuid...]
+
+options:
+ -b use row:column ratio of 1:8 (soft limit)
+ [default, if 64 or more CPUs]
+ -i show CPU numbers
+ -r rowlen maximum number of CPUs per row (soft limit)
+ [default 16, if less than 64 CPUs]
+ -R rowlen force this number of CPUs per row
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+
+ _pmview_usage >>$tmp.msg
+ echo >>$tmp.msg
+ echo 'Default title is: CPU Utilization for Host' >>$tmp.msg
+ _pmview_info -f $tmp.msg
+}
+
+# generate one row of the scene
+#
+_do_row()
+{
+if [ "$1" = "$2" ]
+then
+ msg="$titleArg\n$1 only"
+else
+ msg="$titleArg\n$1 to $2"
+fi
+
+cat <<End-of-File >>$tmp.conf
+ _grid 0 $3 show (
+ _baseLabel "$msg"
+ _bar $group (
+ _metrics (
+End-of-File
+$have_idle && echo " kernel.percpu.cpu.idle[$rowlist] $max_util \"idle\"" >>$tmp.conf
+$have_wait && echo " kernel.percpu.cpu.wait.total[$rowlist] $max_util \"wait\"" >>$tmp.conf
+$have_intr && echo " kernel.percpu.cpu.intr[$rowlist] $max_util \"intr\"" >>$tmp.conf
+$have_nice && echo " kernel.percpu.cpu.nice[$rowlist] $max_util \"nice\"" >>$tmp.conf
+$have_sys && echo " kernel.percpu.cpu.sys[$rowlist] $max_util \"sys\"" >>$tmp.conf
+$have_user && echo " kernel.percpu.cpu.user[$rowlist] $max_util \"user\"" >>$tmp.conf
+cat <<End-of-File >>$tmp.conf
+ )
+End-of-File
+$showinst && echo " _instlabels away ( $labels )" >>$tmp.conf
+cat <<End-of-File >>$tmp.conf
+ _colorlist cpu
+ _baseLabel "$msg"
+ )
+ )
+End-of-File
+}
+
+# build WM_COMMAND X(1) property for restart after login/logout
+#
+echo -n "pmview Version 2.1 \"mpvis\"" >$tmp.conf
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.conf
+done
+
+_pmview_args "$@"
+
+if [ "X$otherArgs" != X ]
+then
+ while getopts "bir:R:v:V?" c $otherArgs
+ do
+ case $c
+ in
+ b)
+ algorithm="b"
+ default_layout=false
+ ;;
+ i)
+ showinst=true
+ gridspace=60
+ ;;
+ r)
+ _pmview_unsigned $c
+ maxrowlen=$OPTARG
+ default_layout=false
+ ;;
+ R)
+ _pmview_unsigned $c
+ maxrowlen=$OPTARG
+ default_layout=false
+ force=true
+ ;;
+
+ v)
+ version=$OPTARG
+ if [ $version = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ version=2
+ elif [ $version != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+
+ V)
+ verbose=true
+ ;;
+ ?)
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+ set -- $otherArgs
+ shift `expr $OPTIND - 1`
+
+ [ $# -gt 0 ] && cpuargs=$@
+fi
+
+[ -z "$titleArg" ] && titleArg="SGI PCP : CPU Utilization for Host $host"
+
+_pmview_cache_fetch -I kernel.percpu.cpu.user
+_pmview_cache_fetch -v kernel.percpu.cpu.idle \
+ kernel.percpu.cpu.wait.total \
+ kernel.percpu.cpu.intr \
+ kernel.percpu.cpu.nice \
+ kernel.percpu.cpu.sys \
+ kernel.percpu.cpu.user
+
+
+# Check that we can get the metrics
+#
+if _pmview_fetch_indom kernel.percpu.cpu.user
+then
+ if [ ! -s "$tmp.pmview_result" -o "$number" -lt 1 ]
+ then
+ _pmview_fetch_fail "get CPU inventory"
+ fi
+else
+ _pmview_fetch_fail "get CPU inventory"
+ # NOTREACHED
+fi
+
+if [ ! -z "$cpuargs" ]
+then
+ # restrict based on command line args
+ #
+ rm -f $tmp.tmp $tmp.msg
+ ncpu=0
+ for cpu in $cpuargs
+ do
+ if echo "$cpu" | grep '[.[^]' >/dev/null
+ then
+ # assume egrep(1) regular expression
+ #
+ if egrep "$cpu" $tmp.pmview_result >>$tmp.tmp
+ then
+ # found some matches
+ #
+ :
+ else
+ echo "$prog: pattern \"$cpu\" does not match any CPUs ..." >$tmp.msg
+ fi
+ elif grep "^$cpu\$" $tmp.pmview_result >/dev/null
+ then
+ echo $cpu >>$tmp.tmp
+ else
+ echo "$prog: CPU \"$cpu\" not in the CPU inventory" >$tmp.msg
+ fi
+ done
+ if [ -s $tmp.msg ]
+ then
+ echo "CPUs on host \"$host\" are:" >> $tmp.msg
+ tr < $tmp.pmview_result '\012' ' ' | fmt | sed -e "s/^/ /" >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+ fi
+ sort $tmp.tmp | uniq > $tmp.pmview_result
+ ncpu=`wc -l $tmp.pmview_result | $PCP_AWK_PROG '{print $1}'`
+else
+ ncpu=$number
+fi
+
+if [ "$ncpu" -ge 64 -a "$default_layout" = true ]
+then
+ # >= 64p, no -b, -r or -R options ... make -b the default
+ #
+ algorithm="b"
+fi
+
+# sort list
+#
+if grep cpu: $tmp.pmview_result >/dev/null
+then
+ # Origin series name style
+ sed -e 's/:/./' < $tmp.pmview_result \
+ | sort -t. +1n -2 +2n -3 +3 -4 \
+ | sed -e 's/\./:/' \
+ > $tmp.cpulist
+else
+ # CPU names for older systems
+ sed -e 's/cpu/cpu./' < $tmp.pmview_result \
+ | sort -t. +1n -2 \
+ | sed -e 's/\.//' \
+ > $tmp.cpulist
+fi
+
+scale=''
+have_idle=false
+if _pmview_fetch_values kernel.percpu.cpu.idle
+then
+ have_idle=true
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.idle| sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+have_wait=false
+if _pmview_fetch_values kernel.percpu.cpu.wait.total
+then
+ have_wait=true
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.wait.total | sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+have_intr=false
+if _pmview_fetch_values kernel.percpu.cpu.intr
+then
+# linux 2.6 has wait and intr, but 2.4 does not
+ have_intr=`$PCP_AWK_PROG -v found=false '
+ $1 > 0 { found="true" }
+ END { print found }' $tmp.pmview_result`
+ have_wait=$have_intr
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.intr | sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+have_nice=false
+if _pmview_fetch_values kernel.percpu.cpu.nice
+then
+ have_nice=true
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.nice | sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+have_sys=false
+if _pmview_fetch_values kernel.percpu.cpu.sys
+then
+ have_sys=true
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.sys | sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+have_user=false
+if _pmview_fetch_values kernel.percpu.cpu.user
+then
+ have_user=true
+ [ -z "$scale" ] && scale=`pminfo $namespace $msource -d kernel.percpu.cpu.user | sed -n '/Semantics:/s/.*Units: //p'`
+fi
+
+case $scale
+in
+ microsec)
+ max_util=1000000
+ ;;
+ millisec)
+ max_util=1000
+ ;;
+ *)
+ _pmview_warning "$prog: cannot determine CPU time units, assuming milliseconds"
+ max_util=1000
+ ;;
+esac
+
+# shape the base geometry for the scene
+#
+if [ $ncpu -le "$maxrowlen" ]
+then
+ nrows=1
+ ncols=$ncpu
+elif $force
+then
+ nrows=`echo $ncpu $maxrowlen | $PCP_AWK_PROG ' \
+ { x = $1 / $2; y = $1 % $2; if (y > 0) ++x; printf "%d\n", x; }'`
+ ncols=$maxrowlen
+else
+ case $algorithm in
+ a) # this algorithm doesn't work at the moment
+ # (the exit condition is not robust enough)
+ nrows=1
+ ncols=1
+ bound=1
+ num=0
+ while [ $num -gt $ncols -o $num -lt $bound ]
+ do
+ nrows=`expr $nrows \* 2`
+ ncols=`expr $ncpu / $nrows`
+ bound=`expr $ncols / 2`
+ num=`expr $nrows \* 4`
+ done
+ ncols=`echo $ncpu $nrows | $PCP_AWK_PROG ' { x = $1 / $2; y = $1 % $2; \
+ if (y > 0) ++x; printf "%d\n", x }'`
+ ;;
+ b)
+ # use a ratio for rows:columns of 1:8
+ #
+ nrows=`echo $ncpu | $PCP_AWK_PROG ' { x = sqrt ($1 / 8.0);
+ y = int (x); if (y < x) ++y; print y }'`
+ ncols=`expr $ncpu + $nrows - 1`
+ ncols=`expr $ncols / $nrows`
+ ;;
+ k)
+ nrows=`expr $ncpu + $maxrowlen - 1`
+ nrows=`expr $nrows / $maxrowlen`
+ ncols=`expr $ncpu + $nrows - 1`
+ ncols=`expr $ncols / $nrows`
+ esac
+fi
+
+if [ "$ncols" -gt 6 ]
+then
+ group="_groupByMetric"
+else
+ group="_groupByInst"
+fi
+
+cat <<End-of-File >>$tmp.conf
+
+#
+# mpvis
+#
+# ncpus = $ncpu
+# nrows = $nrows
+# ncols = $ncols
+#
+# List:
+End-of-File
+
+col=0
+rowlist=""
+cat $tmp.cpulist | while read cpu
+do
+ if [ $col -eq 0 ]
+ then
+ echo -n "$cpu " > $tmp.rowlist
+ else
+ echo -n "$cpu " >> $tmp.rowlist
+ fi
+ col=`expr $col + 1`
+ if [ "$col" -eq $ncols ]
+ then
+ echo "# "`cat $tmp.rowlist` >>$tmp.conf
+ col=0
+ rm -f $tmp.rowlist
+ fi
+done
+
+[ -s $tmp.rowlist ] && echo "# "`cat $tmp.rowlist` >>$tmp.conf
+
+echo "_gridSpace $gridspace" >>$tmp.conf
+echo >>$tmp.conf
+
+colorlist="_colorlist cpu ("
+$have_idle && colorlist="$colorlist green2"
+$have_wait && colorlist="$colorlist cyan2"
+$have_intr && colorlist="$colorlist yellow2"
+$have_nice && colorlist="$colorlist rgbi:0.6/1.0/0.7"
+$have_sys && colorlist="$colorlist red2"
+$have_user && colorlist="$colorlist blue2"
+colorlist="$colorlist )"
+
+echo "$colorlist" >>$tmp.conf
+echo "_grid 0 0 _hide ( # outer grid" >>$tmp.conf
+
+# build rows from front-to-back of scene
+# fill rows with CPUs from left-to-right
+#
+y=`expr $nrows \* 2 - 2`
+col=0
+rowlist=""
+labels=""
+cat $tmp.cpulist | while read cpu
+do
+ if [ $col -eq 0 ]
+ then
+ rowlist=$cpu
+ start=$cpu
+ else
+ rowlist="$rowlist,$cpu"
+ fi
+ $showinst && labels="$labels \"`echo $cpu | sed -e 's/cpu:*//'`\""
+ col=`expr $col + 1`
+ echo "$start $cpu $y $rowlist $labels" > $tmp.rowlist
+ if [ $col -eq $ncols ]
+ then
+ _do_row $start $cpu $y
+ col=0
+ echo -n "" > $tmp.rowlist
+ labels=""
+ y=`expr $y - 2`
+ fi
+done
+
+if [ -s $tmp.rowlist ]
+then
+ read start cpu y rowlist labels < $tmp.rowlist
+ # cat $tmp.rowlist
+ _do_row $start $cpu $y
+fi
+
+echo ")" >>$tmp.conf
+
+if [ $nrows -eq 1 ]
+then
+ # remove unnecessary _grid for a single row
+ #
+ sed -e '/^ _grid/d' -e '/^ )/d' <$tmp.conf >$tmp.tmp
+ mv $tmp.tmp $tmp.conf
+fi
+
+$verbose && cat $tmp.conf
+
+eval $PMVIEW <$tmp.conf $args -title "'$titleArg'" -xrm "'*iconName:mpvis'"
+
+exit
diff --git a/src/pmview/front-ends/nfsvis b/src/pmview/front-ends/nfsvis
new file mode 100755
index 0000000..26b87ae
--- /dev/null
+++ b/src/pmview/front-ends/nfsvis
@@ -0,0 +1,244 @@
+#! /bin/sh
+# Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options]
+
+options:
+ -c version Monitor NFS version (integer) client metrics [default 2]
+ -m maxrate maximum request rate expected (integer) [default 120]
+ -s version Monitor NFS version (integer) server metrics [default 2]
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+
+ _pmview_usage >>$tmp.msg
+ echo >>$tmp.msg
+ echo 'Default title is: NFS Version 2 Request Traffic for host' >>$tmp.msg
+ _pmview_info -f $tmp.msg
+}
+
+max=120
+client=2
+server=2
+type=total
+Type=Total
+verbose=false
+version=2
+
+# build WM_COMMAND X(1) property for restart after login/logout
+#
+echo -n "pmview Version 2.1 \"nfsvis\"" >$tmp.conf
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.conf
+done
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?c:m:s:v:V" c $otherArgs
+ do
+ case $c
+ in
+ c)
+ client=$OPTARG
+ if [ "$client" != 2 -a "$client" != 3 ]
+ then
+ _pmview_error "$prog: only NFS 2 and NFS 3 client metrics supported"
+ # NOTREACHED
+ fi
+ ;;
+ m)
+ _pmview_unsigned $c
+ max=$OPTARG
+ ;;
+ s)
+ server=$OPTARG
+ if [ "$server" != 2 -a "$server" != 3 ]
+ then
+ _pmview_error "$prog: only NFS 2 and NFS 3 server metrics supported"
+ # NOTREACHED
+ fi
+ ;;
+
+ v)
+ version=$OPTARG
+ if [ $version = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ version=2
+ elif [ $version != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+
+ V)
+ verbose=true
+ ;;
+ ?)
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+ set - $otherArgs
+ shift `expr $OPTIND - 1`
+ if [ $# -gt 0 ]
+ then
+ _usage
+ exit 1
+ fi
+fi
+
+if [ "$client" = "2" ]
+then
+ # NFS V2 client stats
+ #
+ if _pmview_fetch_indom nfs.client.reqs
+ then
+ :
+ else
+ _pmview_fetch_fail "get NFS Version 2 client metrics"
+ # NOTREACHED
+ fi
+else
+ # NFS V3 client stats
+ #
+ if _pmview_fetch_indom nfs3.client.reqs
+ then
+ :
+ else
+ _pmview_fetch_fail "get NFS Version 3 client metrics"
+ # NOTREACHED
+ fi
+fi
+
+# handle fsstat alias statfs
+#
+c_statfs=statfs
+grep fsstat $tmp.pmview_result >/dev/null && c_statfs=fsstat
+
+if [ "$server" = "2" ]
+then
+ # NFS V2 server stats
+ #
+ if _pmview_fetch_indom nfs.server.reqs
+ then
+ :
+ else
+ _pmview_fetch_fail "get NFS Version 2 server metrics"
+ # NOTREACHED
+ fi
+else
+ # NFS V3 server stats
+ #
+ if _pmview_fetch_indom nfs3.server.reqs
+ then
+ :
+ else
+ _pmview_fetch_fail "get NFS Verion 3 server metrics"
+ # NOTREACHED
+ fi
+fi
+
+# handle fsstat alias statfs
+#
+s_statfs=statfs
+grep fsstat $tmp.pmview_result >/dev/null && s_statfs=fsstat
+
+if [ -z "$titleArg" ]
+then
+ titleArg="SGI PCP : NFS Client V$client & Server V$server Request Traffic for host $host"
+fi
+
+
+cat << End-of-File >> $tmp.conf
+
+#
+# nfsvis
+#
+_colorlist colors (red1 green1 blue1)
+_grid hide (
+ _label 2 0 _down _large "Client"
+ _bar 0 0 _east _groupByMetric (
+ _metrics (
+End-of-File
+
+if [ "$client" = "2" ]
+then
+ cat << End-of-File >> $tmp.conf
+ nfs.client.reqs[create,remove,rename,link,symlink,mkdir,rmdir] $max "dir"
+ nfs.client.reqs[getattr,setattr,lookup,readdir,$c_statfs,root] $max "attr"
+ nfs.client.reqs[readlink,read,write,wrcache] $max "data"
+ )
+ _baseLabel "Requests by NFS2 Client\nNormalized to $max requests / second"
+End-of-File
+else
+ cat << End-of-File >> $tmp.conf
+ nfs3.client.reqs[create,remove,rename,link,symlink,mkdir,rmdir,mknod] $max "dir"
+ nfs3.client.reqs[getattr,setattr,lookup,readdir,$c_statfs,access,readdir+,fsinfo,pathconf] $max "attr"
+ nfs3.client.reqs[readlink,read,write,commit] $max "data"
+ )
+ _baseLabel "Requests by NFS3 Client\nNormalized to $max requests / second"
+End-of-File
+fi
+cat << End-of-File >> $tmp.conf
+ _colorlist colors
+ )
+ _label 2 2 _down _large "Server"
+ _bar 0 2 _east (
+ _metrics (
+End-of-File
+if [ "$server" = "2" ]
+then
+ cat << End-of-File >> $tmp.conf
+ nfs.server.reqs[create,remove,rename,link,symlink,mkdir,rmdir] $max "dir"
+ nfs.server.reqs[getattr,setattr,lookup,readdir,$s_statfs,root] $max "attr"
+ nfs.server.reqs[readlink,read,write,wrcache] $max "data"
+ )
+ _baseLabel "Requests to NFS2 Server\nNormalized to $max requests / second"
+End-of-File
+else
+ cat << End-of-File >> $tmp.conf
+ nfs3.server.reqs[create,remove,rename,link,symlink,mkdir,rmdir,mknod] $max "dir"
+ nfs3.server.reqs[getattr,setattr,lookup,readdir,$s_statfs,access,readdir+,fsinfo,pathconf] $max "attr"
+ nfs3.server.reqs[readlink,read,write,commit] $max "data"
+ )
+ _baseLabel "Requests to NFS3 Server\nNormalized to $max requests / second"
+End-of-File
+fi
+
+cat << End-of-File >> $tmp.conf
+ _colorlist colors
+ )
+)
+End-of-File
+
+$verbose && cat $tmp.conf
+
+eval $PMVIEW <$tmp.conf $args -title "'$titleArg'" -xrm "'*iconName:nfsvis'"
+
+exit
diff --git a/src/pmview/front-ends/osvis b/src/pmview/front-ends/osvis
new file mode 100644
index 0000000..a704446
--- /dev/null
+++ b/src/pmview/front-ends/osvis
@@ -0,0 +1,651 @@
+#! /bin/sh
+# Copyright (c) 1995-2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+#
+# scaling parameters
+#
+
+# maximum network packets per second
+maxpack=750
+
+# maximum error packets per second
+maxerr=`expr $maxpack / 100`
+
+# maximum network bytes per second
+maxbyte=65536
+
+# maximum disk io rate (I/O operations per second)
+maxio=100
+
+# milliseconds per CPU
+maxcpu=1000
+
+# maximum disk activity
+maxdisk=30
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options] [interface [interface ...]]
+
+options:
+ -b bytes maximum expected network throughput [default 65536 bytes]
+ -d activity maximum expected disk activity as a percentage [default 30]
+ -i ops maximum expected I/O operations per seconds [default 100]
+ -m packets maximum expected packets sent or received per sec [default 750]
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+ _pmview_usage >>$tmp.msg
+ echo >> $tmp.msg
+ echo 'Default title is: High-Level Activity for Host' >> $tmp.msg
+
+ echo >>$tmp.msg '
+ By default all network interfaces are shown, with a maximum packet rate
+ of '$maxpack' packets per second and error rate of '$maxerr' packets per second.
+
+ If given, the [interface [interface ...]] regular expressions restrict
+ the network statistics displayed to matching network interface names only.'
+
+ _pmview_info -f $tmp.msg
+}
+
+argInterfaces=""
+verbose=false
+interfaces=""
+
+# build WM_COMMAND X(1) property for restart after login/logout
+#
+echo -n "pmview Version 2.1 \"osvis\"" >$tmp.conf
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.conf
+done
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?b:d:i:m:r:v:V" c $otherArgs
+ do
+ case $c
+ in
+
+ b)
+ _pmview_unsigned $c
+ maxbyte=$OPTARG
+ ;;
+
+ d)
+ _pmview_unsigned $c
+ maxdisk=$OPTARG
+ ;;
+
+ i)
+ _pmview_unsigned $c
+ maxio=$OPTARG
+ ;;
+
+ m)
+ _pmview_unsigned $c
+ maxpack=$OPTARG
+ ;;
+
+ V)
+ verbose=true
+ ;;
+
+ '?')
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+
+ set -- $otherArgs
+ shift `expr $OPTIND - 1`
+ if [ $# -gt 0 ]
+ then
+ argInterfaces="$*"
+ fi
+fi
+
+cat << end-of-file >> $tmp.conf
+
+#
+# osvis
+#
+end-of-file
+
+# maximum req error rate (default: 1% of packet rate)
+maxerr=`expr $maxpack / 100`
+[ "$maxerr" -eq 0 ] && maxerr=1
+
+_pmview_cache_fetch -v hinv.ncpu \
+ hinv.ndisk \
+ disk.all.avg_disk.active \
+ mem.util \
+ hinv.physmem \
+ mem.physmem \
+ kernel.all.cpu.wait.total \
+ kernel.all.cpu.intr \
+ kernel.all.cpu.nice \
+ kernel.all.cpu.sys \
+ kernel.all.cpu.user
+
+_pmview_cache_fetch -I network.interface.in.bytes \
+ disk.ctl.avg_disk.active
+
+if _pmview_fetch_values hinv.ncpu
+then
+ ncpu=`cat $tmp.pmview_result`
+ maxcpu=`expr $maxcpu \* $ncpu`
+ maxload=`expr $ncpu \* 2`
+else
+ _pmview_fetch_fail "get the number of CPUs"
+fi
+
+if [ $ncpu -eq 1 ]
+then
+ cpudesc="1 CPU"
+else
+ cpudesc="$ncpu CPUs"
+fi
+
+$verbose && echo "# $cpudesc detected" >> $tmp.conf
+
+if _pmview_fetch_indom network.interface.in.bytes
+then
+ ninterfaces=$number
+else
+ _pmview_fetch_warn "get the number of network interfaces"
+ ninterfaces=0
+fi
+
+[ $ninterfaces -gt 0 ] && sed < $tmp.pmview_result -e 's/lo[0-9]*//g' -e 's/sl[0-9]*//g' -e 's/ppp[0-9]*//g' > $tmp.list
+
+[ ! -s $tmp.list ] && ninterfaces=0
+
+if $verbose
+then
+ echo "# Available Network Interfaces: "`cat $tmp.list | tr '\012' ' '` >> $tmp.conf
+fi
+
+if [ $ninterfaces -gt 0 ]
+then
+ if [ -z "$argInterfaces" ]
+ then
+ cp $tmp.list $tmp.chosen
+ else
+ touch $tmp.chosen
+ for i in $argInterfaces
+ do
+ egrep $i $tmp.list >> $tmp.chosen
+ done
+ fi
+
+ interfaces_sp=`cat $tmp.chosen | sort | uniq`
+ interfaces=`echo $interfaces_sp | sed -e 's/ /,/g'`
+ ninterfaces=`echo $interfaces | wc -w`
+
+ if $verbose
+ then
+ echo "# Network interfaces Matching \"$argInterfaces\": $interfaces" >> $tmp.conf
+ fi
+
+ if [ $ninterfaces -eq 0 ]
+ then
+ echo "$prog: no matching network interfaces for \"$argInterfaces\"" > $tmp.msg
+ echo "Available network interfaces on host \"$host\" are: " >> $tmp.msg
+ tr < $tmp.list '\012' ' ' | fmt | sed -e "s/^/ /" >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ #NOTREACHED
+ fi
+fi
+
+if _pmview_fetch_values hinv.ndisk
+then
+ ndisk=`cat $tmp.pmview_result`
+ maxdiskscale=`expr $maxdisk \* 10`
+else
+ ndisk=0
+ maxdiskscale=0
+fi
+
+if [ $ndisk -eq 1 ]
+then
+ diskdesc="1 Disk"
+else
+ diskdesc="$ndisk Disks"
+fi
+
+$verbose && echo "# $diskdesc detected" >> $tmp.conf
+
+if [ "$ndisk" -gt 0 ]
+then
+
+ if _pmview_fetch_values disk.all.avg_disk.active
+ then
+ allAvg=true
+ else
+ allAvg=false
+ fi
+
+ if _pmview_fetch_indom disk.ctl.avg_disk.active
+ then
+ nctrl=$number
+ cp $tmp.pmview_result $tmp.ctrls
+ else
+ nctrl=0
+ fi
+
+ if [ $nctrl -eq 1 ]
+ then
+ ctrldesc="1 Disk Controller"
+ else
+ ctrldesc="$nctrl Disk Controllers"
+ fi
+
+ if [ "$nctrl" -gt 0 ]
+ then
+
+ collen=`expr $ninterfaces + 3`
+ collensq=`expr $collen \* $collen`
+
+ if [ $nctrl -le $collen ]
+ then
+ ctrlcols=$nctrl
+ elif [ $nctrl -le $collensq ]
+ then
+ ctrlcols=$collen
+ else
+ ctrlcols=`echo $nctrl \
+ | $PCP_AWK_PROG '{x = sqrt($1); y = int(x); if (y < x) y++; print y }'`
+ fi
+ fi
+
+ if $verbose
+ then
+ echo "# $ctrldesc detected: "`tr < $tmp.ctrls ' ' '\012'` >> $tmp.conf
+ echo "#" >> $tmp.conf
+ fi
+fi
+
+linuxutilmem=false
+utilmem=false
+if _pmview_fetch_values mem.util.used
+then
+ linuxutilmem=true
+ if $verbose
+ then
+ echo "# Linux memory utilization metrics supported" >> $tmp.conf
+ echo "#" >> $tmp.conf
+ fi
+else
+ linuxutilmem=false
+ if _pmview_fetch_values mem.util
+ then
+ utilmem=true
+ if $verbose
+ then
+ echo "# Memory utilization metrics supported" >> $tmp.conf
+ echo "#" >> $tmp.conf
+ fi
+ else
+ utilmem=false
+ if $verbose
+ then
+ _pmview_warning "$prog: Memory utilization metrics not supported, showing free memory only"
+ echo "# Memory utilization metrics not supported, showing free memory only" >> $tmp.conf
+ echo "#" >> $tmp.conf
+ fi
+ fi
+fi
+
+# Use mem.physmem if available, otherwise hinv.physmem will do.
+if _pmview_fetch_values mem.physmem
+then
+ realmem=`cat $tmp.pmview_result`
+elif _pmview_fetch_values hinv.physmem
+then
+ realmem=`cat $tmp.pmview_result`
+ realmem=`expr $realmem \* 1024`
+else
+ realmem=0
+
+ if $utilmem
+ then
+ if $verbose
+ then
+ echo "# Unable to determine total real memory" >> $tmp.conf
+ echo "# Showing memory utilisation with free memory" >> $tmp.conf
+ fi
+ else
+ _pmview_warning "Unable to determine size of real memory on host \"$host\""
+ fi
+fi
+
+have_wait=false
+if _pmview_fetch_values kernel.all.cpu.wait.total
+then
+ have_wait=true
+fi
+
+have_intr=false
+if _pmview_fetch_values kernel.all.cpu.intr
+then
+ have_intr=true
+fi
+
+have_nice=false
+if _pmview_fetch_values kernel.all.cpu.nice
+then
+ have_nice=true
+# linux hack !!
+# these metrics are not actually supported in linux
+ have_intr=false
+ have_wait=false
+fi
+
+have_sys=false
+if _pmview_fetch_values kernel.all.cpu.sys
+then
+ have_sys=true
+fi
+
+have_user=false
+if _pmview_fetch_values kernel.all.cpu.user
+then
+ have_user=true
+fi
+
+cpucolors="("
+$have_user && cpucolors="$cpucolors blue2"
+$have_sys && cpucolors="$cpucolors red2"
+$have_nice && cpucolors="$cpucolors rgbi:0.6/1.0/0.7"
+$have_intr && cpucolors="$cpucolors yellow2"
+$have_wait && cpucolors="$cpucolors cyan2"
+cpucolors="$cpucolors )"
+
+if [ -z "$titleArg" ]
+then
+ titleArg="SGI PCP : High-Level Activity for Host $host"
+fi
+
+cat << end-of-file >> $tmp.conf
+
+_colorlist cpu_colors $cpucolors
+_colorlist disk_colors ( violet yellow )
+_colorlist ctrl_colors ( green2 )
+_colorlist network_colors ( green2 blue2 red2 )
+
+_colorlist memory_colors (
+ rgbi:1.0/1.0/0.0
+ rgbi:0.0/1.0/1.0
+ rgbi:1.0/0.0/0.0
+ rgbi:1.0/0.0/1.0
+ rgbi:0.0/0.0/1.0
+ rgbi:0.0/1.0/0.0
+)
+
+_grid hide (
+
+#
+# System level stuff
+#
+end-of-file
+
+if [ "$ndisk" -gt 0 ]
+then
+ cat << end-of-file >> $tmp.conf
+
+ _label 0 1 _down _large "Disk"
+
+ _stack 1 1 _west _cylinder (
+ _metrics (
+ disk.all.write $maxio
+ disk.all.read $maxio
+ )
+ _colorlist disk_colors
+ _baseLabel "Disk Operations\nNormalized to $maxio I/Os per second"
+ )
+end-of-file
+
+ if $allAvg
+ then
+ cat << end-of-file >> $tmp.conf
+
+ _bar 2 1 _west _cylinder (
+ _metrics (
+ disk.all.avg_disk.active $maxdiskscale
+ )
+ _colorlist ctrl_colors
+ _baseLabel "Disk Activity\nNormalized to ${maxdisk}% for $ndisk disks"
+ )
+end-of-file
+ fi
+
+ if [ "$nctrl" -gt 0 ]
+ then
+ cat << end-of-file >> $tmp.conf
+
+ _label 4 0 _west "Disk Controllers"
+
+ _bar 4 1 _west _cylinder (
+ _metrics (
+end-of-file
+
+ cat $tmp.ctrls | tr '\012' ' ' \
+ | $PCP_AWK_PROG -v cols=$ctrlcols -v scale=$maxdiskscale >> $tmp.conf '
+BEGIN { str = ""; j = 0 }
+ { for (i = 1; i <= NF; i++) {
+ if (str == "")
+ str = $i;
+ else
+ str = str "," $i
+ if (j == cols) {
+ printf(" disk.ctl.avg_disk.active[%s] %d\n", str, scale);
+ str = "";
+ j = 0;
+ }
+ else
+ j++;
+ }
+ }
+END { if (str != "")
+ printf(" disk.ctl.avg_disk.active[%s] %d\n", str, scale);
+ }'
+
+ cat << end-of-file >> $tmp.conf
+ )
+ _colorlist ctrl_colors
+ _baseLabel "Disk Controller Activity\nNormalized to ${maxdisk}% for the disks on each controller"
+ )
+end-of-file
+
+ fi
+fi
+
+cat << end-of-file >> $tmp.conf
+
+ _label 0 3 _west _down _large "Load"
+
+ _bar 1 3 2 1 _west (
+ _metrics (
+ kernel.all.load[15] $maxload
+ kernel.all.load[5] $maxload
+ kernel.all.load[1] $maxload
+ )
+ _metriclabels _away ( "15" "5" "1" )
+ _colorlist ( blue2 blue2 blue2 )
+ _baseLabel "Average System Load over the last 1, 5, and 15 minutes\nNormalized to $maxload"
+ )
+
+ _label 0 5 _west _down _large "Mem"
+
+end-of-file
+
+if [ $realmem -ne 0 ]
+then
+ if $utilmem
+ then
+ cat << end-of-file >> $tmp.conf
+ _stack 1 5 _west (
+ _metrics (
+ mem.util.kernel $realmem
+ mem.util.fs_ctl $realmem
+ mem.util.fs_dirty $realmem
+ mem.util.fs_clean $realmem
+ mem.util.user $realmem
+ )
+ _colorlist memory_colors
+ _baseLabel "Physical Memory Utilization\nNormalized to $realmem Kbytes"
+ )
+end-of-file
+ elif $linuxutilmem
+ then
+ cat << end-of-file >> $tmp.conf
+ _stack 1 5 _west (
+ _metrics (
+ mem.util.shared $realmem
+ mem.util.cached $realmem
+ mem.util.bufmem $realmem
+ mem.util.other $realmem
+ mem.util.free $realmem
+ )
+ _colorlist memory_colors
+ _baseLabel "Physical Memory Utilization\nNormalized to `expr $realmem / 1024` Kbytes"
+ )
+end-of-file
+ else
+ cat << end-of-file >> $tmp.conf
+ _stack 1 5 _west _fillmod (
+ _metrics (
+ mem.freemem $realmem
+ )
+ _colorlist ( blue2 )
+ _baseLabel "Unallocated Physical Memory"
+ _stackLabel "Used Physical Memory\nNormalized to $realmem Kbytes"
+ )
+end-of-file
+fi
+elif $utilmem
+then
+ cat << end-of-file >> $tmp.conf
+ _stack 1 5 _west _utilmod (
+ _metrics (
+ mem.util.kernel 0
+ mem.util.fs_ctl 0
+ mem.util.fs_dirty 0
+ mem.util.fs_clean 0
+ mem.util.user 0
+ mem.util.free 0
+ )
+ _colorlist memory_colors
+ _baseLabel "Physical Memory Utilization"
+ )
+end-of-file
+elif $linuxutilmem
+then
+ cat << end-of-file >> $tmp.conf
+ _stack 1 5 _west _utilmod (
+ _metrics (
+ mem.util.shared 0
+ mem.util.cached 0
+ mem.util.bufmem 0
+ mem.util.other 0
+ mem.util.free 0
+ )
+ _colorlist memory_colors
+ _baseLabel "Physical Memory Utilization"
+ )
+end-of-file
+fi
+
+cat << end-of-file >> $tmp.conf
+
+ _label 0 7 _west _down _large "CPU"
+
+ _stack 1 7 _west (
+ _metrics (
+end-of-file
+$have_user && echo " kernel.all.cpu.user $maxcpu" >> $tmp.conf
+$have_sys && echo " kernel.all.cpu.sys $maxcpu" >> $tmp.conf
+$have_nice && echo " kernel.all.cpu.nice $maxcpu" >> $tmp.conf
+$have_intr && echo " kernel.all.cpu.intr $maxcpu" >> $tmp.conf
+$have_wait && echo " kernel.all.cpu.wait.total $maxcpu" >> $tmp.conf
+cat << end-of-file >> $tmp.conf
+ )
+ _colorlist cpu_colors
+ _baseLabel "CPU Utilization\nSummed over $cpudesc"
+ )
+end-of-file
+
+if [ "$ninterfaces" -gt 0 ]
+then
+ cat << end-of-file >> $tmp.conf
+
+#
+# Network Stuff and Alarms
+#
+
+ _marginWidth 1
+
+ _grid 4 2 1 7 _nw (
+
+ _marginWidth 8
+
+ _label 0 0 _sw "Network Input"
+
+ _bar 0 1 _nw _groupByMetric (
+ _metrics (
+ network.interface.in.bytes[$interfaces] $maxbyte
+ network.interface.in.packets[$interfaces] $maxpack
+ network.interface.in.errors[$interfaces] $maxerr
+ )
+ _colorlist network_colors
+ _metricLabels _away ( "Bytes" "Packets" "Errors" )
+ _baseLabel "Input on all Network Interfaces\nNormalized to $maxbyte bytes per second and $maxpack packets per second"
+ )
+
+ _label 0 2 _sw "Network Output"
+
+ _bar 0 3 _nw (
+ _metrics (
+ network.interface.out.bytes[$interfaces] $maxbyte
+ network.interface.out.packets[$interfaces] $maxpack
+ network.interface.out.errors[$interfaces] $maxerr
+ )
+ _instlabels _away ( $interfaces_sp )
+ _metricLabels _away ( "Bytes" "Packets" "Errors" )
+ _colorlist network_colors
+ _baseLabel "Output on all Network Interfaces\nNormalized to $maxbyte bytes per second and $maxpack packets per second"
+ )
+ )
+end-of-file
+fi
+
+echo ")" >> $tmp.conf
+
+$verbose && cat $tmp.conf
+
+eval $PMVIEW <$tmp.conf $args -title "'$titleArg'" -xrm "'*iconName:osvis'" -R $PCP_VAR_DIR/config/pmlogger/config.osvis
+
+exit
diff --git a/src/pmview/front-ends/pmview-args b/src/pmview/front-ends/pmview-args
new file mode 100644
index 0000000..31a7008
--- /dev/null
+++ b/src/pmview/front-ends/pmview-args
@@ -0,0 +1,625 @@
+# Copyright (c) 1995-2005 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+prog=`basename $0`
+
+PMVIEW=pmview
+PMPROBE=pmprobe
+CONFIRM="$PCP_XCONFIRM_PROG"
+ECHONL="echo -n"
+_multiple_sources=false
+
+#
+# Standard usage and command-line argument parsing for pmview front ends.
+# This file should be included by pmview front end scripts to present a
+# consistent interface. See pmview(1), dkvis(1), mpvis(1) and nfsvis(1)
+# for more information on their respective interfaces.
+#
+
+#
+# The front end scripts should call _pmview_usage after their own usage
+# information in a subroutine called _usage. The _usage subroutine may be
+# called by either _pmview_note or _pmview_args.
+#
+_pmview_usage()
+{
+ if $_multiple_sources
+ then
+ echo -n '
+ -A align align sample times on natural boundaries
+ -a archive[,archive...]
+ metrics source is one or more PCP archive logs
+ -C check configuration file and exit
+ -h host[,host...] metrics source is PMCD on one or more hosts'
+
+ else
+
+ echo -n '
+ -A align align sample times on natural boundaries
+ -a archive metrics source is a PCP archive log
+ -C check configuration file and exit
+ -h host metrics source is PMCD on host'
+
+ fi
+
+ echo '
+ -n pmnsfile use an alternative PMNS
+ -O offset initial offset into the time window
+ -p port port name for connection to existing time control
+ -S starttime start of the time window
+ -T endtime end of the time window
+ -t interval sample interval [default 2.0 seconds]
+ -x version use pmlaunch(5) version [default version 2.0]
+ -z set reporting timezone to local time of metrics source
+ -Z timezone set reporting timezone
+
+ -display display-string
+ -geometry geometry-string
+ -name name-string
+ -title title-string
+ -xrm resource'
+}
+
+# Most front-end scripts can handle input from only one source, and
+# hence only one -h or -a option.
+#
+# For those than can handle multiple sources, they should call
+# _pmview_multiple_sources_are_ok before calling _pmview_args to
+# enable the following extensions to the -a and -h options:
+# -a a1 -a a2 ... multiple -a options
+# -h h1 -h h2 ... multiple -h options
+# -a a1,a2,... multiple archives with the -a option
+# -h h1,h2,... multiple hosts with the -h option
+#
+_pmview_multiple_sources_are_ok()
+{
+ _multiple_sources=true
+}
+
+# check for magic numbers in a file that indicate it is a PCP archive
+#
+# if file(1) was reliable, this would be much easier, ... sigh
+#
+# if you need to change this, make consistent changes in all these
+# places:
+# _check_file() in src/pmafm/mkaf
+# _is_archive() in src/pmafm/pmafm
+# _is_archive() in src/pmview/front-ends/pmview-args
+#
+_is_archive()
+{
+ case "$PCP_PLATFORM" in
+ irix)
+ dd ibs=1 count=7 if="$1" 2>/dev/null | od -X | $PCP_AWK_PROG '
+NR == 1 && $2 == "00000084" && $3 == "50052600" { exit 0 }
+ { exit 1 }'
+ ;;
+ linux)
+ dd ibs=1 count=7 if="$1" 2>/dev/null | od -x | $PCP_AWK_PROG '
+NR == 1 && NF == 5 && $2 == "0000" && $3 == "0084" && $4 == "5005" && $5 == "2600" { exit 0 }
+NR == 1 && NF == 5 && $2 == "0000" && $3 == "8400" && $4 == "0550" && $5 == "0026" { exit 0 }
+
+ { exit 1 }'
+ ;;
+ esac
+ return $?
+}
+
+# One of the first actions of a front end script should be to call
+# _pmview_args. It sets the following variables:
+#
+# host the first host specified with -h (if any) in the format
+# hostname
+# else the host from the first archive in the format
+# hostname (Archive archivename)
+# arch the first archive specified with -a (if any).
+# All archives are passed on to pmview with one -a
+# argument per archive via $args
+# numsource Number of metrics sources (hosts or archives)
+# args The list of args that pmview will comprehend and use.
+# otherArgs The arguments pmview will not understand and should be
+# handled by the front end script.
+# titleArg The title the user prefers. If empty, the title should be
+# provided by the front end script.
+# prog The name of the program.
+# namespace The namespace (including the flag) if specified, else empty
+# eg "-n foo"
+# msource The default metrics source, whether live or an archive,
+# including the flag. e.g. "-h blah" or "-a first_archive".
+# Taken from the first encountered -a or -h option.
+#
+# sourcelist space separated list of hosts or archives
+#
+_pmview_args()
+{
+
+_seen_host=false
+_seen_arch=false
+host=""
+arch=""
+numsource=0
+args=""
+otherArgs=""
+titleArg=""
+namespace=""
+msource=""
+
+if [ $# -eq 1 -a '$1' = '-\?' ]
+then
+ _usage
+ exit 0
+fi
+
+while [ $# -gt 0 ]
+do
+ case $1
+ in
+ -g*|-di*|-name|-xrm)
+ # assume an X11 argument
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: X-11 option $1 requires one argument"
+ #NOTREACHED
+ fi
+ args="$args $1 '$2'"
+ shift
+ ;;
+
+ -title)
+ # assume an X11 argument
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: Option $1 requires one argument"
+ #NOTREACHED
+ exit 1
+ fi
+ titleArg="$2"
+ shift
+ ;;
+
+ -A|-D|-O|-p|-S|-T|-t|-x|-Z)
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: Option $1 requires one argument"
+ #NOTREACHED
+ fi
+ args="$args $1 '$2'"
+ shift
+ ;;
+
+ -A*|-D*|-O*|-p*|-S*|-T*|-t*|-Z*|-C|-z)
+ args="$args $1"
+ ;;
+
+ -a)
+ if $_seen_host
+ then
+ _pmview_note Usage-Error error "$prog: Only one of the -h or -a options may be specified"
+ #NOTREACHED
+ fi
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: Option $1 requires one argument"
+ #NOTREACHED
+ fi
+ for _archbase in `echo "$2" | sed -e 's/,/ /g'`
+ do
+ if [ $numsource -gt 0 -a $_multiple_sources = false ]
+ then
+ _pmview_note Usage-Error error "$prog: Only one -a option may be specified"
+ # NOTREACHED
+ fi
+ if _is_archive $_archbase 2>&1
+ then
+ _archbase=`echo $_archbase | sed -e 's/\.[^.]*$//'`
+ fi
+ # at least $_archbase.0 and $_archbase.meta have to be here
+ #
+ if _is_archive $_archbase.0 && _is_archive $_archbase.meta
+ then
+ :
+ else
+ _pmview_note Error error "$prog: \"$_archbase\" is not the basename of a valid PCP archive"
+ #NOTREACHED
+ fi
+ if [ -z "$arch" ]
+ then
+ # first archive seen
+ #
+ arch=$_archbase
+ msource="-a $_archbase"
+ host=`pmdumplog -l $arch \
+ | $PCP_AWK_PROG '/^Performance/ {print $5}' \
+ | sed -e 's/,//g'`
+ [ "X$host" = X ] && host="unknown host"
+ host="$host (Archive $arch)"
+ fi
+
+ # pmview(1) can handle multiple -a options, so
+ # pass _all_ archive names back to the caller both as
+ # -a options via $args and in $sourcelist (counted by
+ # $numsource).
+ #
+ # Note: multiple -h options are handled slightly
+ # differently, see also the comments for -h below.
+ #
+
+ args="$args -a $_archbase"
+ if [ -z "$sourcelist" ]; then
+ sourcelist=$_archbase
+ else
+ sourcelist="$sourcelist $_archbase"
+ fi
+ numsource=`expr $numsource + 1`
+ done
+ _seen_arch=true
+ shift
+ ;;
+
+ -h)
+ if $_seen_arch
+ then
+ _pmview_note Usage-Error error "$prog: Only one of the -h or -a options may be specified"
+ #NOTREACHED
+ fi
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: Option $1 requires one argument"
+ #NOTREACHED
+ fi
+ for _host in `echo "$2" | sed -e 's/,/ /g'`
+ do
+ if [ $numsource -gt 0 -a $_multiple_sources = false ]
+ then
+ _pmview_note Usage-Error error "$prog: Only one -h option may be specified"
+ # NOTREACHED
+ fi
+ if [ -z "$host" ]
+ then
+ host=$_host
+ msource="-h $_host"
+
+ # pmview(1) can handle only one -h options, so
+ # pass the _first_ host name back to the caller as a
+ # -h option via $args and _all_ hostnames via
+ # $sourcelist (counted by $numsource).
+ #
+ # Note: multiple -a options are handled slightly
+ # differently, see also the comments for -a above.
+ #
+
+ args="$args -h $_host"
+ fi
+ if [ -z "$sourcelist" ]; then
+ sourcelist=$_host
+ else
+ sourcelist="$sourcelist $_host"
+ fi
+ numsource=`expr $numsource + 1`
+ done
+ _seen_host=true
+ shift
+ ;;
+
+ -n)
+ if [ $# -lt 2 ]
+ then
+ _pmview_note Usage-Error error "$prog: Option $1 requires one argument"
+ #NOTREACHED
+ fi
+ namespace="-n $2"
+ args="$args -n $2"
+ shift
+ ;;
+
+ *)
+ otherArgs="$otherArgs $1"
+ ;;
+
+ esac
+ shift
+
+done
+
+if [ -z "$host" ]
+then
+ host=`pmhostname`
+ msource="-h $host"
+fi
+}
+
+# standard fatal error reporting
+# Usage: _pmview_error message goes in here
+# _pmview_error -f file
+#
+_pmview_error()
+{
+ _pmview_note Error error $*
+}
+
+# standard warning
+# Usage: _pmview_warning message goes in here
+# _pmview_warning -f file
+#
+_pmview_warning()
+{
+ _pmview_note Warning warning $*
+}
+
+# standard info
+# Usage: _pmview_info message goes in here
+# _pmview_info -f file
+#
+_pmview_info()
+{
+ _pmview_note Info info $*
+}
+
+# generic notifier
+# Usage: _pmview_note tag icon args ...
+#
+_pmview_note()
+{
+ tag=$1; shift
+ icon=$1; shift
+ button=""
+ [ $tag = Error ] && button="-B Quit"
+ [ $tag = Usage-Error ] && button="-B Quit -b Usage"
+
+ [ X"$PCP_STDERR" = XDISPLAY -a -z "$DISPLAY" ] && unset PCP_STDERR
+
+ if [ $# -eq 2 -a "X$1" = X-f ]
+ then
+ case "$PCP_STDERR"
+ in
+ DISPLAY)
+ ans=`$CONFIRM -icon $icon -file $2 -useslider -header "$tag $prog" $button 2>&1`
+ ;;
+ '')
+ echo "$tag:" >&2
+ cat $2 >&2
+ ans=Quit
+ ;;
+ *)
+ echo "$tag:" >>$PCP_STDERR
+ cat $2 >>$PCP_STDERR
+ ans=Quit
+ ;;
+ esac
+ else
+ case "$PCP_STDERR"
+ in
+ DISPLAY)
+ ans=`$CONFIRM -icon $icon -t "$*" -noframe -header "$tag $prog" $button 2>&1`
+ ;;
+ '')
+ echo "$tag: $*" >&2
+ ans=Quit
+ ;;
+ *)
+ echo "$tag: $*" >>$PCP_STDERR
+ ans=Quit
+ ;;
+ esac
+ fi
+
+ if [ $tag = Usage-Error ]
+ then
+ [ $ans = Usage ] && _usage
+ tag=Error
+ fi
+
+ [ $tag = Error ] && exit 1
+}
+
+# used internally by _pmview_cache_fetch() and _pmview_fetch()
+#
+_pmview_probe()
+{
+ flag=$1
+ shift
+ ( echo $* \
+ ; echo "-----" \
+ ; ( $PMPROBE $namespace $msource $flag $* 2>$tmp.pmview_err \
+ | tee -a $tmp.pmview_fetch \
+ ) \
+ ) \
+ | tr ' ' '\012' \
+ | sed -e 's/"//g' \
+ | $PCP_AWK_PROG '
+BEGIN { last = 0 }
+$1 == "-----" { state = 1; next }
+state == 0 { metric[last] = pat[last] = $1
+ # deal with arguments that are non-terminals in the PMNS
+ # so pmprobe a.b => a.b.c a.b.c.x a.b.d etc
+ gsub("\\.", "\\.", pat[last])
+ pat[last] = "^" pat[last] "\\."
+ last++
+ next
+ }
+state > 0 { for (i = 0; i < last; i++) {
+ if (metric[i] == $1 || match($1, pat[i]) > 0) {
+ # new matching metric name
+ name=$1
+ state=2
+ next
+ }
+ }
+ }
+state == 2 { if ($1 > 0) state = 3
+ else state = 1
+ next
+ }
+state == 3 { printf("%s%s|%s\n", "'"$flag|$msource|"'",name,$1) }'
+}
+
+# Fetch metrics and cache result
+# input
+# $1 - pmprobe flag
+# $* - 1 or more metrics
+# output
+# $tmp.pmview_cache - cached values, with this format
+# pmprobe flag|metric source|metric name|pmprobe result
+#
+_pmview_cache_fetch()
+{
+ flag=$1
+ shift
+ _pmview_probe $flag $* >>$tmp.pmview_cache
+
+ return 0
+}
+
+# Fetch metrics
+#
+# input
+# $1 - pmprobe flag
+# $2 - metric name
+# output
+# $number - number of values
+# $tmp.pmview_result - values
+#
+_pmview_fetch()
+{
+ flag=$1
+ metric=$2
+ rm -f $tmp.pmview_fetch $tmp.pmview_result
+ if [ -s $tmp.pmview_cache ]
+ then
+ $PCP_AWK_PROG -F\| \
+ <$tmp.pmview_cache >$tmp.pmview_result \
+'
+$1 == "'"$flag"'" && $2 == "'"$msource"'" && $3 == "'"$metric"'" { print $4 }'
+ fi
+
+ if [ ! -s $tmp.pmview_result ]
+ then
+ # cache miss, forced to probe
+ #
+ _pmview_probe $flag $metric \
+ | $PCP_AWK_PROG -F\| >$tmp.pmview_result '{print $4}'
+ fi
+
+ if [ -s $tmp.pmview_result ]
+ then
+ number=`wc -l <$tmp.pmview_result | sed -e 's/ //g'`
+ else
+ if [ -s $tmp.pmview_fetch ]
+ then
+ check=`cut -d ' ' -f 2 $tmp.pmview_fetch`
+ if [ "$check" = "$metric" ]
+ then
+ # *.pmview_fetch looks valid, extract numval from 2nd field
+ #
+ number=`cut -d ' ' -f 2 $tmp.pmview_fetch`
+ else
+ # *.pmview_fetch exists, but does not contain
+ # pmprobe output, more than likely this is some
+ # sort of fatal error message ... but _real_ message
+ # is likely to be in *.pmview_err
+ #
+ [ -s $tmp.pmview_err ] && mv $tmp.pmview_err $tmp.pmview_fetch
+ number=-1
+ fi
+ else
+ number=-1
+ mv $tmp.pmview_err $tmp.pmview_fetch
+ fi
+ fi
+ if [ $number -le 0 ]
+ then
+ rm -f $tmp.pmview_result
+ return 1
+ fi
+
+ return 0
+}
+
+# Fetch the metric values
+#
+# input
+# $1 - metric name
+# output
+# $number - number of values
+# $tmp.pmview_result - values
+#
+_pmview_fetch_values()
+{
+ _pmview_fetch -v $1
+ return $?
+}
+
+# Fetch the metric instance list
+#
+# input
+# $1 - metric name
+# output
+# $number - number of instances
+# $tmp.pmview_result - instances
+#
+_pmview_fetch_indom()
+{
+ _pmview_fetch -I $1
+ return $?
+}
+
+# Convert pmprobe/pminfo error message into something useful and
+# consistent
+#
+_pmview_fetch_mesg()
+{
+ $PCP_AWK_PROG '
+$1 == "pmprobe:" { $1 = "'$prog':"; print; exit }
+$1 == "pminfo:" { $1 = "'$prog':"; print; exit }
+$1 == "Error:" { $1 = ":";
+ printf("%s: %s%s\n", "'$prog'", metric, $0); exit }
+$1 == "inst" { exit }
+NF == 1 { metric = $1; next }
+NF == 0 { next }
+NF == 2 && $2 == "0" { printf("%s: %s: No values available\n", "'$prog'", $1); exit}
+ { $2 = ":"; print "'$prog': " $0; exit}' \
+ | sed "s/ : /: /" \
+ | fmt
+}
+
+# Generate error metric for failed fetch
+#
+_pmview_fetch_fail()
+{
+ cat $tmp.pmview_fetch | _pmview_fetch_mesg >> $tmp.msg
+ echo "$prog: Failed to $1 from host \"$host\"" | fmt >> $tmp.msg
+ _pmview_error -f $tmp.msg
+ # NOTREACHED
+}
+
+# Generate warning message for failed fetch
+#
+_pmview_fetch_warn()
+{
+ cat $tmp.pmview_fetch | _pmview_fetch_mesg >> $tmp.msg
+ echo "$prog: Failed to $1 from host \"$host\"" | fmt >> $tmp.msg
+ _pmview_warning -f $tmp.msg
+ rm -f $tmp.msg
+}
+
+# Check that $OPTARG for option $1 is a positive integer
+# ...note the creative use of unary - to prevent leading signs
+#
+_pmview_unsigned()
+{
+ if [ "X-$OPTARG" != "X`expr 0 + -$OPTARG 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -$1 option must have a positive integral argument"
+ # NOTREACHED
+ fi
+}
diff --git a/src/pmview/front-ends/weblogvis b/src/pmview/front-ends/weblogvis
new file mode 100755
index 0000000..5b570bd
--- /dev/null
+++ b/src/pmview/front-ends/weblogvis
@@ -0,0 +1,451 @@
+#!/bin/sh
+# Copyright (c) 1995-2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+# default idle time
+#
+defidle=3600
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options] [server ...]
+
+Options
+ -b display byte rate, rather than request rate
+ -f display activity by function, rather than activity by
+ result size
+ -i show server names
+ -I time maximum expected idle time in seconds [default $defidle]
+ -m max maximum expected request rate (or maximum byte rate)
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+ _pmview_usage >> $tmp.msg
+ echo '
+Default title is: Web Log Activity (request rate by result size) for Host' >> $tmp.msg
+ echo '
+ The default is to display the request rate, grouped by result size, for all
+ Web servers on the target host.' | fmt >> $tmp.msg
+ _pmview_info -f $tmp.msg
+}
+
+# --- build WM_COMMAND X(1) property for restart after login/logout ---
+#
+echo -n "pmview Version 2.1 \"$prog\"" >$tmp.pmview
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.pmview
+done
+echo >> $tmp.pmview
+
+# --- parse command line arguments ---
+#
+verbose=false
+serverList=""
+max=0
+idle=$defidle
+class=size
+show=request
+showInst=false
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?bfiI:m:v:V" c $otherArgs
+ do
+ case $c
+ in
+ b) # show bytes not requests
+ show=byte
+ ;;
+
+ f) # classify by function (method)
+ class=method
+ ;;
+ i)
+ showInst=true
+ ;;
+ I)
+ idle=$OPTARG
+ # and now the obscure +ve integer checking bit
+ # ...note the creative use of unary - to prevent leading signs
+ if [ "X-$idle" != "X`expr 0 + -$idle 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -I must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+ m)
+ max=$OPTARG
+ # and now the obscure +ve integer checking bit
+ # ...note the creative use of unary - to prevent leading signs
+ if [ "X-$max" != "X`expr 0 + -$max 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -m must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+ v)
+ if [ $OPTARG = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ elif [ $OPTARG != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+ V)
+ verbose=true
+ ;;
+ '?')
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+
+ set - $otherArgs
+ shift `expr $OPTIND - 1`
+ [ $# -gt 0 ] && serverList_sp=$* && serverList=`echo $* | sed -e 's/ /,/g'`
+fi
+[ -z "$titleArg" ] && titleArg="SGI PCP : Web Log Activity"
+
+
+if [ $max = 0 ]
+then
+ if [ $show = request ]
+ then
+ # requests per second
+ max=50
+ else
+ # bytes per second
+ max=500000
+ fi
+fi
+
+
+# maximum req error rate (default: 5% of request rate)
+#
+maxerr=`expr $max / 20`
+
+
+# if metrics source is an archive, and find out name of host
+#
+if [ "X$arch" != X ]
+then
+ host=`pmdumplog -l $arch | $PCP_AWK_PROG '/^Performance/ {print $5}' \
+ | sed -e 's/,//g'`
+ [ "X$host" = X ] && host="unknown host"
+ host="$host (Archive $arch)"
+fi
+
+
+# get perserver instances
+# in the default case use web.perserver.requests.total
+# in the -b flag case use web.perserver.bytes.total
+#
+rm -f $tmp.int
+if [ $show = request ]
+then
+ pminfo -f $msource $namespace web.perserver.requests.total \
+ > $tmp.int 2>/dev/null
+else
+ pminfo -f $msource $namespace web.perserver.bytes.total \
+ > $tmp.int 2>/dev/null
+fi
+if [ ! -s $tmp.int ]
+then
+ if [ "X$arch" != "X" ]
+ then
+ _pmview_error "$prog: weblog metrics not included in the archive \"$arch\""
+ #NOTREACHED
+ else
+ _pmview_error "$prog: weblog metrics not available for host \"$host\""
+ #NOTREACHED
+ fi
+fi
+
+sed -e 's/\]//' -e 's/"//g' $tmp.int \
+ | $PCP_AWK_PROG '$1 == "inst" {print $4}' > $tmp.list
+
+if [ ! -s $tmp.list ]
+then
+ if [ "X$arch" != X ]
+ then
+ _pmview_error "$prog: failed to get web servers from archive \"$arch\""
+ #NOTREACHED
+ else
+ _pmview_error "$prog: failed to get web servers from host \"$host\""
+ #NOTREACHED
+ fi
+fi
+
+rm -f $tmp.chosen
+if [ -z "$serverList" ]
+then
+ cp $tmp.list $tmp.chosen
+else
+ touch $tmp.chosen
+ for i in $serverList_sp
+ do
+ egrep $i $tmp.list >> $tmp.chosen
+ done
+fi
+
+servers_sp=`cat $tmp.chosen | sort | uniq`
+servers=`echo $servers_sp | sed -e 's/ /,/g'`
+nservers=`echo $servers | wc -w`
+
+if [ $nservers = 0 ]
+then
+ _usage
+ echo
+ echo "Error: $prog: no matching web servers"
+ echo " Available web servers are: " `cat $tmp.list`
+ exit 1
+fi
+
+
+if [ $show = request ]
+then
+ totalLabel="Total_Req_Rate"
+ label_sp="\"Request Rate\""
+ met="requests"
+ titleArg="$titleArg (request rate"
+else
+ totalLabel="Total_Data_Rate"
+ label_sp="\"Data Rate\""
+ met="bytes"
+ titleArg="$titleArg (data rate"
+fi
+
+#
+# strings for base plane labels
+#
+basestr_idle="Elapsed time since the last request\nNormalized to $idle seconds"
+if [ $show = request ]
+then
+ basestr_total="Total number of HTTP requests processed by server\nNormalized to $max requests per second"
+ basestr_req="HTTP request rate by response size in bytes\nNormalized to $max hits per second"
+ basestr_type="HTTP request rate by HTTP method\nNormalized to $max hits per second"
+else
+ basestr_total="Total number of bytes processed by server\nNormalized to $max bytes per second"
+ basestr_req="HTTP size rate by response size in bytes\nNormalized to $max bytes per second"
+ basestr_type="HTTP size rate by HTTP method\nNormalized to $max hits per second"
+fi
+
+
+#--- config file has already been created; continue writing to it ---
+#
+
+cat << end-of-file >>$tmp.pmview
+#
+# $prog
+#
+# Servers: $servers
+#
+end-of-file
+
+if $verbose
+then
+ if [ "X$serverList" != X ]
+ then
+ echo "# Matching servers for \"$serverList\": $servers"
+ fi
+fi
+
+if [ $class = size ]
+then
+ titleArg="$titleArg by result size)"
+else
+ titleArg="$titleArg by request type)"
+fi
+
+
+#
+# the real config starts here
+#
+cat << end-of-file >>$tmp.pmview
+
+_scale 1.2
+
+_grid _hide (
+
+ _label 2 0 1 5 _down _large $label_sp
+
+ _bar 0 0 east _col (
+ _metrics (
+ web.perserver.logidletime[$servers] $idle
+ )
+ _metriclabels ( Idle )
+ _colorList ( orange )
+ _baseLabel "$basestr_idle"
+ )
+
+end-of-file
+
+if [ $class = size ]
+then
+ cat << end-of-file >>$tmp.pmview
+
+ _bar 0 2 east _col (
+ _metrics (
+ web.perserver.$met.total[$servers] $max
+ )
+ _metriclabels ( Total )
+ _colorList ( rgbi:0.0/0.88/0.88 )
+ _baseLabel "$basestr_total"
+ )
+
+ _bar 0 4 east _col _groupbyinst (
+ _metrics (
+end-of-file
+
+ if [ $show = request ]
+ then
+ cat <<end-of-file >>$tmp.pmview
+ web.perserver.$met.size.unknown[$servers] $max
+end-of-file
+ fi
+
+ cat << end-of-file >>$tmp.pmview
+ web.perserver.$met.size.gt3m[$servers] $max
+ web.perserver.$met.size.le3m[$servers] $max
+ web.perserver.$met.size.le1m[$servers] $max
+ web.perserver.$met.size.le300k[$servers] $max
+ web.perserver.$met.size.le100k[$servers] $max
+ web.perserver.$met.size.le30k[$servers] $max
+ web.perserver.$met.size.le10k[$servers] $max
+ web.perserver.$met.size.le3k[$servers] $max
+end-of-file
+
+ if [ $show = request ]
+ then
+ cat <<end-of-file >>$tmp.pmview
+ web.perserver.$met.size.zero[$servers] $max
+ )
+ _metriclabels (
+ "?" "> 3M" "1M < 3M" "300K < 1M" "100K < 300K"
+ "30K < 100K" "10K < 30K" "3K < 10K" "0 < 3K" "0K"
+ )
+end-of-file
+ else
+ cat <<end-of-file >>$tmp.pmview
+ )
+ _metriclabels (
+ "> 3M" "1M < 3M" "300K < 1M" "100K < 300K"
+ "30K < 100K" "10K < 30K" "3K < 10K" "0 < 3K"
+ )
+end-of-file
+ fi
+
+ if $showInst
+ then
+ cat <<end-of-file >>$tmp.pmview
+ _instlabels _away ( $servers_sp )
+end-of-file
+ fi
+
+ cat << end-of-file >>$tmp.pmview
+ _colorList (
+ rgbi:1.0/0.35/0.0
+ rgbi:0.6/0.0/0.9
+ rgbi:0.0/1.0/0.0
+ rgbi:1.0/0.5/0.0
+ rgbi:0.65/0.3/1.0
+ rgbi:0.3/1.0/0.3
+ rgbi:1.0/0.65/0.3
+ rgbi:0.8/0.6/1.0
+ rgbi:0.6/1.0/0.6
+ rgbi:1.0/0.8/0.6
+
+ )
+ _baseLabel "$basestr_req"
+ )
+
+end-of-file
+
+else
+ cat << end-of-file >>$tmp.pmview
+
+ _bar 0 2 east _col (
+ _metrics (
+ web.perserver.$met.total[$servers] $max
+ )
+ _metriclabels ( Total )
+ _colorList ( rgbi:1.0/0.5/0.0 )
+ _baseLabel "$basestr_total"
+ )
+
+ _bar 0 4 east _col (
+ _metrics (
+ web.perserver.$met.get[$servers] $max
+ web.perserver.$met.head[$servers] $max
+ web.perserver.$met.post[$servers] $max
+ web.perserver.$met.other[$servers] $max
+end-of-file
+
+ if [ $show = request ]
+ then
+ cat << end-of-file >>$tmp.pmview
+ web.perserver.errors[$servers] $maxerr
+end-of-file
+ fi
+
+ cat << end-of-file >>$tmp.pmview
+ )
+ _metriclabels ( Get Head Post Other Error )
+end-of-file
+
+ if $showInst
+ then
+ cat <<end-of-file >>$tmp.pmview
+ _instlabels _away ( $servers_sp )
+end-of-file
+ fi
+
+ cat << end-of-file >>$tmp.pmview
+ _colorList (
+ rgbi:1.0/1.0/0.0
+ rgbi:0.0/1.0/1.0
+ rgbi:1.0/0.0/1.0
+ rgbi:1.0/1.0/0.6
+ rgbi:0.8/0.0/0.0
+ )
+ _baseLabel "$basestr_type"
+ )
+end-of-file
+
+fi
+
+cat << end-of-file >>$tmp.pmview
+)
+end-of-file
+
+titleArg="$titleArg for Host $host"
+
+$verbose && cat $tmp.pmview
+
+eval $PMVIEW <$tmp.pmview $args -title "'$titleArg'" -xrm "'*iconName: $prog'"
+
+exit
+
diff --git a/src/pmview/front-ends/weblogvis.load b/src/pmview/front-ends/weblogvis.load
new file mode 100755
index 0000000..a676124
--- /dev/null
+++ b/src/pmview/front-ends/weblogvis.load
@@ -0,0 +1,103 @@
+#!/bin/sh
+# Copyright (c) 2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Load up a Web server to show off/QA weblogvis
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; killall -9 load; exit" 0 1 2 3 15
+
+i=0
+
+# specular
+#
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.108/file8k.html
+GET http://155.11.225.108/file15k.html
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.108/file15k.html
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+# specular IP alias
+#
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.118/file45k.html
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.118/file15k.html
+GET http://155.11.225.118/file45k.html
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.118/file45k.html
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+# specular proxy
+#
+cat >$tmp.$i <<End-of-File
+GET http://boing/file15k.html
+End-of-File
+webping -c $tmp.$i -I0 -q -P specular:8080 &
+i=`expr $i + 1`
+
+cat >$tmp.$i <<End-of-File
+GET http://boing/file0k.html
+GET http://boing/file0k.html
+GET http://boing/file115k.html
+End-of-File
+webping -c $tmp.$i -I0 -q -P specular:8080 &
+i=`expr $i + 1`
+
+# specular socks
+#
+cat >$tmp.$i <<End-of-File
+GET http://155.11.225.108/file500k.html
+GET http://boing/file500k.html
+End-of-File
+webping -c $tmp.$i -I0 -q -S specular:8080 &
+i=`expr $i + 1`
+
+# specular ftp-socks
+#
+cat >$tmp.$i <<End-of-File
+GET ftp://155.11.225.108/pub/README
+End-of-File
+webping -c $tmp.$i -I0 -q -S specular:8080 &
+i=`expr $i + 1`
+
+# specular ftp
+#
+cat >$tmp.$i <<End-of-File
+GET ftp://155.11.225.108/pub/README
+End-of-File
+webping -c $tmp.$i -I0 -q &
+i=`expr $i + 1`
+
+wait
diff --git a/src/pmview/front-ends/weblogvis.rgb b/src/pmview/front-ends/weblogvis.rgb
new file mode 100644
index 0000000..11c4712
--- /dev/null
+++ b/src/pmview/front-ends/weblogvis.rgb
Binary files differ
diff --git a/src/pmview/front-ends/webpingvis b/src/pmview/front-ends/webpingvis
new file mode 100644
index 0000000..a08aa81
--- /dev/null
+++ b/src/pmview/front-ends/webpingvis
@@ -0,0 +1,372 @@
+#! /bin/sh
+# Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options]
+
+options:
+ -i show URL names
+ -m max maximum expected total ping response time (milliseconds)
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+
+ _pmview_usage >> $tmp.msg
+ echo >> $tmp.msg
+ echo 'Default title is: SGI PCP: Web PING Performance for Host' >> $tmp.msg
+ echo '
+ The "max" parameter (used with -m) should be set to the maximum
+ expected ping response time for all URLs being monitored. The default
+ is 1000 milliseconds. This governs the height of the bar showing total
+ response time (at the far right of the scene). All bars showing
+ response times use "max" for height normalization.' >> $tmp.msg
+ _pmview_info -f $tmp.msg
+}
+
+#--- build WM_COMMAND X(1) property for restart after login/logout ---
+#
+echo -n "pmview Version 2.1 \"$prog\"" > $tmp.pmview
+for arg
+do
+ echo -n " \"$arg\"" >> $tmp.pmview
+done
+echo >> $tmp.pmview
+
+# --- LOCAL FUNCTIONS : START ------------------------------------------------
+_sort_host_indom()
+{
+ sed <$1 \
+ -e 's/instance\[\([0-9][0-9]*\)]:/\1/' \
+ | $PCP_AWK_PROG '
+BEGIN { state = 0 }
+/^samples:/ { state = 1; next }
+state == 0 { next }
+/^full label/ { label[$4] = $NF; next }
+NF == 0 { state = 2; next }
+state == 2 { for (i=1; i<=NF; i++) {
+ if (label[i-1] == "")
+ label[i-1] = $i
+ }
+ state = 3
+ next
+ }
+state == 3 { for (i=1; i<=NF; i++)
+ size[i-1] = $i
+ }
+END { for (i in label) {
+ print label[i],size[i]
+ }
+ }' \
+ | sort +1n -2 +0 -1 >$tmp.tmp
+ mv $tmp.tmp $1
+}
+
+_sort_arch_indom()
+{
+metric=webping.perurl.kbytes
+indom=`pminfo -d -a $arch $metric \
+| sed -n -e '/InDom:/{
+s/.*InDom: //
+s/ .*//p
+}'`
+
+if [ "X$indom" = XPM_INDOM_NULL ]
+then
+ _pmview_error "$prog: $metric is singular"
+ #NOTREACHED
+elif [ -z "$indom" ]
+then
+ _pmview_error "$prog: cannot determine InDom for $metric"
+ #NOTREACHED
+fi
+
+pmdumplog -z -i $arch 2>&1 \
+| $PCP_AWK_PROG '
+/^InDom: '$indom'$/ { state=1; next }
+/^InDom: / { state=0; next }
+state == 1 && /^[^ ]/ { print }' \
+| while read stamp junk
+do
+ pminfo -f -a $arch -z -O "@$stamp" -f $metric
+done \
+| sed -n \
+ -e '/ value /{
+s/"] value//
+s/.*"//p
+}' \
+| sort -u >$tmp.known
+
+pmdumplog -z -i $arch 2>&1 \
+| $PCP_AWK_PROG '
+/^InDom: '$indom'$/ { state=1; next }
+/^InDom: / { state=0; next }
+state == 1 && /^[ ]/ { print }' \
+| sed -n \
+ -e '/ or /{
+s/.* or "//
+s/".*//p
+}' \
+| sort -u \
+| join -a1 - $tmp.known \
+| sort +2n -3 +1 -2 \
+| $PCP_AWK_PROG '
+NF==1 { printf("%s ?\n",$0); next }
+ { print }' > $1
+}
+# --- LOCAL FUNCTIONS : END --------------------------------------------------
+
+verbose=false
+max=1000
+showInst=false
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?im:v:V" c $otherArgs
+ do
+ case $c
+ in
+ i)
+ showInst=true
+ ;;
+ m)
+ max=$OPTARG
+ # and now the obscure +ve integer checking bit
+ # ...note the creative use of unary - to prevent leading signs
+ if [ "X-$max" != "X`expr 0 + -$max 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -m must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+ v)
+ if [ $OPTARG = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ elif [ $OPTARG != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+ V)
+ verbose=true
+ ;;
+ '?')
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+fi
+[ -z "$titleArg" ] && titleArg="SGI PCP: Web PING Performance for Host $host"
+
+
+# check that webping metrics are available from metrics source
+#
+if pminfo $msource $namespace webping 2>&1 \
+ | grep 'webping: Unknown metric name' >/dev/null
+then
+ _pmview_error "$prog: webping metrics not defined in the name space"
+ #NOTREACHED
+fi
+#
+# do a second check to make sure that we have webping.perurl metrics
+#
+if pminfo -f $msource $namespace webping.perurl.kbytes 2>&1 \
+ | grep 'inst .* value' >/dev/null
+then
+ :
+else
+ if [ "X$arch" != "X" ]
+ then
+ _pmview_error "$prog: webping.perurl metrics not available from $arch"
+ #NOTREACHED
+ else
+ _pmview_error "$prog: webping.perurl metrics not available from $host"
+ #NOTREACHED
+ fi
+fi
+
+
+# if metrics source is an archive, and find out name of host
+# get the instance domain and sort it
+#
+if [ "X$arch" != X ]
+then
+ _sort_arch_indom $tmp.int
+ host=`pmdumplog -l $arch | $PCP_AWK_PROG '/^Performance/ {print $5}' | sed -e 's/,//g'`
+ [ "X$host" = X ] && host="unknown host"
+ host="$host (Archive $arch)"
+else
+ pmval -h $host -s 1 webping.perurl.kbytes >$tmp.int
+ _sort_host_indom $tmp.int
+fi
+
+
+urlcount=`wc -l <$tmp.int | sed -e 's/ *//g'`
+bytesmax=`tail -1 $tmp.int | $PCP_AWK_PROG '{print $2}'`
+
+if [ $urlcount -eq 0 ]
+then
+ if [ "X$arch" != "X" ]
+ then
+ _pmview_error "$prog: there were no URLs monitored in archive \"$arch\""
+ #NOTREACHED
+ else
+ _pmview_error "$prog: there are no URLs monitored on host \"$host\""
+ #NOTREACHED
+ fi
+fi
+
+
+url_list=`$PCP_AWK_PROG <$tmp.int '
+NR>1 { printf "," }
+ { printf $1 }
+END { print "" }'`
+
+url_list_sp=`$PCP_AWK_PROG <$tmp.int '
+NR>1 { printf " " }
+/^GET_.*/ { printf "\"GET %s\"",substr($1,5) }
+/^HEAD_.*/ { printf "\"HEAD %s\"",substr($1,6) }
+/^POST_.*/ { printf "\"POST %s\"",substr($1,6) }
+END { print "" }'`
+
+
+#
+# strings for base plane labels
+#
+basestr_size="URL size in kbytes\nNormalized to $bytesmax kbytes"
+basestr_urltime="Time to fetch the URL\nNormalized to $max seconds"
+basestr_tottime="Time to fetch all URLs\nNormalized to $max seconds"
+basestr_err="Webing errors by error type\nNormalized to 1"
+
+
+#--- config file has already been created ; continue writing to it ---
+#
+
+cat << end-of-file >> $tmp.pmview
+#
+# $prog
+#
+# Largest URL = $bytesmax Kbytes
+# Maximum fetch time = $max seconds
+#
+# URLs = $url_list_sp
+#
+end-of-file
+
+
+#
+# the real config starts here
+# pmview Version 2.1
+#
+cat <<end-of-file >> $tmp.pmview
+
+_scale 1.2
+
+_colorList url_colors (
+ rgbi:1.0/0.5/0.0
+ rgbi:0.9/0.9/0.0
+ rgbi:0.0/0.9/0.9
+ rgbi:0.9/0.0/0.9
+)
+
+_grid _hide (
+
+ _bar 0 0 east _col (
+ _metrics (
+ webping.perurl.kbytes[$url_list] $bytesmax
+ )
+ _metriclabels ( Size )
+ _baseLabel "$basestr_size"
+end-of-file
+
+if $showInst
+then
+ cat <<end-of-file >>$tmp.pmview
+ _instlabels _towards ( $url_list_sp )
+end-of-file
+fi
+
+cat <<end-of-file >>$tmp.pmview
+ _colorList ( rgbi:0.0/0.9/0.0 )
+ )
+
+ _bar 0 2 ne _col _groupbyinst (
+ _metrics (
+ webping.perurl.time.total[$url_list] $max
+ webping.perurl.time.body[$url_list] $max
+ webping.perurl.time.head[$url_list] $max
+ webping.perurl.time.connect[$url_list] $max
+ )
+ _metriclabels ( Total Body Head Connect )
+ _baseLabel "$basestr_urltime"
+ _colorList url_colors
+ )
+
+ _bar 0 4 east _row _groupbyrow (
+ _metrics (
+ webping.errors.sockerr 1
+ webping.errors.httperr 1
+ webping.errors.htmlerr 1
+ webping.errors.othererr 1
+ )
+ _instlabels ( Errors )
+ _baseLabel "$basestr_err"
+ _colorList ( red1 red1 red1 red1 )
+ )
+
+end-of-file
+
+#
+# Only show row totals if there is more than one URL being monitored
+#
+if [ $urlcount -gt 1 ]
+then
+ totoff=`expr $urlcount + 1`
+ cat <<end-of-file >> $tmp.pmview
+ _bar 2 2 north _col _groupbycol (
+ _metrics (
+ webping.time.total $max
+ webping.time.body $max
+ webping.time.head $max
+ webping.time.connect $max
+ )
+ _colorList url_colors
+ _baseLabel "$basestr_tottime"
+ )
+end-of-file
+
+fi
+
+cat <<end-of-file >> $tmp.pmview
+)
+end-of-file
+
+$verbose && cat $tmp.pmview
+
+#eval pmview <$tmp.pmview $args -title "'$titleArg'" -xrm "'*iconName: $prog'" -geometry 560x515
+eval pmview <$tmp.pmview $args -title "'$titleArg'" -xrm "'*iconName: $prog'"
+
+exit
diff --git a/src/pmview/front-ends/webpingvis.rgb b/src/pmview/front-ends/webpingvis.rgb
new file mode 100644
index 0000000..a444bec
--- /dev/null
+++ b/src/pmview/front-ends/webpingvis.rgb
Binary files differ
diff --git a/src/pmview/front-ends/webvis b/src/pmview/front-ends/webvis
new file mode 100755
index 0000000..7969aec
--- /dev/null
+++ b/src/pmview/front-ends/webvis
@@ -0,0 +1,707 @@
+#!/bin/sh
+# Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit" 0 1 2 3 15
+rm -f $tmp.*
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmview-args
+
+# --- scaling parameters ---
+#
+
+# maximum packets per second
+max=750
+
+# maximum req rate (default: 5% of packet rate)
+maxreq=`expr $max / 20`
+
+# maximum disk io rate (I/O operations per second)
+maxio=100
+
+# maximum average disk business (percent)
+maxbusy=30
+
+# milliseconds per CPU
+maxcpu=1000
+
+# maximum TCP output queue length
+maxq=5
+
+# --- define usage message ---
+#
+_usage()
+{
+ echo >$tmp.msg 'Usage: '$prog' [options] [interface ...]
+
+options:
+ -b maxbusy maximum average disk active (percent) [default 30]
+ -i maxio maximum total I/Os per second [default 100]
+ -m max maximum expected packets sent or received per sec [default 750]
+ -r maxreq maximum expected Web requests per second [default 35]
+ -V verbose/diagnostic output
+
+pmview(1) options:'
+
+ _pmview_usage >> $tmp.msg
+ echo >> $tmp.msg
+ echo >> $tmp.msg 'Default title is: Web Server Activity for Host'
+ echo >> $tmp.msg '
+ By default all network interfaces are shown, with a maximum packet rate
+ of '$max' packets per second. The maximum request rate is 5% (of the
+ maximum packet rate) and the maximum error rate is 20% of the maximum
+ request rate.
+
+ If given, the [interface ...] regular expressions restrict
+ the network statistics displayed to matching network interface names only.'
+
+ _pmview_info -f $tmp.msg
+}
+
+# --- build WM_COMMAND X(1) property for restart after login/logout ---
+#
+echo -n "pmview Version 2.1 \"$prog\"" > $tmp.pmview
+for arg
+do
+ echo -n " \"$arg\"" >>$tmp.pmview
+done
+echo >> $tmp.pmview
+
+# --- parse command line arguments ---
+#
+verbose=false
+argInterfaces=""
+interfaces=""
+
+_pmview_args "$@"
+
+if [ -n "$otherArgs" ]
+then
+ while getopts "?b:i:m:r:v:V" c $otherArgs
+ do
+ case $c
+ in
+ b)
+ # and now the obscure +ve integer checking bit
+ # ...note the creative use of unary - to prevent leading signs
+ maxbusy=$OPTARG
+ if [ "X-$maxbusy" != "X`expr 0 + -$maxbusy 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -b must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+
+ i)
+ maxio=$OPTARG
+ if [ "X-$maxio" != "X`expr 0 + -$maxio 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -i must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+
+ m)
+ max=$OPTARG
+ if [ "X-$max" != "X`expr 0 + -$max 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -m must have a positive integral argument"
+ #NOTREACHED
+ fi
+ maxreq=`expr $max / 20`
+ ;;
+
+ r)
+ maxreq=$OPTARG
+ if [ "X-$maxreq" != "X`expr 0 + -$maxreq 2>/dev/null`" ]
+ then
+ _pmview_error "$prog: -r must have a positive integral argument"
+ #NOTREACHED
+ fi
+ ;;
+
+ v)
+ if [ $OPTARG = "1" ]
+ then
+ _pmview_warning "$prog: pmview version 1 no longer supported, using version 2"
+ elif [ $OPTARG != "2" ]
+ then
+ _pmview_error "$prog: only version 2 supported for -v"
+ # NOTREACHED
+ fi
+ ;;
+
+ V)
+ verbose=true
+ ;;
+
+ '?')
+ _usage
+ exit 1
+ ;;
+ esac
+ done
+
+ set - $otherArgs
+ shift `expr $OPTIND - 1`
+ [ $# -gt 0 ] && argInterfaces="$*"
+fi
+
+# maximum average active for disks, percent -> msec/sec
+maxactive=`expr $maxbusy \* 1000 / 100`
+
+
+# maximum req error rate (default: 20% of packet rate)
+maxerr=`expr $maxreq / 5`
+[ "$maxerr" -eq 0 ] && maxerr=1
+
+
+# --- check that web metrics are available from metrics source ---
+#
+if _pmview_fetch web.allservers.errors
+then
+ :
+else
+ _pmview_error "$prog: weblog metrics not defined in the name space"
+ #NOTREACHED
+fi
+
+
+# --- if metrics source is an archive, and find out name of host ---
+#
+if [ "X$arch" != X ]
+then
+ host=`pmdumplog -l $arch | $PCP_AWK_PROG '/^Performance/ {print $5}' | sed -e 's/,//g'`
+ [ "X$host" = X ] && host="unknown host"
+ host="$host (Archive $arch)"
+fi
+
+
+# --- get network interfaces ---
+#
+pminfo -f $msource network.interface.total.bytes >$tmp.int
+sed -e 's/\]//' -e 's/"//g' $tmp.int \
+ | $PCP_AWK_PROG '$1 == "inst" {print $4}' > $tmp.list
+if [ ! -s $tmp.list ]
+then
+ if [ "X$arch" != X ]
+ then
+ _pmview_error "$prog: failed to get network interface list from archive \"$arch\""
+ #NOTREACHED
+ else
+ _pmview_error "$prog: failed to get network interface list from host \"$host\""
+ #NOTREACHED
+ fi
+fi
+
+
+# --- pmview config file has already been created; keep writing to it ---
+#
+
+cat << end-of-file >> $tmp.pmview
+#
+# $prog
+#
+end-of-file
+
+if $verbose
+then
+ echo "# Available Network Interfaces: " `cat $tmp.list` >> $tmp.pmview
+fi
+
+if [ -z "$argInterfaces" ]
+then
+ cp $tmp.list $tmp.chosen
+else
+ touch $tmp.chosen
+ for i in $argInterfaces
+ do
+ egrep $i $tmp.list >> $tmp.chosen
+ done
+fi
+
+interfaces_sp=`cat $tmp.chosen | sort | uniq`
+loflag=false
+for iface in $interfaces_sp
+do
+ if [ "X$iface" = "Xlo0" ]
+ then
+ loflag=true
+ else
+ interfaces="$interfaces $iface"
+ fi
+done
+$loflag && interfaces="$interfaces lo0"
+ninterfaces=`echo $interfaces | wc -w`
+
+if $verbose
+then
+ echo "# Network interfaces Matching \"$argInterfaces\": $interfaces" >> $tmp.pmview
+fi
+
+if [ $ninterfaces = 0 ]
+then
+ echo "$prog: no matching network interfaces"
+ echo "Available interfaces on host \"$host\" are: " `cat $tmp.list`
+ echo ""
+ _usage
+ exit 1
+fi
+
+net_grid1=`expr $ninterfaces + 2`
+
+# --- how many CPUs on this system? ---
+#
+numcpu=`pminfo $msource -f $namespace hinv.ncpu 2>&1 | $PCP_AWK_PROG '
+BEGIN { num = 0 }
+$1 == "value" { if (NF == 2) num = $2 }
+END { print num }'`
+
+if [ $numcpu -lt 1 ]
+then
+ _pmview_fetch_indom kernel.percpu.cpu.user && numcpu=$number
+ if [ $numcpu -lt 1 ]
+ then
+ _pmview_error "$prog: Unable to determine the number of CPUs on host $host"
+ #NOTREACHED
+ fi
+fi
+
+maxcpu=`expr $maxcpu \* $numcpu`
+
+if $verbose
+then
+ if [ $numcpu = 1 ]
+ then
+ echo "# 1 CPU detected" >> $tmp.pmview
+ echo "#" >> $tmp.pmview
+ else
+ echo "# $numcpu CPUs detected" >> $tmp.pmview
+ echo "#" >> $tmp.pmview
+ fi
+fi
+
+# --- how much memory on this system? ---
+#
+realmem=0
+if pminfo -v $msource $namespace hinv.physmem > /dev/null 2>&1
+then
+ realmem=`pminfo -f $msource $namespace hinv.physmem | $PCP_AWK_PROG '/value/ { print $2 }'`
+ if [ -z "$realmem" ]
+ then
+ realmem=0
+ else
+ realmem=`expr $realmem \* 1024`
+ fi
+fi
+[ $realmem = 0 ] && echo "$prog: Warning: Unable to determine size of real memory for $host"
+
+
+# --- how many disks on this system? ---
+#
+numdisk=`pminfo $msource -f $namespace hinv.ndisk 2>&1 | $PCP_AWK_PROG '
+BEGIN { num = 0 }
+$1 == "value" { if (NF == 2) num = $2 }
+END { print num }'`
+
+if [ $numdisk -lt 0 ]
+then
+ _pmview_fetch_indom disk.dev.read && numdisk=$number
+ [ $numdisk -lt 0 ] && _pmview_warning "$prog: Unable to determine the number of disks for $host"
+fi
+
+if $verbose
+then
+ if [ $numdisk = 1 ]
+ then
+ echo "# 1 disk detected" >> $tmp.pmview
+ echo "#" >> $tmp.pmview
+ else
+ echo "# $numdisk disks detected" >> $tmp.pmview
+ echo "#" >> $tmp.pmview
+ fi
+fi
+
+
+# --- set the window title ---
+#
+if [ -z "$titleArg" ]
+then
+ titleArg="SGI PCP : Web Server Activity for Host $host"
+fi
+
+
+# --- set base strings for base plane objects ---
+#
+if [ $numcpu = 1 ]
+then
+ basestr_cpu="CPU Utilization\nSummed over 1 CPU"
+else
+ basestr_cpu="CPU Utilization\nSummed over $numcpu CPUs"
+fi
+
+basestr_mem="Physical Memory Utilization\nNormalized to `pminfo -f $msource mem.physmem | grep value | sed -e 's/ *value //'` Kbytes"
+
+basestr_disk="Read and Write activity for all Disks\nNormalized to $maxio I/Os per second"
+basestr_diskact="Average Disk Utilization\nNormalized to $maxbusy% across $numdisk disks"
+
+basestr_net="Input and Output on Network Interfaces\nPackets are normalized to $max packets per second"
+
+basestr_amem="Memory metrics which may indicate a problem\nNormalized to $maxerr events per second"
+basestr_atcp="TCP metrics which may indicate a problem\nNormalized to $maxerr events per second"
+
+basestr_size="HTTP request rate by response size in bytes\nNormalized to $maxreq hits per second"
+basestr_type="HTTP request rate by HTTP method\nNormalized to $maxreq hits per second"
+
+
+# ---- the real config starts here ---
+# pmview Version 2.1
+#
+cat << end-of-file >> $tmp.pmview
+
+_stackLength 26
+_marginWidth 8
+_marginDepth 8
+
+_colorList cpu_colors ( blue2 red2 yellow2 cyan2 )
+_colorList disk_colors ( violet yellow )
+_colorList memory_colors (
+ rgbi:1.0/1.0/0.0
+ rgbi:0.0/1.0/1.0
+ rgbi:1.0/0.0/0.0
+ rgbi:1.0/0.0/1.0
+ rgbi:0.0/0.0/1.0
+ rgbi:0.0/1.0/0.0
+)
+_colorList network_colors (
+ rgbi:0.8/0.0/0.0
+ rgbi:1.0/0.5/0.0
+ rgbi:0.0/0.8/0.0
+)
+_colorList type_colors (
+ rgbi:0.8/0.0/0.0
+ rgbi:1.0/1.0/0.6
+ rgbi:1.0/0.0/1.0
+ rgbi:0.0/1.0/1.0
+ rgbi:1.0/1.0/0.0
+)
+
+_colorList size_colors (
+ rgbi:1.0/0.35/0.0
+ rgbi:0.6/0.0/0.9
+ rgbi:0.0/1.0/0.0
+ rgbi:1.0/0.5/0.0
+ rgbi:0.65/0.3/1.0
+ rgbi:0.3/1.0/0.3
+ rgbi:1.0/0.65/0.3
+ rgbi:0.8/0.6/1.0
+ rgbi:0.6/1.0/0.6
+ rgbi:1.0/0.8/0.6
+)
+
+_grid _hide (
+
+#
+# Alarms
+#
+ _grid 1 0 6 2 south _hide (
+ _bar 0 1 6 1 west _row _groupbyrow (
+ _metrics (
+end-of-file
+
+for m in drops conndrops timeoutdrop rcvbadsum rexmttime sndrexmitpack attemptfails inerrs retranssegs
+do
+ if _pmview_fetch network.tcp.$m
+ then
+ echo " network.tcp.$m $maxerr" >> $tmp.pmview
+ fi
+done
+
+cat << end-of-file >> $tmp.pmview
+ )
+ _colorList (
+ red1 red1 red1 red1 red1 red1
+ )
+ _baseLabel "$basestr_atcp"
+ )
+ _bar 0 0 3 1 west _row _groupbyrow (
+ _metrics (
+end-of-file
+
+for m in swap.pagesout network.mbuf.failed network.mbuf.waited
+do
+ if _pmview_fetch $m
+ then
+ echo " $m $maxerr" >> $tmp.pmview
+ fi
+done
+
+cat << end-of-file >> $tmp.pmview
+ )
+ _colorList (
+ yellow rgbi:1.0/0.5/0.0 rgbi:1.0/0.5/0.0
+ )
+ _baseLabel "$basestr_amem"
+ )
+ _label 3 0 west _right _medium "Alarms"
+ )
+
+#
+# Size
+#
+ _bar 0 1 1 10 south _groupbycol (
+ _metrics (
+ web.allservers.requests.size.unknown $maxreq
+ web.allservers.requests.size.gt3m $maxreq
+ web.allservers.requests.size.le3m $maxreq
+ web.allservers.requests.size.le1m $maxreq
+ web.allservers.requests.size.le300k $maxreq
+ web.allservers.requests.size.le100k $maxreq
+ web.allservers.requests.size.le30k $maxreq
+ web.allservers.requests.size.le10k $maxreq
+ web.allservers.requests.size.le3k $maxreq
+ web.allservers.requests.size.zero $maxreq
+ )
+ _metriclabels _towards (
+ "?" ">3M" "3M" "1M" "300k"
+ "100k" "30k" "10k" "3k" "0k"
+ )
+ _colorList size_colors
+ _baseLabel "$basestr_size"
+ )
+
+ _label 0 11 northeast _right _medium "Size"
+
+#
+# Type
+#
+ _bar 1 6 1 5 south _groupbycol (
+ _metrics (
+ web.allservers.errors $maxerr
+ web.allservers.requests.other $maxreq
+ web.allservers.requests.post $maxreq
+ web.allservers.requests.head $maxreq
+ web.allservers.requests.get $maxreq
+ )
+ _colorList type_colors
+ _baseLabel "$basestr_type"
+ )
+
+ _label 1 11 north _right _medium "Type"
+
+#
+# System level stuff
+#
+ _grid 1 3 5 3 southwest (
+ _stack 0 0 (
+ _metrics (
+ kernel.all.cpu.user $maxcpu
+ kernel.all.cpu.sys $maxcpu
+ kernel.all.cpu.intr $maxcpu
+ kernel.all.cpu.wait.total $maxcpu
+ )
+ _colorList cpu_colors
+ _baseLabel "$basestr_cpu"
+ )
+ _label 0 1 north _right _medium "CPU"
+
+# 2 levels of base plane, halve the margin size and increase the height
+# for the inner one
+#
+_marginWidth 4
+_marginDepth 4
+_baseHeight 4
+
+ _grid 1 0 2 1 _show (
+ _baseColor rgbi:0.30/0.30/0.30
+ _stack 0 0 south _cylinder (
+ _metrics (
+ disk.all.write $maxio
+ disk.all.read $maxio
+ )
+ _colorList disk_colors
+ _baseLabel "$basestr_disk"
+ )
+end-of-file
+
+ # disk.all.avg_disk.active metric is not available from pcp 1.x
+ #
+ if _pmview_fetch disk.all.avg_disk.active
+ then
+ cat << end-of-file >> $tmp.pmview
+ _bar 1 0 _cylinder (
+ _metrics (
+ disk.all.avg_disk.active $maxactive
+ )
+ _colorList ( green2 )
+ _baseLabel "$basestr_diskact"
+ )
+end-of-file
+ fi
+
+ cat << end-of-file >> $tmp.pmview
+ _baseColor rgbi:0.15/0.15/0.15
+ )
+ _label 1 1 2 1 north _medium "Disk"
+
+end-of-file
+
+ if [ "X$realmem" != X0 -a "X$realmem" != X ]
+ then
+ xcoord=0
+
+ cat << end-of-file >> $tmp.pmview
+ _grid 3 0 2 1 _show (
+ _baseColor rgbi:0.30/0.30/0.30
+end-of-file
+
+ if _pmview_fetch mem.freemem
+ then
+ cat << end-of-file >> $tmp.pmview
+ _stack $xcoord 0 (
+ _metrics (
+ mem.freemem $realmem
+ )
+ _colorList ( rgbi:0.0/0.8/0.0 )
+ _baseLabel "Free memory"
+ )
+end-of-file
+ xcoord=`expr $xcoord + 1`
+ fi
+
+ if _pmview_fetch mem.util.kernel
+ then
+ cat << end-of-file >> $tmp.pmview
+
+ _stack $xcoord 0 (
+ _metrics (
+end-of-file
+ # Use all the metrics we have
+ for m in kernel fs_ctl fs_dirty fs_clean user ; do
+ if _pmview_fetch mem.util.$m
+ then
+ echo " mem.util.$m $realmem" >> $tmp.pmview
+ fi
+ done
+
+ cat << end-of-file >> $tmp.pmview
+ )
+ _colorList memory_colors
+ _baseLabel "$basestr_mem"
+ )
+end-of-file
+ xcoord=`expr $xcoord + 1`
+ fi
+
+ cat << end-of-file >> $tmp.pmview
+ _baseColor rgbi:0.15/0.15/0.15
+ )
+ _label 3 1 2 1 north _medium "Mem"
+end-of-file
+ fi
+
+ cat << end-of-file >> $tmp.pmview
+
+# restore defaults
+#
+ _marginWidth 8
+ _marginDepth 8
+ _baseHeight 2
+ )
+
+#
+# Network Stuff
+#
+ _grid 2 6 $net_grid1 5 south _hide (
+ _grid 0 0 1 2 west _hide (
+ _label 0 0 east _right _medium "In"
+ _label 0 1 east _right _medium "Out"
+ )
+# 2 levels of base plane, halve the margin size and increase the height
+# for the inner one
+#
+_marginWidth 4
+_marginDepth 4
+_baseHeight 4
+
+ _grid 1 0 $ninterfaces 2 _show (
+ _baseColor rgbi:0.30/0.30/0.30
+
+end-of-file
+
+ xcoord=0
+ yin=0
+ yout=1
+ for iface in $interfaces
+ do
+ cat << end-of-file >> $tmp.pmview
+
+ _stack $xcoord $yin (
+ _metrics (
+ network.interface.in.errors[$iface] $maxerr
+ network.interface.in.drops[$iface] $maxerr
+ network.interface.in.packets[$iface] $max
+ )
+ _colorList network_colors
+ _baseLabel "$basestr_net"
+ )
+ _stack $xcoord $yout (
+ _metrics (
+ network.interface.out.errors[$iface] $maxerr
+ network.interface.out.drops[$iface] $maxerr
+ network.interface.out.packets[$iface] $max
+ )
+ _colorList network_colors
+ _baseLabel "$basestr_net"
+ )
+end-of-file
+ xcoord=`expr $xcoord + 1`
+ done
+
+ cat << end-of-file >> $tmp.pmview
+ _baseLabel "$basestr_net"
+_baseColor rgbi:0.15/0.15/0.15
+ )
+# restore defaults
+#
+_marginWidth 8
+_marginDepth 8
+_baseHeight 2
+ _grid 1 2 $ninterfaces 2 _hide (
+end-of-file
+
+ xcoord=0
+ ylabel=0
+ for iface in $interfaces
+ do
+ cat << end-of-file >> $tmp.pmview
+ _label $xcoord $ylabel north _down _medium "$iface"
+end-of-file
+ xcoord=`expr $xcoord + 1`
+ done
+
+ cat << end-of-file >> $tmp.pmview
+ )
+ )
+ _label 3 11 northwest _right _medium "Network"
+)
+end-of-file
+
+$verbose && cat $tmp.pmview
+
+eval $PMVIEW <$tmp.pmview $args -title "'$titleArg'" -xrm "'*iconName: $prog'"
+
+exit
+
diff --git a/src/pmview/front-ends/webvis.rgb b/src/pmview/front-ends/webvis.rgb
new file mode 100644
index 0000000..5bd1482
--- /dev/null
+++ b/src/pmview/front-ends/webvis.rgb
Binary files differ