Appendices

Appendix A: NetSpy User Manual

A.1 Starting the Collection Service

The collection service for DPML-MCS is the executable file, nsserv.<os> where <os> is one of:
This process should be started in the background and left to run. If it is desired to include extra statistics the path names of the executable files exporting the extra statistics (see Appendix B for more information) should be passed as parameters on the command line. For example:
nsserv.<os> ./bin/extraStats1 ./bin/extraStats2

The collection service displays status messages to standard output indicating when a client connects (i.e. when NetSpy starts up communication with this collection service) and one clients disconnect.

A.2 Starting NetSpy

The NetSpy executable file is netspy. To start NetSpy simply execute this file from the Unix shell. After a sign-on message on the console, a window that looks like the following should appear on the workstation display:

Figure A-1: Main NetSpy screen after startup

This is the main NetSpy window, and it is from here that NetSpy functions are performed.

A.3 Connecting to a Collection Service

To be able to monitor statistics from a particular computer NetSpy must connect to the collection service running on that computer. To do this, the user uses the "Add host..." menu item in the "Hosts" menu.

This menu selection will bring up the "Add New Host" dialog box. This dialog box has the following appearance:

Figure A-2: "Add New Host" dialog box

The user is required to enter the name of the computer to be monitored into the text field. Upon selection of the "OK" button an attempt is made to contact the collection service running at the computer. An error will be returned given any of the following conditions:

If a successful connection to a new computer is made, the statistics being selected by that computer will be available in the "New Connection" dialog box (see below).

A.4 Adding a Shape Gadget to the Scene

Shape gadgets are used to actually see the value of the statistics that are being monitored. In order to add a shape gadget to the scene the user selects the "Add shape..." option from the "Scene" menu. This option brings up the "Add New Shape" dialog box:

Figure A-3: "Add New Shape" dialog box

The various elements of this dialog box are described here:

Shape Type
This list contains all of the shape gadgets available to the user. One shape only must be selected from this list. This designates which shape will be drawn.
Shape Name
Every shape must be given a unique name by which it is identified in the other dialogs of the system. This name is entered in this text box. The name should not contain white space of commas. An error will occur if a duplicate name is used.
Distributor Type
This radio button group allows the user to choose the type of distributor to use when dealing with multiple instances of a statistic.
Note: at this time the hierarchy distributor has not been implemented.
Arranger
This list displays the different arrangers available for laying copies of the shape gadget. This is necessary when there are multiple instances of a statistic and NetSpy must create multiple copies of a shape gadget to display the various instances. One arranger only must be selected from the list.
Attach to:
This list contains the names of all of the arranger objects within the scene to which this new shape object can be assigned. It will then be the responsibility of that gadget to place it within the scene. The [root] arranger is the default arranger for the whole scene. It is always present.

A.5 Adding a New Arranger to the Scene

For scenes involving more than a couple of shapes it is desirable to break the scene up into smaller groups. Each of these groups requires an arranger to help lay that part out. By selecting the "Add arranger..." option from the "Scene" menu, the user is presented with the following dialog:

Figure A-4: "Add New Arranger" dialog box

This dialog allows the user to place another arranger gadget into the scene for grouping shape gadgets together. These arrangers gadgets will appear in the "Attach to:" list of the "New Shape Dialog". The various fields of this dialog are:

Arranger Type
This list shows all of the different arrangers available to the user. One arranger only must be selected from this list.
Arranger Name
This text field is where the identifying name for this gadget is entered. The name must be unique amongst all of the gadgets within this scene. The name may not contain white space or commas.
Attach to:
The list contains the list of all of the arranger objects to which this new arranger can be attached. That existing arranger object will then be responsible for laying out the subscene created by this new arranger.

A.6 Connecting a Statistic to a Gadget

Once the desired shape has been added to the scene, and connection to the desired computer has been made it is necessary to connect a statistic to a degree of freedom on that shape. The dialog for doing this (pictured below) is obtained by selecting "Add connection..." from the "Scene" menu:

Figure A-5: "Add New Connection" dialog box

The fields in this dialog box are:

Host
This list shows the names of all of the computers from which statistics are being collected. One host only must be selected from this list.
Metric
This list shows all of the statistics being collected from the host currently selected in the "Host" list. Changing the selected host will cause this list to update its contents.
Shape
This list shows all of the shape gadgets in the scene that export degrees of freedom. One shape only must be selected from this list.
Degree
This list contains the list of all the degrees of freedom exported by the currently selected shape gadget in the "Shape" list. If the selection in the "Shape" list is changed, this list will automatically update. One degree only must be selected from this list

When the user selects the "OK" button a connection is established between the chosen statistic and the degree of freedom.

A.7 Navigating Within a Scene

There are a couple of major controls on the NetSpy main window which allow the user to navigate around the visualization scene. The following screen shot shows the controls for rotation, zoom and camera movement.

