moodss

(Modular Object Oriented Dynamic SpreadSheet)

Contents

About this document

This document contains general information, reference information and examples designed to help the user understand the moodss application and the programmer write modules for it.

Introduction

Quite often, one needs to monitor changing data, whether it might come from a system, such as the different processes running on a Unix server, or from a network, such as the kind and volume of traffic that runs through it.

Most often, such data can be organized in a table with rows of information, each column representing a different type of data. For example, in the case of processes running on a system, rows might be sorted according to their unique process identifier, and columns might represent such values as CPU usage, memory usage, owner's name, time of creation, ...

The software used to view this type of information comes in different forms and shapes. Unix users might be familiar with the "top" application which presents rows of process data as lines of text, whereas RMON (Remote MONitoring) SNMP software usually uses multiple windows with graphical displays, curves, pie charts, multiple configuration dialog boxes, even 3D visualization modules to present network traffic, session matrices, ...

In most cases, data comes from one or several tables. A common interface, graphical with menus and a table widget, could then be used for a start. The user could then sort the table rows, select one or more cells, rows, columns, to launch viewers such as other tables, charts, ... best suited to the way data should be presented. In effect, what is needed is a spreadsheet that is capable of dealing with dynamically changing data.

Moodss (Modular Object Oriented Dynamic SpreadSheet) is an attempt at answering these needs. It is composed of a main part (the core) and an unlimited set of modules, each module fitted to a particular type of data. Modules as well as the core are written in the great Tcl language (http://sunscript.sun.com/) using object oriented techniques thanks to the stooop and scwoop packages (http://www.mygale.org/~jfontain/). The module function is to describe the type of data that it is also in charge of retrieving when asked by the core.

As features are added to moodss, different ways of viewing data will be made available while the modules will stay the same. The goal of moodss is to become a nice feature packed generic way of viewing table data. Moodss can be used to monitor any type of data, since the simplest cases can fit in a table with a single row.

As moodss is written in Tcl, it will run on all Tcl/Tk supported platforms: UNIX, Windows and MacIntosh. Some modules may be specific to a platform (or include some C code), but the core is guaranteed to run on them all.

After reading and understanding this document, you should be able to write your own modules in order to monitor the data that you are interested in.

Moodss is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License: please see the COPYRIGHT file and the main window Help menu for more information.

Required software

For the current version (1.0), the following packages must be installed before attempting to install moodss:
* many thanks to Jeffrey Hobbs for this great package
The stooop library and required scwoop widgets are included in the self-contained moodss file. Therefore, it is not required to install the stooop and scwoop packages, unless you want to work on the moodss source code itself. However, should you want to get more information on those extensions, you could find them at:

Architecture

The moodss application is composed of the core software and one or several modules. Modules are implemented as Tcl packages and thus usually comprise a Tcl source file and a pkgIndex.tcl file required by the Tcl package implementation.

The core will load the module whose name was passed as a command-line parameter and will display the module data in a table. The table is then updated at the frequency defined by the poll time, which the user may change. For example, to launch moodss with the random module, just type:

$ wish moodss random
All the module code and data is kept in a separate namespace. The module data is stored is a single array including some configuration data used when the module is loaded by the core, and variable data (displayed in the application table) which the module must update when asked by the core.

Core

User interface

The user interface is quite simple at this time. Tabular data is displayed in a tkTable widget with automatic scrollbars, between the menu bar and a message area, as one can see right below:
moodss main window view

The message area is used to display status information, such as when data is being updated, and help information, as the user moves the mouse pointer over sensitive areas, such as table column headers. Further help is provided through widget tips (or balloons) when appropriate, and of course the Help menu.

The window title shows the name of the currently loaded module along with the poll time.

The File menu only contains the exit menu entry, used to gracefully quit the moodss application.

The Options menu contains the Poll time entry which when selected launches the corresponding dialog box, as shown below:

poll time dialog box

The user can select a new poll time among the proposed choices from a spin entry widget, or directly type in a new value, as long as it is not smaller than the specified minimum poll time.

Table data can be sorted at any time by simply clicking on a column title. Clicking on the same column title again sorts the data in opposite order, thus toggling between increasing and decreasing orders.
When sorting, the selected column is used as a reference, meaning that all rows will be rearranged so that the selected column appears sorted, with values either increasing or decreasing depending on the current state.
The reference column for sorting always appear in a darker shade of gray.

The Help menu contains Module help, Copyright information, Warranty information and About general information entries.

Command line

Launching moodss is very simple: just pass the data module name as parameter, as in:
$ wish moodss random
You may eventually specify a poll time in seconds using:
$ wish moodss -update 25 random

Modules

All examples are drawn from the random sample module.

source

Since a module is a package, it must have a name in the Tcl sense. For example, at the beginning of the random.tcl file, one can find the following statement:
package provide random 1.0
This line simply states that this is the 1.0 version of the random package. Please note that the package name must also be used as the module namespace name (see below).
namespace
All module procedures and data are kept in a specific namespace bearing the module name. For example (from the random.tcl source file):
namespace eval random {
    array set data {
        ...
    }
    proc update {} {
        ...
    }
}
configuration
The module configuration defines the data table column headers, help information, ... This data never changes during the lifetime of the application.

All the module configuration data is stored as array members of the array named data within the module namespace. For example:

namespace eval random {
    array set data {
        updates 0
        0,label name 0,type ascii 0,message {user name}
        1,label cpu 1,type real 1,message {cpu usage in percent}
        2,label disk 2,type integer 2,message {disk usage in megabytes}
        3,label command 3,type dictionary 3,message {most time consuming command}
        pollTimes {10 5 20 30 60 120 300}
        columns 4
        sort {1 decreasing}
        helpText {
This is a simple demonstration module ...
        }
    }
    ...
}
The updates member is a counter used to keep track of the number of times that the module data was updated, and is also used by the core to detect when module data display should be updated (see variable data for more information).

The columns member defines the number of columns in the table to be displayed by the core.

The n,label members define the text to be displayed as column titles. There must be as many n,label members as they are columns.
The n,type members define the type of the corresponding column data. Valid types are simply those that the Tcl lsort command can handle: ascii, dictionary, integer and real. There must be as many n,type members as they are columns.
The n,message members define the text of the help message to be displayed in the message area (see User Interface) as the user moves the mouse pointer over column titles. It should be composed of only a few words, just enough to actually help the user understand what the column data means. There must be as many n,message members as they are columns.
Note that column numbers start at 0.

The pollTimes member is a list of valid poll times (in seconds) for the module. The list need not be ordered, as its first element represents the default poll time value to be used when the moodss application starts. This value may be overridden by a command line argument. The smallest value in the list is used by the core as the lowest possible poll time and checked against when the user enters a new value through the poll time dialog box. The list must not be empty.
Note that the list is also used by moodss as a set of possible choices in the dialog box used to set the new poll time. The user may still directly input any value as long as it is greater than or equal to the minimum value.

The sort list defines the index of the column which should be initially used as a reference for sorting the data table rows, and in which order (increasing or decreasing) the rows should be sorted. The column index for sorting works like the -index Tcl lsort command option, that is rows are sorted so that that specific column appears sorted in the specified order.

The helpText member specifies a text of any length, to be displayed when the user requests help information on the current module from within the help menu.

variable data
The tabular data (variable data) that the module code must update is stored in the same data array as the module configuration data.

The core invokes the update procedure (which must exist) when it is time to refresh the table display for the user. At this time, the update procedure may update the tabular data straight away (synchronous operation) or launch a request for latter data update (asynchronous operation).

It actually does not matter when the data is updated. The core will know that fresh data is available when the updates array member is set (actually incremented as it also serves as a counter for the number of updates so far).
It is the module programmer's responsibility to increment this counter right after all tabular data has been updated.

For example, retrieving information for the processes running on a machine is a local operation that can be achieved in a reasonably small amount of time. In such a case, data would be updated immediately and the updates variable incremented at the same time.
But if the data has to be retrieved from across a network, waiting for it to come back would cause a delay that the user would certainly notice, as the application would not respond to mouse or keyboard input during the whole time that it would take to fetch the complete data. In such cases, it is easier to let the update procedure return immediately without setting the updates variable, which would be incremented at a later time, only when the data would become available. For example, when waiting for data to come across a network connection, the Tcl fileevent command could be used on a non blocking channel, where the script to be evaluated when the channel becomes readable would increment the updates array member.
Thus, data update can occur synchronously or asynchronously.

For example:

namespace eval random {
    ...
    proc update {} {
        variable data
        array set data "
            0,0 john    0,1 1234 0,2 4567 0,3 cc
            1,0 william 1,1 8901 1,2 2345 1,3 xedit
            2,0 anny    2,1 6789 2,2 0123 2,3 ps
            4,0 peter   4,1 4567 4,2 8901 4,3 ls
            6,0 laura   6,1 2345 6,2 6789 6,3 emacs
            3,0 robert  3,1 1234 3,2 5678 3,3 top
        "
        incr data(updates)
    }
}
The tabular data array index is the row number followed by the column number separated by a comma. The column number must start from 0 up to the total number of columns minus 1 (no holes are allowed in the column sequence).
The row number can take any integer value and be defined in any order, as long as it is unique during the lifetime of the module data. If a new row is created, it must take a value that was never used: the index of a row that has disappeared cannot be reused. Row numbers need not be consecutive.

When all rows (or only those table cells that have changed) have been updated, the updates member array is incremented so that the core can update the table data display.

installation

A module is a package in the Tcl sense. When writing a module, you must then provide a pkgIndex.tcl file along with the module code file. The pkgIndex.tcl file is very simple, as the following example shows:
package ifneeded random 1.0 "source [file join $dir random.tcl]"
The line above says that if the random package is needed, the Tcl core should source the random.tcl module source code from the directory where it was installed. 1.0 is the version number for the package.

Modules can be installed at any valid place that the Tcl core allows (look at the pkg_mkIndex manual page for more information).

When you unpack moodss, you will find the sample modules in sub-directories. The current directory is appended to the auto_load global list variable so that sample modules can be found when moodss is run from the unpacking directory.

For example, if you unpacked moodss in /home/joe/moodss-1.0/, you will find the random module package in /home/joe/moodss-1.0/random/ so that the following will work:

$ cd /home/joe/moodss-1.0/
$ wish moodss random
You can install your new modules in the default location: /usr/local/lib/ on Unix. For example, if you move the files in /home/joe/moodss-1.0/random/ to /usr/local/lib/random/, moodss will still be able to find the random module (again, look at the pkg_mkIndex manual page for more information).

Please take a look at the INSTALL file for the latest information on how to install the moodss application itself.

Future developments

The 1.0 version is only a beginning. It provides the basic features and architecture that future versions can build on.

The following features will be added to the core:

Drag'n'drop would be used when dropping one or more cells, or rows or columns, into icons representing viewers. For example, if one wanted to graphically monitor the CPU usage for a certain process, one would select the corresponding cell in the table, drag it to the icons bar and drop it into the chart icon. The user would then have to interactively place the newly created chart within a scrollable area placed below the main data table, thus constructing a graphical dashboard for the module data.

Sub-modules would be launched from the main module (probably through menus), in order to display specific areas of the data being observed, or even different but related information (this concept needs to be defined, input is welcomed).

Miscellaneous information

For downloading other Tcl software (such as stooop, scwoop, ...), visit my web page.

Send your comments, complaints, ... to Jean-Luc Fontaine.