v09i059: xmeter, Part01/01
Rober Schwartzkopf
bobs at rand.org
Sat Sep 29 16:49:06 AEST 1990
Submitted-by: Rober Schwartzkopf <bobs at rand.org>
Posting-number: Volume 9, Issue 59
Archive-name: xmeter/part01
This is a complete repost of xmeter, with lots of new features,
improvements and bugfixes. Please see the README for details.
Don't feel bad if you missed patchlevels 3 and 4, they were never
posted. Thanks to everyone who contributed suggestions and fixes
to this release.
Bob Schwartzkopf (bobs at rand.org)
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: patchlevel.h README Imakefile xmeter.c xmeter.man
# XMeter.ad
# Wrapped by bobs at boris on Fri Sep 28 20:47:07 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 5
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1652 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xxmeter displays a histogram of data returned by rstat(3). It can be
Xtold to monitor multiple hosts, or to monitor multiple statistics on the
Xsame host.
X
XAuthor: Bob Schwartzkopf (bobs at rand.org)
X The RAND Corporation
X 1700 Main Street
X Santa Monica, CA 90406-2138
X
XEdit history
X
XPatchlevel 5
X - Put explict closes of sockets back in after clnt_destroy().
X Apparently some versions of clnt_destroy don't close the
X socket.
X - Minor changes to XMeter.ad.
X
XPatchlevel 4
X - Allow user to specify foreground, border, internal border and
X highlight color for each level.
X - Fixed bug in determining width/height of form widget.
X - Allow user to specify label foreground and background colors
X independently of stripcharts.
X - Made all colors either class Foreground or Background, should
X simplify .Xdefaults files.
X
XPatchlevel 3
X - Added "cols" and "rows" options, allows rectangular
X layout of graphs. Removed "orientation" option.
X - Backgrounds of stripcharts can now be set to user specified
X bitmaps with "*Bitmap" resources.
X - Added op, wp, ep and fp options, which takes a program name as an
X argument. When a graph enters state OK, WARN, ERROR or FATAL, the
X specified program is invoked.
X - Added menus which allow the monitored statistic to be changed
X on the fly.
X
XPatchlevel 2
X - Changed resource name of paned widgets to host name.
X - Used actual time between rstat(3) calls instead of "update"
X interval for computing graph values.
X - Rewrote functions that return graph values.
X - Fixed divide by 0 errors in fcpu(), fsys() and fuser().
X - Use RSTATVERS_TIME instead of RSTATVERS.
X
XPatchlevel 1
X - Fixed memory leak.
END_OF_FILE
if test 1652 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(369 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X INCLUDES = -I$(TOP) -I$(TOP)/X11
X DEPLIBS = XawClientDepLibs
XLOCAL_LIBRARIES = XawClientLibs
X SYS_LIBRARIES = -lrpcsvc
X SRCS = xmeter.c
X OBJS = xmeter.o
X SHARS = patchlevel.h README Imakefile xmeter.c xmeter.man XMeter.ad
X
XComplexProgramTarget(xmeter)
XInstallAppDefaults(XMeter)
X
Xxmeter.shar: $(SHARS)
X shar -o xmeter.shar $(SHARS)
END_OF_FILE
if test 369 -ne `wc -c <'Imakefile'`; then
echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'xmeter.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xmeter.c'\"
else
echo shar: Extracting \"'xmeter.c'\" \(31247 characters\)
sed "s/^X//" >'xmeter.c' <<'END_OF_FILE'
X/*
X * xmeter.c - Display histogram of rstat(3) output for multiple hosts.
X *
X * Author: Bob Schwartzkopf, The RAND Corporation
X *
X * Suggestions for improvements and bug fixes can be sent to "bobs at rand.org".
X * As my schedule permits I'll try to incorporate them.
X */
X
X#ifndef lint
Xstatic char *RCSid="$Header: /tmp_mnt/home/src/rand/bin/xmeter/RCS/xmeter.c,v 1.6 90/09/28 20:32:34 root Exp $";
X#endif lint
X
X/*
X * $Log: xmeter.c,v $
X * Revision 1.6 90/09/28 20:32:34 root
X * Add explicit closes of sockets back in, apparently some versions of
X * clnt_destroy() don't do it automatically.
X *
X * Revision 1.5 90/09/18 20:47:03 root
X * Allow user specification of foreground colors.
X *
X * Revision 1.4 90/08/20 14:18:01 root
X * Added menus, column and row options, background bitmaps, and user
X * specifiable programs to be invoked when graphs change state.
X *
X * Revision 1.3 90/06/07 16:17:06 bobs
X * Removed "retries".
X * Changed name of paned widgets to host name displayed in that widget.
X * Used actual time between rstat calls instead of "update" interval in
X * computing rates in functions that return values to stripchart widgets.
X * Removed "ost" variable, rewrote functions that return values to
X * stripcharts.
X * Fixed bug in fsys, fcpu and fuser that could cause divide by 0 errors.
X * Fixed rpc timeout handling in getmeter and getport.
X * Use RSTATVERS_TIME instead of RSTATVERS, which isn't defined in SunOS 4.1.
X *
X * Revision 1.2 90/05/04 12:31:52 bobs
X * Fix memory leak in getport(). Wasn't freeing resources allocated by
X * clntudp_create when clnt_call failed. Also removed explicit calls
X * to close sockets since clnt_destroy() does this.
X *
X * Revision 1.1 90/04/30 14:33:59 bobs
X * Initial revision
X *
X */
X
X#include <stdio.h>
X#include <sys/time.h>
X#include <sys/param.h>
X#include <sys/socket.h>
X#include <sys/dk.h>
X#include <signal.h>
X#include <netdb.h>
X#include <rpc/rpc.h>
X#include <rpc/pmap_prot.h>
X#include <rpcsvc/rstat.h>
X#include <X11/Xlib.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Xatom.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Cardinals.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/StripChart.h>
X#include <X11/Xaw/SimpleMenu.h>
X#include <X11/Xaw/MenuButton.h>
X#include <X11/Xaw/SmeBSB.h>
X#include <X11/Xaw/Paned.h>
X#include <X11/Xmu/Xmu.h>
X
X#define DMSG "down"
X#define OK 0
X#define WARN 1
X#define ERROR 2
X#define FATAL 3
X#define MAXBACKS (FATAL+1)
X#define STATMENU "statmenu"
X#ifndef FSCALE
X#define FSCALE (1 << 8)
X#endif
X
X/*
X * There is one METER structure per strip chart. If multiple stats
X * on a single host are being watched we save rstatd calls by sharing
X * part of this structure (SHMETER) between the different meters watching
X * the same host.
X */
Xtypedef struct _shmeter {
X char *name; /* Host name */
X struct sockaddr_in addr;
X CLIENT *clnt;
X int s; /* Socket */
X struct statstime st[2]; /* Keep last 2 stats to compute diffs */
X int idx; /* Index into st array */
X int refcnt; /* Meters sharing this structure */
X int curcnt; /* Meters who've displayed current data */
X int first; /* TRUE when only 1 rstat has been done */
X struct _shmeter *nxt; /* Link these together */
X} SHMETER;
X
Xtypedef struct _meter {
X char *label;
X int stat; /* Which stat to watch */
X Widget pdwidget; /* Paned widget */
X Widget mbwidget; /* MenuButton widget */
X Widget scwidget; /* StripChart widget */
X int oldstate; /* Save state so know when to */
X /* change backgrounds */
X SHMETER *sh; /* Shared info */
X Pixmap pm; /* Current background pixmap */
X struct _meter *nxt;
X} METER;
X
X/*
X * There is a STATDATA structure for each statistic that can be monitored.
X */
Xtypedef struct {
X int scale; /* Each stat is scaled */
X int (*val)(); /* Function that computes this stat */
X char *name; /* Name of stat for menu widget */
X} STATDATA;
X
X/*
X * xmeter supports 4 background colors and pixmaps that it will switch
X * between as a meter changes state, called OK, WARN, ERROR and FATAL.
X * The background bitmaps are stored in BITMAP structures.
X */
Xtypedef struct {
X int w; /* Width of bitmap */
X int h; /* Height of bitmap */
X Pixmap bm; /* Bitmap */
X} BITMAP;
X
X/*
X * Functions
X */
Xextern char *malloc ();
Xextern char *index ();
Xint getstatus ();
Xint changestat ();
Xint selecthost ();
Xint freechild ();
XMETER *initmeter ();
Xint fcoll (), fcpu (), fierr (), fintr (), fipkt (), fload ();
Xint foerr (), fopkt (), fpage (), fpgpgin (), fpgpgout ();
Xint fpswpin (), fpswpout (), fswt (), fsys (), fuser ();
X
XSTATDATA sd[] = {
X#define S_COLL 0
X {1, fcoll, "coll"},
X#define S_CPU S_COLL+1
X {1, fcpu, "cpu"},
X#define S_IERR S_CPU+1
X {1, fierr, "ierr"},
X#define S_INTR S_IERR+1
X {1, fintr, "intr"},
X#define S_IPKT S_INTR+1
X {1, fipkt, "ipkt"},
X#define S_LOAD S_IPKT+1
X {1, fload, "load"},
X#define S_OERR S_LOAD+1
X {1, foerr, "oerr"},
X#define S_OPKT S_OERR+1
X {1, fopkt, "opkt"},
X#define S_PAGE S_OPKT+1
X {1, fpage, "page"},
X#define S_PGPGIN S_PAGE+1
X {1, fpgpgin, "pgpgin"},
X#define S_PGPGOUT S_PGPGIN+1
X {1, fpgpgout, "pgpgout"},
X#define S_PSWPIN S_PGPGOUT+1
X {1, fpswpin, "pswpin"},
X#define S_PSWPOUT S_PSWPIN+1
X {1, fpswpout, "pswpout"},
X#define S_SWT S_PSWPOUT+1
X {1, fswt, "swt"},
X#define S_SYS S_SWT+1
X {1, fsys, "sys"},
X#define S_USER S_SYS+1
X {1, fuser, "user"},
X};
X#define DEFSTAT S_LOAD
X#define MAXSTAT (sizeof (sd) / sizeof (STATDATA))
X#define MAXSTATNAME 10 /* Max length of stat name */
X
Xstatic char *progname;
XPixel back[MAXBACKS]; /* Meter backgrounds */
XPixel fore[MAXBACKS]; /* Meter foregrounds */
XPixel hl[MAXBACKS]; /* Meter highlights */
XPixel bd[MAXBACKS]; /* Meter borders */
XPixel ibd[MAXBACKS]; /* Meter internal bds */
XPixel lback[MAXBACKS]; /* Label backgrounds */
XPixel lfore[MAXBACKS]; /* Label foregrounds */
XBITMAP bitmap[MAXBACKS]; /* Stripchart bg pixmaps*/
XPixmap bitmapdef = XtUnspecifiedPixmap;
Xint warnLevel; /* Warning level */
Xint errorLevel; /* Error level */
Xstatic struct timeval ptto = {0, 0}; /* RPC timeout interval */
Xstatic struct timeval tto = {0, 0}; /* Total timeout */
Xstatic SHMETER *shmeters = NULL; /* List of SHMETERs */
Xstatic METER *selected; /* Current meter */
Xstatic METER *meterlist = NULL; /* List of METERs */
Xint columns; /* Columns to display */
Xint rows; /* Rows to display */
Xint timeout; /* RPC timeout */
Xint retries; /* RPC retries */
Xint loadscaledef = FSCALE; /* Scale for load ave. */
XBoolean shortname; /* Short hostname flag */
XString prog[MAXBACKS]; /* Alert programs */
Xstatic XtResource application_resources[] = {
X {"columns", "Columns", XtRInt, sizeof (int),
X (Cardinal) &columns, XtRString, "0"},
X {"errorBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &back[ERROR], XtRString, XtDefaultBackground},
X {"errorBd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &bd[ERROR], XtRString, XtDefaultForeground},
X {"errorBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap),
X (Cardinal) &bitmap[ERROR].bm, XtRBitmap, (caddr_t) &bitmapdef},
X {"errorFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &fore[ERROR], XtRString, XtDefaultForeground},
X {"errorHl", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &hl[ERROR], XtRString, XtDefaultForeground},
X {"errorIbd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &ibd[ERROR], XtRString, XtDefaultForeground},
X {"errorLevel", "ErrorLevel", XtRInt, sizeof (int),
X (Cardinal) &errorLevel, XtRString, "6"},
X {"errorProg", "Program", XtRString, sizeof (char *),
X (Cardinal) &prog[ERROR], XtRString, NULL},
X {"fatalBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &back[FATAL], XtRString, XtDefaultBackground},
X {"fatalBd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &bd[FATAL], XtRString, XtDefaultForeground},
X {"fatalBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap),
X (Cardinal) &bitmap[FATAL].bm, XtRBitmap, (caddr_t) &bitmapdef},
X {"fatalFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &fore[FATAL], XtRString, XtDefaultForeground},
X {"fatalHl", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &hl[FATAL], XtRString, XtDefaultForeground},
X {"fatalIbd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &ibd[FATAL], XtRString, XtDefaultForeground},
X {"fatalProg", "Program", XtRString, sizeof (char *),
X (Cardinal) &prog[FATAL], XtRString, NULL},
X {"lErrorBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lback[ERROR], XtRString, XtDefaultBackground},
X {"lErrorFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lfore[ERROR], XtRString, XtDefaultForeground},
X {"lFatalBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lback[FATAL], XtRString, XtDefaultBackground},
X {"lFatalFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lfore[FATAL], XtRString, XtDefaultForeground},
X {"lOkBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lback[OK], XtRString, XtDefaultBackground},
X {"lOkFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lfore[OK], XtRString, XtDefaultForeground},
X {"lWarnBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lback[WARN], XtRString, XtDefaultBackground},
X {"lWarnFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &lfore[WARN], XtRString, XtDefaultForeground},
X {"okBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &back[OK], XtRString, XtDefaultBackground},
X {"okBd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &bd[OK], XtRString, XtDefaultForeground},
X {"okBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap),
X (Cardinal) &bitmap[OK].bm, XtRBitmap, (caddr_t) &bitmapdef},
X {"okFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &fore[OK], XtRString, XtDefaultForeground},
X {"okHl", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &hl[OK], XtRString, XtDefaultForeground},
X {"okIbd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &ibd[OK], XtRString, XtDefaultForeground},
X {"okProg", "Program", XtRString, sizeof (char *),
X (Cardinal) &prog[OK], XtRString, NULL},
X {"retries", "Retries", XtRInt, sizeof (int),
X (Cardinal) &retries, XtRString, "2"},
X {"rows", "Rows", XtRInt, sizeof (int),
X (Cardinal) &rows, XtRString, "0"},
X {"scaleColl", "ScaleColl", XtRInt, sizeof (int),
X (Cardinal) &sd[S_COLL].scale, XtRString, "1"},
X {"scaleCpu", "ScaleCpu", XtRInt, sizeof (int),
X (Cardinal) &sd[S_CPU].scale, XtRString, "20"},
X {"scaleIerr", "ScaleIerr", XtRInt, sizeof (int),
X (Cardinal) &sd[S_IERR].scale, XtRString, "1"},
X {"scaleIntr", "ScaleIntr", XtRInt, sizeof (int),
X (Cardinal) &sd[S_INTR].scale, XtRString, "50"},
X {"scaleIpkt", "ScaleIpkt", XtRInt, sizeof (int),
X (Cardinal) &sd[S_IPKT].scale, XtRString, "20"},
X {"scaleLoad", "ScaleLoad", XtRInt, sizeof (int),
X (Cardinal) &sd[S_LOAD].scale, XtRInt, (caddr_t) &loadscaledef},
X {"scaleOerr", "ScaleOerr", XtRInt, sizeof (int),
X (Cardinal) &sd[S_OERR].scale, XtRString, "1"},
X {"scaleOpkt", "ScaleOpkt", XtRInt, sizeof (int),
X (Cardinal) &sd[S_OPKT].scale, XtRString, "20"},
X {"scalePage", "ScalePage", XtRInt, sizeof (int),
X (Cardinal) &sd[S_PAGE].scale, XtRString, "10"},
X {"scalePgpgin", "ScalePgpgin", XtRInt, sizeof (int),
X (Cardinal) &sd[S_PGPGIN].scale, XtRString, "10"},
X {"scalePgpgout", "ScalePgpgout", XtRInt, sizeof (int),
X (Cardinal) &sd[S_PGPGOUT].scale, XtRString, "10"},
X {"scalePswpin", "ScalePswpin", XtRInt, sizeof (int),
X (Cardinal) &sd[S_PSWPIN].scale, XtRString, "1"},
X {"scalePswpout", "ScalePswpout", XtRInt, sizeof (int),
X (Cardinal) &sd[S_PSWPOUT].scale, XtRString, "1"},
X {"scaleSwt", "ScaleSwt", XtRInt, sizeof (int),
X (Cardinal) &sd[S_SWT].scale, XtRString, "30"},
X {"scaleSys", "ScaleSys", XtRInt, sizeof (int),
X (Cardinal) &sd[S_SYS].scale, XtRString, "20"},
X {"scaleUser", "ScaleUser", XtRInt, sizeof (int),
X (Cardinal) &sd[S_USER].scale, XtRString, "20"},
X {"shortName", "Shortname", XtRBoolean, sizeof (Boolean),
X (Cardinal) &shortname, XtRString, "False"},
X {"timeout", "Timeout", XtRInt, sizeof (int),
X (Cardinal) &timeout, XtRString, "5"},
X {"warnBack", XtCBackground, XtRPixel, sizeof (Pixel),
X (Cardinal) &back[WARN], XtRString, XtDefaultBackground},
X {"warnBd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &bd[WARN], XtRString, XtDefaultForeground},
X {"warnBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap),
X (Cardinal) &bitmap[WARN].bm, XtRBitmap, (caddr_t) &bitmapdef},
X {"warnFore", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &fore[WARN], XtRString, XtDefaultForeground},
X {"warnHl", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &hl[WARN], XtRString, XtDefaultForeground},
X {"warnIbd", XtCForeground, XtRPixel, sizeof (Pixel),
X (Cardinal) &ibd[WARN], XtRString, XtDefaultForeground},
X {"warnLevel", "WarnLevel", XtRInt, sizeof (int),
X (Cardinal) &warnLevel, XtRString, "3"},
X {"warnProg", "Program", XtRString, sizeof (char *),
X (Cardinal) &prog[WARN], XtRString, NULL},
X};
Xstatic XrmOptionDescRec options[] = {
X {"-cols", "columns", XrmoptionSepArg, NULL},
X {"-ebd", "errorBd", XrmoptionSepArg, NULL},
X {"-ebg", "errorBack", XrmoptionSepArg, NULL},
X {"-efg", "errorFore", XrmoptionSepArg, NULL},
X {"-ehl", "errorHl", XrmoptionSepArg, NULL},
X {"-eibd", "errorIbd", XrmoptionSepArg, NULL},
X {"-elevel", "errorLevel", XrmoptionSepArg, NULL},
X {"-ep", "errorProg", XrmoptionSepArg, NULL},
X {"-fbd", "fatalBd", XrmoptionSepArg, NULL},
X {"-fbg", "fatalBack", XrmoptionSepArg, NULL},
X {"-ffg", "fatalFore", XrmoptionSepArg, NULL},
X {"-fhl", "fatalHl", XrmoptionSepArg, NULL},
X {"-fibd", "fatalIbd", XrmoptionSepArg, NULL},
X {"-fp", "fatalProg", XrmoptionSepArg, NULL},
X {"-h", "*Paned.height", XrmoptionSepArg, NULL},
X {"-lebg", "lErrorBack", XrmoptionSepArg, NULL},
X {"-lefg", "lErrorFore", XrmoptionSepArg, NULL},
X {"-lfbg", "lFatalBack", XrmoptionSepArg, NULL},
X {"-lffg", "lFatalFore", XrmoptionSepArg, NULL},
X {"-lobg", "lOkBack", XrmoptionSepArg, NULL},
X {"-lofg", "lOkFore", XrmoptionSepArg, NULL},
X {"-lwbg", "lWarnBack", XrmoptionSepArg, NULL},
X {"-lwfg", "lWarnFore", XrmoptionSepArg, NULL},
X {"-obd", "okBd", XrmoptionSepArg, NULL},
X {"-obg", "okBack", XrmoptionSepArg, NULL},
X {"-ofg", "okFore", XrmoptionSepArg, NULL},
X {"-ohl", "okHl", XrmoptionSepArg, NULL},
X {"-oibd", "okIbd", XrmoptionSepArg, NULL},
X {"-op", "okProg", XrmoptionSepArg, NULL},
X {"-rows", "rows", XrmoptionSepArg, NULL},
X {"-rt", "retries", XrmoptionSepArg, NULL},
X {"-scoll", "scaleColl", XrmoptionSepArg, NULL},
X {"-scpu", "scaleCpu", XrmoptionSepArg, NULL},
X {"-sierr", "scaleIerr", XrmoptionSepArg, NULL},
X {"-sintr", "scaleIntr", XrmoptionSepArg, NULL},
X {"-sipkt", "scaleIpkt", XrmoptionSepArg, NULL},
X {"-sload", "scaleLoad", XrmoptionSepArg, NULL},
X {"-sn", "shortName", XrmoptionNoArg, "on"},
X {"-soerr", "scaleOerr", XrmoptionSepArg, NULL},
X {"-sopkt", "scaleOpkt", XrmoptionSepArg, NULL},
X {"-spage", "scalePage", XrmoptionSepArg, NULL},
X {"-spgpgin", "scalePgpgin", XrmoptionSepArg, NULL},
X {"-spgpgout", "scalePgpgout", XrmoptionSepArg, NULL},
X {"-spswpin", "scalePswpin", XrmoptionSepArg, NULL},
X {"-spswpout", "scalePswpout", XrmoptionSepArg, NULL},
X {"-sswt", "scaleSwt", XrmoptionSepArg, NULL},
X {"-ssys", "scaleSys", XrmoptionSepArg, NULL},
X {"-suser", "scaleUser", XrmoptionSepArg, NULL},
X {"-to", "timeout", XrmoptionSepArg, NULL},
X {"-update", "*StripChart.update", XrmoptionSepArg, NULL},
X {"-w", "*Paned.width", XrmoptionSepArg, NULL},
X {"-wbd", "warnBd", XrmoptionSepArg, NULL},
X {"-wbg", "warnBack", XrmoptionSepArg, NULL},
X {"-wfg", "warnFore", XrmoptionSepArg, NULL},
X {"-whl", "warnHl", XrmoptionSepArg, NULL},
X {"-wibd", "warnIbd", XrmoptionSepArg, NULL},
X {"-wlevel", "warnLevel", XrmoptionSepArg, NULL},
X {"-wp", "warnProg", XrmoptionSepArg, NULL},
X};
Xstatic Arg formargs[] = {
X {XtNdefaultDistance, 1}, /* Spacing */
X {XtNresizable, TRUE }, /* Resizable */
X};
X
Xmain (argc, argv)
X
Xint argc;
Xchar **argv;
X
X{
X Widget toplevel;
X Widget form;
X Widget pane = NULL;
X int i;
X int n;
X Arg args[10];
X XtAppContext appcon;
X String mbtrans =
X "<EnterWindow>: highlight()\n\
X <LeaveWindow>: reset()\n\
X <BtnDown>: set() notify() PopupMenu()";
X XtTranslations mbtt;
X Widget *lw; /* Last column or row of widgets */
X int numwgt;
X
X progname = argv[0];
X toplevel = XtAppInitialize (&appcon, "XMeter", options,
X XtNumber (options), &argc, argv, NULL, NULL, ZERO);
X XtGetApplicationResources (toplevel, NULL, application_resources,
X XtNumber (application_resources), NULL, 0);
X form = XtCreateManagedWidget ("form", formWidgetClass, toplevel,
X formargs, XtNumber (formargs));
X if (argc < 2)
X usage ();
X init (toplevel, &lw);
X createmenus (form);
X mbtt = XtParseTranslationTable (mbtrans);
X /*
X * Each meter consists of a paned widget, each paned widget has two
X * children, which are a menubutton widget and stripchart widget.
X * The following loop creates and initializes the appropriate widgets.
X */
X for (i = 1, numwgt = 0; i < argc; i++, numwgt++) {
X meterlist = initmeter (meterlist, &i, argc, argv);
X /*
X * Create paned widget.
X */
X n = 0;
X if (columns > 0) { /* Locate pane in form ... */
X XtSetArg (args[n], XtNfromVert, lw[numwgt % columns]); n++;
X if (numwgt % columns != 0) {
X XtSetArg (args[n], XtNfromHoriz, pane); n++;
X }
X } else {
X XtSetArg (args[n], XtNfromHoriz, lw[numwgt % rows]); n++;
X if (numwgt % rows != 0) {
X XtSetArg (args[n], XtNfromVert, pane); n++;
X }
X }
X XtSetArg (args[n], XtNborder, bd[OK]); n++;
X XtSetArg (args[n], XtNinternalBorderColor, ibd[OK]); n++;
X pane = XtCreateManagedWidget (meterlist->sh->name, panedWidgetClass,
X form, args, n);
X lw[numwgt % (columns > 0 ? columns : rows)] = pane;
X meterlist->pdwidget = pane;
X /*
X * Create menubutton widget.
X */
X n = 0;
X XtSetArg (args[n], XtNshowGrip, XtEno); n++;
X XtSetArg (args[n], XtNlabel, meterlist->label); n++;
X XtSetArg (args[n], XtNbackground, lback[OK]); n++;
X XtSetArg (args[n], XtNforeground, lfore[OK]); n++;
X XtSetArg (args[n], XtNmenuName, STATMENU); n++;
X XtSetArg (args[n], XtNtranslations, mbtt); n++;
X meterlist->mbwidget = XtCreateManagedWidget ("menu",
X menuButtonWidgetClass, pane, args, n);
X XtRemoveAllCallbacks (meterlist->mbwidget, XtNcallback);
X XtAddCallback (meterlist->mbwidget, XtNcallback, selecthost, meterlist);
X /*
X * Create stripchart widget.
X */
X n = 0;
X XtSetArg (args[n], XtNfromVert, meterlist->mbwidget); n++;
X XtSetArg (args[n], XtNresizable, TRUE); n++;
X XtSetArg (args[n], XtNbackground, back[OK]); n++;
X XtSetArg (args[n], XtNforeground, fore[OK]); n++;
X XtSetArg (args[n], XtNhighlight, hl[OK]); n++;
X meterlist->scwidget = XtCreateManagedWidget ("load",
X stripChartWidgetClass, pane, args, n);
X XtRemoveAllCallbacks (meterlist->scwidget, XtNgetValue);
X XtAddCallback (meterlist->scwidget, XtNgetValue, getstatus, meterlist);
X }
X free (lw);
X signal (SIGCHLD, freechild); /* Clean up after our children */
X XtRealizeWidget (toplevel);
X setokbackgrounds (XtDisplay (toplevel), XtScreen (toplevel));
X XtAppMainLoop (appcon);
X}
X
Xusage ()
X
X{
X int i;
X
X fprintf (stderr, "Usage: %s [toolkit options] [options] [stat] host ...\n",
X progname);
X fprintf (stderr, " Options are:");
X for (i = 0; i < XtNumber (options); i++) {
X if (i % 8 == 0)
X fprintf (stderr, "\n ");
X else
X fprintf (stderr, ", ");
X fprintf (stderr, "%s", options[i].option);
X }
X fprintf (stderr, "\n Stats to watch are:");
X for (i = 0; i < MAXSTAT; i++) {
X if (i % 8 == 0)
X fprintf (stderr, "\n ");
X else
X fprintf (stderr, ", ");
X fprintf (stderr, "-%s", sd[i].name);
X }
X fprintf (stderr, "\n");
X exit (1);
X}
X
X/*
X * init - Initialze various globals.
X */
Xinit (toplevel, lw)
X
XWidget toplevel;
XWidget **lw;
X
X{
X int i;
X Window rw;
X int x;
X int y;
X int bwidth;
X int depth;
X
X ptto.tv_sec = timeout;
X tto.tv_sec = timeout * retries;
X if (columns <= 0 && rows <= 0)
X columns = 1;
X if (columns > 0) {
X if ((*lw = (Widget *) calloc (columns, sizeof (Widget))) == NULL)
X fatal ("lw");
X } else
X if ((*lw = (Widget *) calloc (rows, sizeof (Widget))) == NULL)
X fatal ("lw");
X for (i = 0; i < MAXBACKS; i++)
X if (bitmap[i].bm != bitmapdef) /* Get bitmap dimensions */
X XGetGeometry (XtDisplay (toplevel), bitmap[i].bm, &rw, &x, &y,
X &bitmap[i].w, &bitmap[i].h, &bwidth, &depth);
X}
X
X/*
X * createmenus - Create menus used by each meter. Currently there's just
X * one which consists of the stats that can be monitored.
X */
Xcreatemenus (parent)
X
XWidget parent;
X
X{
X int i;
X int n;
X Widget menu;
X Widget me;
X Arg args[10];
X
X menu = XtCreatePopupShell (STATMENU, simpleMenuWidgetClass, parent,
X NULL, ZERO);
X for (i = 0; i < MAXSTAT; i++) {
X n = 0;
X XtSetArg (args[n], XtNlabel, sd[i].name); n++;
X me = XtCreateManagedWidget (sd[i].name, smeBSBObjectClass, menu,
X args, n);
X XtRemoveAllCallbacks (me, XtNcallback);
X XtAddCallback (me, XtNcallback, changestat, i);
X }
X}
X
X/*
X * setokbackgrounds - Set initial background pixmaps. Can't do this
X * when the stripchart widgets are created as they have to be
X * realized apparently before the pixmaps can be created.
X */
Xsetokbackgrounds (d, s)
X
XDisplay *d;
XScreen *s;
X
X{
X METER *h;
X int n;
X Arg args[10];
X
X if (bitmap[OK].bm != bitmapdef) {
X for (h = meterlist; h; h = h->nxt) {
X h->pm = XmuCreatePixmapFromBitmap (d, XtWindow (h->scwidget),
X bitmap[OK].bm,
X bitmap[OK].w, bitmap[OK].h,
X DefaultDepthOfScreen (s),
X fore[OK],
X back[OK]);
X n = 0;
X XtSetArg (args[n], XtNbackgroundPixmap, h->pm); n++;
X XtSetValues (h->scwidget, args, n);
X }
X }
X}
X
X/*
X * freechild - Clean up child processes.
X */
Xfreechild ()
X
X{
X int status;
X
X wait (&status);
X}
X
X/*
X * getstatus - Get status from remote host, update meter appropriately,
X * including changing colors, background pixmap and label if necessary.
X */
Xgetstatus (w, h, data)
X
XWidget w;
XMETER *h;
Xchar *data;
X
X{
X int l;
X int n;
X int s;
X register SHMETER *sh;
X Arg args[10];
X
X s = state (l = getmeter (h), h);
X *(double *) data = s == FATAL ? 0.0 : (double) l / sd[h->stat].scale;
X sh = h->sh;
X if (s != h->oldstate) {
X if (bitmap[h->oldstate].bm != bitmapdef)
X XFreePixmap (XtDisplay (w), h->pm);
X n = 0; /* Update stripchart widget */
X XtSetArg (args[n], XtNbackground, back[s]); n++;
X XtSetArg (args[n], XtNforeground, fore[s]); n++;
X XtSetArg (args[n], XtNhighlight, hl[s]); n++;
X if (bitmap[s].bm != bitmapdef) {
X h->pm = XmuCreatePixmapFromBitmap (XtDisplay (w),
X XtWindow (w),
X bitmap[s].bm,
X bitmap[s].w, bitmap[s].h,
X DefaultDepthOfScreen(XtScreen(w)),
X fore[s],
X back[s]);
X XtSetArg (args[n], XtNbackgroundPixmap, h->pm); n++;
X } else if (bitmap[h->oldstate].bm != bitmapdef) {
X XtSetArg (args[n], XtNbackgroundPixmap, XtUnspecifiedPixmap); n++;
X }
X XtSetValues (w, args, n);
X n = 0; /* Update menubutton widget */
X XtSetArg (args[n], XtNbackground, lback[s]); n++;
X XtSetArg (args[n], XtNforeground, lfore[s]); n++;
X if (s == FATAL || h->oldstate == FATAL) {
X sprintf (h->label, "%s %s", sh->name,
X s == FATAL ? DMSG : sd[h->stat].name);
X XtSetArg (args[n], XtNlabel, h->label); n++;
X }
X XtSetValues (h->mbwidget, args, n);
X n = 0; /* Update paned widget */
X XtSetArg (args[n], XtNborder, bd[s]); n++;
X XtSetArg (args[n], XtNinternalBorderColor, ibd[s]); n++;
X XtSetValues (h->pdwidget, args, n);
X if (prog[s])
X runprog (h, s);
X }
X h->oldstate = s;
X}
X
X/*
X * runprog - Run user specified alert program.
X */
Xrunprog (h, s)
X
XMETER *h;
Xint s;
X
X{
X char oldstate[4];
X char state[4];
X
X sprintf (oldstate, "%d", h->oldstate);
X sprintf (state, "%d", s);
X if (vfork ())
X return; /* Parent just returns */
X execlp (prog[s], prog[s], oldstate, state, h->sh->name, NULL);
X fatal (prog[s]);
X}
X
X/*
X * selecthost - Select host for next changestat().
X */
Xselecthost (w, h, data)
X
XWidget w;
XMETER *h;
Xchar *data;
X
X{
X selected = h;
X}
X
X/*
X * changestat - Change statistic we're looking at.
X */
Xchangestat (w, statidx, data)
X
XWidget w;
Xint statidx;
Xchar *data;
X
X{
X int n;
X Arg args[10];
X
X selected->stat = statidx;
X sprintf (selected->label, "%s %s", selected->sh->name,
X sd[statidx].name);
X n = 0;
X XtSetArg (args[n], XtNlabel, selected->label); n++;
X XtSetValues (selected->mbwidget, args, n);
X}
X
X/*
X * state - Return state of current stat.
X */
Xint state (l, h)
X
Xint l;
XMETER *h;
X
X{
X if (l < 0)
X return (FATAL);
X else if (l < warnLevel * sd[h->stat].scale)
X return (OK);
X else if (l < errorLevel * sd[h->stat].scale)
X return (WARN);
X else
X return (ERROR);
X}
X
X/*
X * The following functions return the value of the specified stat, which
X * is normally computed by taking the difference between the current
X * value and the previous value, and dividing by the update interval in
X * order to get the current rate.
X */
X#define DIF(m,fld) (m->sh->st[m->sh->idx].fld - \
X m->sh->st[m->sh->idx ^ 1].fld)
X
Xint fcoll (h)
X
XMETER *h;
X
X{
X return (DIF (h, if_collisions) / DIF (h, curtime.tv_sec));
X}
X
Xint fcpu (h)
X
XMETER *h;
X
X{
X int i;
X int t;
X int d[CPUSTATES];
X
X for (t = 0, i= 0; i < CPUSTATES; i++)
X t += (d[i] = DIF (h, cp_time[i]));
X return (t ? (100 * (d[CP_USER]+d[CP_NICE]+d[CP_SYS])) / t : 0);
X}
X
Xint fierr (h)
X
XMETER *h;
X
X{
X return (DIF (h, if_ierrors) / DIF (h, curtime.tv_sec));
X}
X
Xint fintr (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_intr) / DIF (h, curtime.tv_sec));
X}
X
Xint fipkt (h)
X
XMETER *h;
X
X{
X return (DIF (h, if_ipackets) / DIF (h, curtime.tv_sec));
X}
X
Xint fload (h)
X
XMETER *h;
X
X{
X return (h->sh->st[h->sh->idx].avenrun[0]);
X}
X
Xint foerr (h)
X
XMETER *h;
X
X{
X return (DIF (h, if_oerrors) / DIF (h, curtime.tv_sec));
X}
X
Xint fopkt (h)
X
XMETER *h;
X
X{
X return (DIF (h, if_opackets) / DIF (h, curtime.tv_sec));
X}
X
Xint fpage (h)
X
XMETER *h;
X
X{
X return ((DIF (h, v_pgpgin) + DIF (h, v_pgpgout)) / DIF (h, curtime.tv_sec));
X}
X
Xint fpgpgin (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_pgpgin) / DIF (h, curtime.tv_sec));
X}
X
Xint fpgpgout (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_pgpgout) / DIF (h, curtime.tv_sec));
X}
X
Xint fpswpin (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_pswpin) / DIF (h, curtime.tv_sec));
X}
X
Xint fpswpout (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_pswpout) / DIF (h, curtime.tv_sec));
X}
X
Xint fswt (h)
X
XMETER *h;
X
X{
X return (DIF (h, v_swtch) / DIF (h, curtime.tv_sec));
X}
X
Xint fsys (h)
X
XMETER *h;
X
X{
X int i;
X int t;
X int d[CPUSTATES];
X
X for (t = 0, i= 0; i < CPUSTATES; i++)
X t += (d[i] = DIF (h, cp_time[i]));
X return (t ? (100 * d[CP_SYS]) / t : 0);
X}
X
Xint fuser (h)
X
XMETER *h;
X
X{
X int i;
X int t;
X int d[CPUSTATES];
X
X for (t = 0, i= 0; i < CPUSTATES; i++)
X t += (d[i] = DIF (h, cp_time[i]));
X return (t ? (100 * (d[CP_USER] + d[CP_NICE])) / t : 0);
X}
X
X/*
X * getmeter - Executes rstat(3) call to read statistics for specified host.
X * I do all the rpc junk myself so that I have better control over timeouts
X * than rstat(3) gives me. If we're watching multiple stats
X * on the same host I only do one rstat(3) call (refcnt and curcnt are
X * used for this).
X */
Xint getmeter (h)
X
Xregister METER *h;
X
X{
X enum clnt_stat cs;
X register SHMETER *sh;
X int p;
X
X sh = h->sh;
X if (sh->curcnt >= sh->refcnt)
X sh->curcnt = 0;
X if (!sh->curcnt++) {
X if (sh->clnt == NULL) {
X if ((p = getport (h)) < 0)
X return (-1);
X sh->addr.sin_port = p;
X sh->s = RPC_ANYSOCK;
X if (!(sh->clnt = clntudp_create(&sh->addr, RSTATPROG, RSTATVERS_TIME,
X ptto, &sh->s)))
X return (-1);
X sh->first = 1;
X sh->idx = 0;
X } else {
X sh->first = 0;
X sh->idx ^= 1;
X }
X cs = clnt_call (sh->clnt, RSTATPROC_STATS, xdr_void, 0, xdr_statstime,
X &sh->st[sh->idx], tto);
X if (cs != RPC_SUCCESS) {
X clnt_destroy (sh->clnt);
X close (sh->s); /* Some clnt_destroy's don't do this */
X sh->clnt = NULL;
X return (-1);
X }
X }
X return (sh->first ? 0 :
X sh->clnt == NULL ? -1 : (sd[h->stat].val) (h));
X}
X
X/*
X * getport - Get port rstatd is listening on.
X */
Xint getport (h)
X
XMETER *h;
X
X{
X CLIENT *c;
X enum clnt_stat cs;
X static struct pmap pm = {RSTATPROG, RSTATVERS_TIME, IPPROTO_UDP, 0};
X short p;
X register SHMETER *sh;
X
X sh = h->sh;
X sh->s = RPC_ANYSOCK;
X sh->addr.sin_port = htons (PMAPPORT);
X if (!(c = clntudp_create (&sh->addr, PMAPPROG, PMAPVERS, ptto, &sh->s)))
X return (-1);
X cs = clnt_call (c, PMAPPROC_GETPORT, xdr_pmap, &pm, xdr_u_short, &p, tto);
X clnt_destroy (c);
X close (sh->s); /* Some clnt_destroy's don't do this */
X return (cs == RPC_SUCCESS ? p : -1);
X}
X
X/*
X * initmeter - Fill in METER and SHMETER structures for this stat.
X */
XMETER *initmeter (meterlist, idx, argc, argv)
X
XMETER *meterlist;
Xint *idx;
Xint argc;
Xchar **argv;
X
X{
X register METER *h;
X register SHMETER *sh;
X struct hostent *he;
X int i;
X char *cp;
X
X /*
X * Create and fill in METER struct.
X */
X if (!(h = (METER *) malloc (sizeof (METER))))
X fatal ("METER");
X h->nxt = meterlist;
X if (argv[*idx][0] == '-') {
X for (i = 0; i < MAXSTAT; i++)
X if (strcmp (&argv[*idx][1], sd[i].name) == 0) {
X h->stat = i;
X break;
X }
X if (++(*idx) == argc || i >= MAXSTAT)
X usage ();
X } else
X h->stat = DEFSTAT;
X if ((he = gethostbyname (argv[*idx])) == NULL)
X fatal (argv[*idx]);
X if (shortname)
X if (cp = index (he->h_name, '.'))
X *cp = '\0';
X if (!(h->label = malloc (strlen (he->h_name) + 2 + MAXSTATNAME)))
X fatal ("label");
X sprintf (h->label, "%s %s", he->h_name, sd[h->stat].name);
X h->oldstate = OK;
X /*
X * If we're already looking at this host then just point h->sh at
X * existing structure and we're done.
X */
X for (sh = shmeters; sh; sh = sh->nxt)
X if (strcmp (sh->name, he->h_name) == 0) {
X h->sh = sh;
X sh->refcnt++; /* Count how many references */
X return (h);
X }
X /*
X * Not looking at this host yet, create and fill in SHMETER struct.
X */
X if (!(sh = (SHMETER *) malloc (sizeof (SHMETER))))
X fatal ("SHMETER");
X sh->nxt = shmeters; /* Save this struct in linked list */
X shmeters = sh;
X h->sh = sh;
X if (!(sh->name = malloc (strlen (he->h_name) + 1)))
X fatal ("name");
X strcpy (sh->name, he->h_name);
X bcopy (he->h_addr, &sh->addr.sin_addr, he->h_length);
X sh->addr.sin_family = AF_INET;
X sh->clnt = NULL;
X sh->refcnt = 1;
X sh->curcnt = 0;
X return (h);
X}
X
Xfatal (m)
X
Xchar *m;
X
X{
X perror (m);
X exit (1);
X}
END_OF_FILE
if test 31247 -ne `wc -c <'xmeter.c'`; then
echo shar: \"'xmeter.c'\" unpacked with wrong size!
fi
# end of 'xmeter.c'
fi
if test -f 'xmeter.man' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xmeter.man'\"
else
echo shar: Extracting \"'xmeter.man'\" \(13833 characters\)
sed "s/^X//" >'xmeter.man' <<'END_OF_FILE'
X.TH XMETER 1 "14 August 1989" "X Version 11"
X.SH NAME
Xxmeter - rstat display for X
X.SH SYNOPSIS
X.B xmeter
X[-\fItoolkitoption\fP ...] [-\fIoption\fP ...] [-\fIstat\fP] hosts ...
X.SH DESCRIPTION
X.I Xmeter
Xdisplays a periodically updating histogram of the system statistics
Xgathered by rstat(3) for the specified hosts. Meters can be
Xdisplayed in a vertical, horizontal or rectangular arrangement. As
Xstatistics range between 4 user defineable levels (OK, WARN, ERROR
Xor FATAL), the background, foreground, highlight, border and internal
Xborder colors and the background bitmap of each meter can be changed.
X.LP
X.I Xmeter
Xuses the StripChart widget of the Athena Widget Set to graph each
Xstatistic. StripCharts automatically scale the graph as the value
Xvaries, by drawing a number of horizontal lines across the StripChart.
XEach line represents an increment of a user settable value. For
Xexample, if the statistic being graphed is number of pages paged in
Xper second, and the scale is set to 10, then each horizontal line
Xwould represent 10 pages per second. Each time a graph is updated,
X.I xmeter
Xwill examine the current value of the statistic and the current scale,
Xas the number of scale lines increases above
X.I wlevel
Xand
X.I elevel
Xthe background colors and bitmaps of each graph are modified as specified.
X.LP
XThe statistic being graphed may be modified while
X.I xmeter
Xis running by moving the mouse cursor into the label part of a graph,
Xclicking any mouse button, and sliding down to the desired stat.
X.SH OPTIONS
X.PP
X.I Xmeter
Xaccepts all of the standard X Toolkit command line options along with the
Xfollowing additional options:
X.PP
X.TP 8
X.B \-cols \fIcols\fP
XThis option specifies the number of columns the meters should be
Xdisplayed in. If both
X.I cols
Xand
X.I rows
Xare specified,
X.I cols
Xtakes precedence. The default is 1 column.
X.PP
X.TP 8
X.B \-ebd \fIcolor\fP
XSet error level border color.
X.PP
X.TP 8
X.B \-ebg \fIcolor\fP
XSet error level background color.
X.PP
X.TP 8
X.B \-efg \fIcolor\fP
XSet error level foreground color.
X.PP
X.TP 8
X.B \-ehl \fIcolor\fP
XSet error level highlight color.
X.PP
X.TP 8
X.B \-eibd \fIcolor\fP
XSet error level internal border color.
X.PP
X.TP 8
X.B \-elevel \fIinteger\fP
XThis option specifies the level at which the background color is changed
Xto ebg. The default is 6.
X.PP
X.TP 8
X.B \-ep \fIprogram\fP
X.I program
Xshould be the name of a program to be invoked when the meter enters the
Xerror state.
X.I program
Xwill be passed 3 arguments, oldstate, newstate and the hostname being
Xmonitored. Oldstate and newstate will be integers ranging from 0 to
X3, corresponding to levels OK, WARN, ERROR and FATAL.
X.PP
X.TP 8
X.B \-fbd \fIcolor\fP
XSet fatal level border color.
X.PP
X.TP 8
X.B \-fbg \fIcolor\fP
XSet fatal level background color.
X.PP
X.TP 8
X.B \-ffg \fIcolor\fP
XSet fatal level foreground color.
X.PP
X.TP 8
X.B \-fhl \fIcolor\fP
XSet fatal level highlight color.
X.PP
X.TP 8
X.B \-fibd \fIcolor\fP
XSet fatal level internal border color.
X.PP
X.TP 8
X.B \-fp \fIprogram\fP
X.I program
Xshould be the name of a program to be invoked when the monitored host is
Xdown.
X.I program
Xwill be passed 3 arguments, oldstate, newstate and the hostname being
Xmonitored. Oldstate and newstate will be integers ranging from 0 to
X3, corresponding to levels OK, WARN, ERROR and FATAL.
X.PP
X.TP 8
X.B \-h \fIpixels\fP
XThis option specifies the height of each chart
X.I xmeter
Xwill display. The default is 80.
X.PP
X.TP 8
X.B \-lebg \fIcolor\fP
XSet error level background color in menubutton.
X.PP
X.TP 8
X.B \-lefg \fIcolor\fP
XSet error level foreground color in menubutton.
X.PP
X.TP 8
X.B \-lfbg \fIcolor\fP
XSet fatal level background color in menubutton.
X.PP
X.TP 8
X.B \-lffg \fIcolor\fP
XSet fatal level foreground color in menubutton.
X.PP
X.TP 8
X.B \-lobg \fIcolor\fP
XSet ok level background color in menubutton.
X.PP
X.TP 8
X.B \-lofg \fIcolor\fP
XSet ok level foreground color in menubutton.
X.PP
X.TP 8
X.B \-lwbg \fIcolor\fP
XSet warn level background color in menubutton.
X.PP
X.TP 8
X.B \-lwfg \fIcolor\fP
XSet warn level foreground color in menubutton.
X.PP
X.TP 8
X.B \-obd \fIcolor\fP
XSet ok level border color.
X.PP
X.TP 8
X.B \-obg \fIcolor\fP
XSet ok level background color.
X.PP
X.TP 8
X.B \-ofg \fIcolor\fP
XSet ok level foreground color.
X.PP
X.TP 8
X.B \-ohl \fIcolor\fP
XSet ok level highlight color.
X.PP
X.TP 8
X.B \-oibd \fIcolor\fP
XSet ok level internal border color.
X.PP
X.TP 8
X.B \-op \fIprogram\fP
X.I program
Xshould be the name of a program to be invoked when the meter enters WARN
Xstate.
X.I program
Xwill be passed 3 arguments, oldstate, newstate and the hostname being
Xmonitored. Oldstate and newstate will be integers ranging from 0 to
X3, corresponding to levels OK, WARN, ERROR and FATAL.
X.PP
X.TP 8
X.B \-rows \fIrows\fP
XThis option specifies the number of rows the meters should be
Xdisplayed in. If both
X.I cols
Xand
X.I rows
Xare specified,
X.I cols
Xtakes precedence. The default is 1 column.
X.PP
X.TP 8
X.B \-rt \fIretries\fP
XThis option specifies the number of times to retry failed RPC calls.
XThe default is 2.
X.PP
X.TP 8
X.B \-scoll \fIinteger\fP
XSet scale for collisions. The default is 1.
X.PP
X.TP 8
X.B \-scpu \fIinteger\fP
XSet scale for cpu time. The default is 20.
X.PP
X.TP 8
X.B \-sierr \fIinteger\fP
XSet scale for input errors. The default is 1.
X.PP
X.TP 8
X.B \-sintr \fIinteger\fP
XSet scale for interrupts. The default is 50.
X.PP
X.TP 8
X.B \-sipkt \fIinteger\fP
XSet scale for input packets. The default is 20.
X.PP
X.TP 8
X.B \-sload \fIinteger\fP
XSet scale for load average. The default is FSCALE (see param.h).
X.PP
X.TP 8
X.B \-sn
XIf specified strips off domain part of host name in menubuttons.
X.PP
X.TP 8
X.B \-soerr \fIinteger\fP
XSet scale for output errors. The default is 1.
X.PP
X.TP 8
X.B \-sopkt \fIinteger\fP
XSet scale for output packets. The default is 20.
X.PP
X.TP 8
X.B \-spage \fIinteger\fP
XSet scale for pages paged in and out. The default is 10.
X.PP
X.TP 8
X.B \-spgpgin \fIinteger\fP
XSet scale for pages paged in. The default is 10.
X.PP
X.TP 8
X.B \-spgpgout \fIinteger\fP
XSet scale for pages paged out. The default is 10.
X.PP
X.TP 8
X.B \-spswpin \fIinteger\fP
XSet scale for pages swapped in. The default is 1.
X.PP
X.TP 8
X.B \-spswpout \fIinteger\fP
XSet scale for pages swapped out. The default is 1.
X.PP
X.TP 8
X.B \-sswt \fIinteger\fP
XSet scale for context switches. The default is 30.
X.PP
X.TP 8
X.B \-ssys \fIinteger\fP
XSet scale for sys time. The default is 20.
X.PP
X.TP 8
X.B \-suser \fIinteger\fP
XSet scale for user time. The default is 20.
X.PP
X.TP 8
X.B \-to \fIseconds\fP
XThis option specifies the timeout for RPC calls. The default is 5 seconds.
X.PP
X.TP 8
X.B \-update \fIseconds\fP
XThis option specifies the frequency in seconds at which
X.I xmeter
Xupdates its display. The minimum amount of time allowed between updates
Xis 5 seconds. The default is 60 seconds.
X.PP
X.TP 8
X.B \-w \fIpixels\fP
XThis option specifies the width of each chart
X.I xmeter
Xwill display. The default is 80.
X.PP
X.TP 8
X.B \-wbd \fIcolor\fP
XSet warn level border color.
X.PP
X.TP 8
X.B \-wbg \fIcolor\fP
XSet warn level background color.
X.PP
X.TP 8
X.B \-wfg \fIcolor\fP
XSet warn level foreground color.
X.PP
X.TP 8
X.B \-whl \fIcolor\fP
XSet warn level highlight color.
X.PP
X.TP 8
X.B \-wibd \fIcolor\fP
XSet warn level internal border color.
X.PP
X.TP 8
X.B \-wlevel \fIinteger\fP
XThis option specifies the level at which the background color is changed
Xto wbg. The default is 3.
X.PP
X.TP 8
X.B \-wp \fIprogram\fP
X.I program
Xshould be the name of a program to be invoked when the meter enters
XWARN state.
X.I program
Xwill be passed 3 arguments, oldstate, newstate and the hostname being
Xmonitored. Oldstate and newstate will be integers ranging from 0 to
X3, corresponding to levels OK, WARN, ERROR and FATAL.
X.SH STATISTICS
X.PP
X.TP 8
X.B \-coll
XGraph number of collisions per second.
X.PP
X.TP 8
X.B \-cpu
XGraph percentage of non idle time for the specified host.
X.PP
X.TP 8
X.B \-ierr
XGraph number of input errors per second.
X.PP
X.TP 8
X.B \-intr
XGraph number of interrupts per second.
X.PP
X.TP 8
X.B \-ipkt
XGraph number of input packets per second.
X.PP
X.TP 8
X.B \-load
XGraph 1 minute load average.
X.PP
X.TP 8
X.B \-oerr
XGraph number of output errors per second.
X.PP
X.TP 8
X.B \-opkt
XGraph number of output packets per second.
X.PP
X.TP 8
X.B \-page
XSum of pgpgin and pgpgout values.
X.PP
X.TP 8
X.B \-pgpgin
XGraph number of pages paged in per second.
X.PP
X.TP 8
X.B \-pgpgout
XGraph number of pages paged out per second.
X.PP
X.TP 8
X.B \-pswpin
XGraph number of swapins per second.
X.PP
X.TP 8
X.B \-pswpout
XGraph number of swapouts per second.
X.PP
X.TP 8
X.B \-swt
XGraph number of context switches per second.
X.PP
X.TP 8
X.B \-sys
XGraph percentage of system time for the specified host.
X.PP
X.TP 8
X.B \-user
XGraph percentage of user time for the specified host.
X.SH "WIDGET HIERARCHY"
XThe widget hierarchy for
X.I xmeter
Xis given below. Class names are given first, followed by instance
Xnames.
X.sp
X.nf
XXMeter xmeter
X Form form
X SimpleMenu statmenu
X SmeBSB <stat>
X Paned <hostname>
X MenuButton menu
X StripChart load
X.SH "RESOURCES"
XThe following resources are defined. Resource instance names
Xare specified first, followed by class name.
X.PP
X.TP 8
X.B columns Columns
XSet number of columns of display.
X.PP
X.TP 8
X.B errorBack Background
XError level background color.
X.PP
X.TP 8
X.B errorBd Foreground
XError level border color.
X.PP
X.TP 8
X.B errorBitmap Bitmap
XError level background bitmap.
X.PP
X.TP 8
X.B errorFore Foreground
XError level foreground color.
X.PP
X.TP 8
X.B errorHl Foreground
XError level highlight color.
X.PP
X.TP 8
X.B errorIbd Foreground
XError level internal border color.
X.PP
X.TP 8
X.B errorLevel ErrorLevel
XWhen a statistic is above this value colors and bitmaps are
Xset to the appropriate error level value.
X.PP
X.TP 8
X.B errorProg Program
XProgram to be invoked when a meter enters error state.
X.PP
X.TP 8
X.B fatalBack Background
XBackground color of dead hosts.
X.PP
X.TP 8
X.B fatalBd Foreground
XBorder color of dead hosts.
X.PP
X.TP 8
X.B fatalBitmap Bitmap
XBackground bitmap of dead hosts.
X.PP
X.TP 8
X.B fatalFore Foreground
XForeground color of dead hosts.
X.PP
X.TP 8
X.B fatalHl Foreground
XHighlight color of dead hosts.
X.PP
X.TP 8
X.B fatalIbd Foreground
XInternal border color of dead hosts.
X.PP
X.TP 8
X.B fatalProg Program
XProgram to be invoked when a meter enters fatal state.
X.PP
X.TP 8
X.B lErrorBack Background
XError level background color of menubutton widget.
X.PP
X.TP 8
X.B lErrorFore Foreground
XError level foreground color of menubutton widget.
X.PP
X.TP 8
X.B lFatalBack Background
XFatal level background color of menubutton widget.
X.PP
X.TP 8
X.B lFatalFore Foreground
XFatal level foreground color of menubutton widget.
X.PP
X.TP 8
X.B lOkBack Background
XOk level background color of menubutton widget.
X.PP
X.TP 8
X.B lOkFore Foreground
XOk level foreground color of menubutton widget.
X.PP
X.TP 8
X.B lWarnBack Background
XWarn level background color of menubutton widget.
X.PP
X.TP 8
X.B lWarnFore Foreground
XWarn level foreground color of menubutton widget.
X.PP
X.TP 8
X.B okBack Background
XOk level background color.
X.PP
X.TP 8
X.B okBd Foreground
XOk level border color.
X.PP
X.TP 8
X.B okBitmap Bitmap
XOk level background bitmap.
X.PP
X.TP 8
X.B okFore Foreground
XOk level foreground color.
X.PP
X.TP 8
X.B okHl Foreground
XOk level highlight color.
X.PP
X.TP 8
X.B okIbd Foreground
XOk level internal border color.
X.PP
X.TP 8
X.B okProg Program
XProgram to be invoked when a meter enters ok state.
X.PP
X.TP 8
X.B retries Retries
XNumber of retries for RPC calls.
X.PP
X.TP 8
X.B rows Rows
XNumber of rows to display.
X.PP
X.TP 8
X.B scaleColl ScaleColl
XScale for interface collisions.
X.PP
X.TP 8
X.B scaleCpu ScaleCpu
XScale for percentage cpu usage.
X.PP
X.TP 8
X.B scaleIerr ScaleIerr
XScale for interface input errors.
X.PP
X.TP 8
X.B scaleIerr ScaleIntr
XScale for interface interrupts.
X.PP
X.TP 8
X.B scaleIpkt ScaleIpkt
XScale for interface input packets.
X.PP
X.TP 8
X.B scaleLoad ScaleLoad
XScale for load average.
X.PP
X.TP 8
X.B scaleOerr ScaleOerr
XScale for interface output errors.
X.PP
X.TP 8
X.B scaleOpkt ScaleOpkt
XScale for interface output packets.
X.PP
X.TP 8
X.B scalePage ScalePage
XScale for paging (sum of pageins and pageouts).
X.PP
X.TP 8
X.B scalePgpgin ScalePgpgin
XScale for pages paged in.
X.PP
X.TP 8
X.B scalePgpgout ScalePgpgout
XScale for pages paged out.
X.PP
X.TP 8
X.B scalePswpin ScalePswpin
XScale for swap ins.
X.PP
X.TP 8
X.B scalePswpout ScalePswpout
XScale for swap outs.
X.PP
X.TP 8
X.B scaleSwt ScaleSwt
XScale for context switches.
X.PP
X.TP 8
X.B scaleSys ScaleSys
XScale for percentage system time.
X.PP
X.TP 8
X.B scaleUser ScaleUser
XScale for percentage user time.
X.PP
X.TP 8
X.B shortName ShortName
XTrim domains off host names.
X.PP
X.TP 8
X.B timeout Timeout
XTimeout for RPC calls.
X.PP
X.TP 8
X.B warnBack Background
XWarn level background color.
X.PP
X.TP 8
X.B warnBd Foreground
XWarn level border color.
X.PP
X.TP 8
X.B warnBitmap Bitmap
XWarn level Background bitmap.
Xbelow ErrorLevel.
X.PP
X.TP 8
X.B warnFore Foreground
XWarn level foreground color.
X.PP
X.TP 8
X.B warnHl Foreground
XWarn level highlight color.
X.PP
X.TP 8
X.B warnIbd Foreground
XWarn level internal border.
X.PP
X.TP 8
X.B warnLevel WarnLevel
XWhen statistic is above this level and below ErrorLevel background colors
Xand bitmaps are set to WarnBack and WarnBitmap.
X.PP
X.TP 8
X.B warnProg Program
XProgram to be invoked when a meter enters warn state.
X.SH BUGS
XWhen a host doesn't respond it can sometimes take awhile for the labels
Xin the menubuttons to update.
X.LP
XIf a height for the meters is specified but not a width, the error
X"Widget has zero width and/or height" is printed by the X toolkit.
XThe converse is not true. I suspect the problem is in the Paned
Xwidget but xmeter could be doing something wrong. The supplied
Xapplication defaults file initializes both width and height, as long
Xas this is installed there shouldn't be a problem unless the user
Xexplicitly sets width to 0.
X.SH AUTHORS
XBob Schwartzkopf, The RAND Corporation. Based on xload from MIT.
END_OF_FILE
if test 13833 -ne `wc -c <'xmeter.man'`; then
echo shar: \"'xmeter.man'\" unpacked with wrong size!
fi
# end of 'xmeter.man'
fi
if test -f 'XMeter.ad' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'XMeter.ad'\"
else
echo shar: Extracting \"'XMeter.ad'\" \(80 characters\)
sed "s/^X//" >'XMeter.ad' <<'END_OF_FILE'
XXMeter*Paned.Width: 80
XXMeter*Paned.Height: 80
XXMeter*StripChart.Interval: 60
END_OF_FILE
if test 80 -ne `wc -c <'XMeter.ad'`; then
echo shar: \"'XMeter.ad'\" unpacked with wrong size!
fi
# end of 'XMeter.ad'
fi
echo shar: End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list