Figure A-6: Rotation, zoom, and camera movement controls

The viewer controls are shown in the following figure:

Figure A-7: Viewer controls

A.8 Saving and Loading Scenes

Once a scene has been created it is useful to save it so that it can be recalled when necessary. This can be done by selecting the "Save As..." option from the "File" menu. This will bring open the file selection dialog box which allows the user to select the name and destination of the file to store the current scene. The extension to be used for scene files is ".ns".

Once a scene has been saved once, any additions made can be saved to the same file (overwriting the old one) using the "Save" option from the "File" menu.

To load a scene file previously saved use the "Open..." option from the "File" menu. This will bring up the file selection dialog box (similar to the one for saving files) to allow the user to select the file to load. By default, only those files ending in ".ns" are displayed. This can be changed manually though.


Appendix B: DPML-MCS Protocol Description

This section is designed for programmers or network administrators wishing to extend the number and type of statistics collected by a DPML-MCS collection service running on a particular computer. For this to be possible, an executable program must be written that outputs information to standard output. The output must conform to the output defined in this section. The files in the DPML directory of the source distribution contain a set of C++ classes that will help the prospective programmer in this task. These files are known to compile under g++ version 2.7.0 and the Silicon Graphics C++ compiler available on Irix 5.3.

The protocol defines two distinct sections that must be included: a preamble and the body. The preamble consists of the details of the statistics being collected here. The body, which is of indefinite duration once it begins is the values of these statistics, updated at some regular interval.

B.1 Preamble

The preamble consists of a number of lines of ASCII text that conform to the following format:
<metric name> <ID> <Type> <Semantics> <Units> [<Instance>...]
where:
<metric name>
A string uniquely identifying this statistic. The string should only contain alphanumeric characters and '.'.
<ID>
A unique integer indentifier for this statistic. Numbers above 5000 and included are set aside for the use by external statistic sources. The lower numbers are reserved for built in statistics.
<Type>
An integer indentifying the data type of this statistic. At present the only supported types are:
  • 0 - Undefined
  • 1 - Long (32-bit) integer
  • 2 - Floating point number
<Semantics
An integer indicating the semantics of this statistic. Supported values and their meanings are:
  • 0 - Monotonically increasing counter
  • 1 - Instantaneous value in the continuous domain
<Units>
This is reserved for future use. For now the number 0 should be used as a place holder. If anything else is sent these sources may not work with future versions of the DPML-MCS.
<Instance>
One or more instances definitions (see below).
An instance is defined by the following text:
<instance name> <ID>
where:
<instance name>
A string describing this instance of the statistic. The same restrictions apply to this string as to the metric name string.
ID
An integer uniquely identifying this instance. Note: these IDs must be unique within the metric IDs as well. That is, an instance ID should never be the same as any metric ID. The standard practice is to number the statistic IDs in intervals of 100, and to number the instance IDs in intervals of 1 starting at the statistic ID+1.
If a statistic is a singular instance, for example the number of users logged into a computer then there should be no instances defined for that statistic in the preamble. A singular instance is different from a statistic in which for this computer there is only one instance!

Each statistic definition line in the preamble must be followed by a newline character (ASCII 10). After all of the statistics have been defined the line:

!!end!!
followed by a newline character should be output.

B.2 Body

Once the preamble has been sent the body follows. The body consists of a single line of ASCII characters followed by a newline character sent once every interval. The interval is defined on as command line parameter to the collecting process and is an integral number of seconds.

The format of the line is as follows:

<metric ID> <Values> [<metric ID> <Values> ...
where <Values> is of the form:
0 <value>
for single instance statistics, and:
<instance ID> <value> [<instance ID> <value> ...
The various elements are defined as:
<metric ID>
The indentifying integer for this statistic as defined in the preamble.
<instance ID>
The indentifying integer for this instance of the statistic as defined in the preamble.
<value>
The actual value of the statistic at this reading.
The program should go on collecting and outputting statistics until it is killed.


Appendix C: Gadget Creation

This section is for the programmer who wishes to create his own gadgets for NetSpy. New gadgets are created by writing code in C++ and compiling it into NetSpy. There is a sub-section describing what must be done each for each different kind of gadget.

Firstly there is some common code that must be included for every kind of gadget. This code is related to the run-time identification of gadget types. At certain points it is necessary for NetSpy to check that gadgets are of the necessary type, for example when the user connects a statistic to a gadget that gadget must be a distributor. The following methods must be implemented following the pattern described:

Constructors
Each new gadget class must provide two constructors. As an example, if our new gadget class is called NewShapeGadget, the two constructors must be:
NewShapeGadget( int id = -1 )
NewShapeGadget( const string& name, int id = -1 )
The first constructor should call the constructor of the second form in the base class with the name parameter set to a string which contains the class name.

virtual const string className()
Must return the name of the class as a string. For example, if a new class called NewShapeGadget was created to implement a new gadget, it should be implemented as:
{ return "NewShapeGadget"; }

virtual int isOfType( const string& type )
The new class should check to see if the string type is the same as the class name. If it is, the function should return 1. If it is not, then the class should call the isOfType() method of the parent class with the same paramter. For example, if again we are creating the NewShapeGadget class that is derived from the GadgetBase class, then the resultant code should be:
virtual int NewShapeType::isOfType( const string& type )
{
    if( type == NewShapeType::className() )
        return 1;
    return GadgetBase::isOfType( type );
}

virtual GadgetBase* copy( const string& name )
This method is usually only called on the master gadget instance of this gadget. This method should return a new instance of this class, it having been created with name given as the parameter. The standard implementation (for our example new gadget NewShapeGadget is:
virtual GadgetBase* NewShapeGadget::copy( const string& name )
{
    NewShapeGadget* nsg = new NewShapeGadget(name);
    copyData(nsg);
    return nsg;
}

virtual void copyData( GadgetBase* gb )
It is not necessary to implement this method unless there is some data in the new class that needs to be copied from the master gadget when this gadget the copy() method is called. In most cases, it is not necessary to implement this method.

C.1 Shape Gadgets

Shape gadgets are those gadgets which actually present some shape on the screen. They have one or more degrees of freedom which modify the visual appearance in some manner. These gadget types must implement the following methods:

virtual void createSceneGraph()
This method is called by the getSceneGraph() method in the GadgetBase class if the separator node for this shape gadget has not been created. It is the responsibility of this method to create this separator node, and then to add to this node the rest of the scene graph that defines the shape for this gadget. The code to create the separator node is:
m_root = new SoSeparator;
It is the responsibility of the class to maintain pointers to the nodes in its scene graph that are modified by the degrees of freedom.

virtual void animate()
It is necessary only to implement this method if the gadget performs some form of animation. For example, some part of the shape may rotate, and the rate of rotation is defined as one of the degrees of freedom. This method is provided to let a gadget adjust its scene graph to perform animation. If this gadget is implemented it is necessary for the object to register itself with the application object. This is done by the following line of code, which is usually included at the end of the createSceneGraph() method:
theApp->getScene().addToAnimate( this );

Degrees of Freedom Callbacks
For each degree of freedom exported by a gadget it is necessary to register a callback method for each degree. The callback function has the following prototype:
static void <degree>Callback( GadgetBase*, Value& )
Standard practice is to provide a similar non-static method with the following prototype, given that our new class is called NewShapeGadget:
void <degree>Change( Value& )
and to implement the static member as follows:
    static void <degree>Callback( GadgetBase* gb, Value& value )
    { ((NewGadgetShape*)gb)-><degree>Change( value ); }
To register the callback functions the the addCallback() member of GadgetBase should be called in the constructor. If our new class is called NewShapeGadget and it exports a degree called "size" the call to this member would be as follows:
addCallback( "size", &NewShapeGadget::sizeCallback )

C.2 Arranger Gadgets

Arranger gadgets are used to layout the scenes. They are responsible for inserting transform nodes into their portion of the scene graph as well as the scene graphs created by the various other gadgets they are arranging. In order to accomplish these feats the following methods must be implemented:
virtual GadgetBase* copy()
This method is very similar to the one of the same name that accepts the single string parameter. In this case the new gadget object that is created should be done using the constructor that takes the single integer parameter. Implementation should otherwise be the same. In fact, this version of copy() can be implemented using a call to the other version as follows, if are new arranger is called NewArranger:

virtual GadgetBase* NewArranger::copy()
{
    return copy( "NewArranger" );
}
virtual void createSceneGraph()
It is possible for an arranger to have some visual component. For example, if the gadgets are to arranger on top of some sort of base. In these circumstances this method should be implemented to create these parts of the scene graph in the same manner as for shape gadgets. The only difference being that the root separator node (in m_root) will already have been created.

virtual void arrange( ArrangeMode )
This is the method called whenever the gadgets for which this arranger is responsible change their size, or any new gadgets are added to this arranger. This method is usually where the layout algorithm is implemented. It is possible (through the m_gadget array) to access the size information about each gadget to be layed out. The ArrangeMode parameter lets the method know what event cause it to be called. It will have one of the following values:
  • Add - a new gadget was added
  • Resize - one or more of the gadgets has changed size
  • Remove - a gadget was removed (not implemented yet)
virtual void sizeChange( SizeChange, GadgetBase* )
When one the gadgets for which this arranger is responsible changes size, this method is called. The SizeChange parameter indicates which of the dimensions of the gadget changed size. The GadgetBase* parameter points to the gadget that changed size. It is the responsibility of this method to call the arrange() method indicating that the gadgets have resized.

For a better understanding of how various gadgets are actually implemented the files GadgetLib.h and GadgetLib.cc should be consulted.


[Table of Contents] [Previous Section]


David Sykes / dsykes@cs.monash.edu.au