Monitored Object Creation Guide

    This guide explains how to create your own monitored objects.  A monitored. object is any system, application, or program parameter which you can gather from a TCL script.  This guide explains how to write your own monitored objects.

    If you wish to share your creation with the rest of the Internet community, send a description to:  sblack@ee.ryerson.ca.

    The MAT console queries each host to determine which objects it can monitor.  Each MAT host returns a list of all of the objects it can monitor, along with a function name, and arguments necessary to run the TCL monitoring script.  In effect the console it told:

    • What objects the host can monitor.
    • What icon to display on the console.
    • What description to give the icon.
    • What file and function to call on the host.
    • Finally it tells the console how to display the data.
    The data can be displayed as a Pie chart, Bar graph, or as text.  An example of each will be provided later.
     

    Telling MAT About Your Monitored Object

    This sections explains how to tell the MAT console about your monitored object.  It first explains what it is doing then shows some example code.

    During the agent installation MAT will attempt to discover which monitored objects a host has.  It searches the $MATHOME/lib directory for any  *.mon files.  Once it finds a file with a .mon extension, it searches the file for the procedures within it.  It is these procedures which gather the data.  It is these procedures which you will create.  Each procedure must be able to determine if it is appropriate for the type of operatiing system it is run on.  For example if the monitored object is the number of NFS requests.  The monitored object should determine if the "nfsstat" function exists on the operation system.  During the discovery of the monitored objects, each procedure is invoked with the "Discover" argument.  If the monitored paramater is available on the given operating system, then it will return a configuration string.  This configuration string is retreived when the Status icon is double-clicked on the console.  It tells the console about your monitored object.  The format is as follows:

    array set tclmon2t {10000 { 0x l myicon.gif myscript.mon myFunction "Description" instance_Arguments } }
     

    • The "array set tclmon2t" is a TCL command to set an array value.  It is required.
    • The "10000" is a procedure number.  Each procedure MUST have it's own unique number.  Numbers from 0-9999 are reserved for monitored parammeters shipped with MAT.
    • The "0x" defines where to display the icon in the console.  You can create your own object subclasses.  In this case this object is a sub-object of 0x.  This controls the hierarchy of the monitored objects.  For you monitored objects use 0x.
    • The "l" defines this as a leaf node in the console display.  The other option is a branch "b".  The leaf node is an actual monitored object.  The branch is a container for leaf nodes and other branches.  If you define a branch the leafs it contains will be sub-objects of it, and so the position for the objects it contains will have to change e.g "0xa"
    • The "myicon.gif" is the icon the console displays for the monitored object.  The icons should be 48x48 pixels.
    • The "myscript.mon" is the name of the file with the object monitoring procedures.
    • The "myFunction" is the function name that the console will call to get the information on the monitored object.  This is the name of the function you have created to gather the data displayed on the console.
    • The "Description" is a textual description of the monitored object.  This will be displayed below the icon in the console.  Use "\\n" to add new lines to the description.
    • The "instance_arguments" are additional arguments you may wish the console to pass to the "myFunction" when it is gathering data.  This is used for the disk monitoring.  The one function monitores all the partitions by getting the partition name as an argument.


    Each monitored object function must generate the above configuration string on request.  This is done by requireing each monitoring function to process the argument "Discover".  Below is an example:

    proc myFunction { args } {
        global mat_os
        # Discovery:  Tell the console if this monitoring script is supported by this OS
        if { $args == "discover" } {
            switch -- $mat_os {
                linux {
                    return "array set tclmon2t \{10000 \{ 0x l myicon.gif myfile.mon myFunction
    \"Description\" \}\}"
                }
            }
            return
        }
        # The monitoring code goes here

    }

    Copy the above code fragment to a file called myfile.mon, in the $MATHOME/lib directory.  The mat_os is a variable provided by MAT.  It is set to the OS type e.g. linux, solaris, sunos, hpux, or irix.  You can test the script by running the cmd function.  Change directory to the MAT bin/ directory, on a machine where the MAT agent and myfile.mon reside.  To test it run:
        ./cmd MATTCL mon myfile.mon myFunction Discover
    It will return a string like:
        array set tclmon2t {1000 { 0x l myicon.gif myfile.mon myFunction
    "Description" }}

    Now you are ready to create the icon for the console, and write the script to gather the data.
     

    Console Icons

    The console needs an icon to display to represent the object to monitor.  The xpaint utility can be used to make the icon.  The icon size should be 48x48 pixels.  The pallet sould be kept to a minimum.  The icon's background can be set to transparent using the giftool utility.  The finished icon should use the same name as given in the discovery portion of your monitoring function.  Copy your icon to the lib directory of the MAT console.  Several icons are already in that directory, and you can use and modify them.

    Now you are ready to write the script to gather the data.
     

    Writing the Monitoring Script

    The monitoring script is written in Tcl.  This is not intended as a tutorial in Tcl.  Go to http://developer.scriptics.com for more Tcl resources.  The existing monitoring scripts will also provide examples on how to create you own.

    The monitoring protion of the function has two functions:

    • Gather the data for the console to display
    • Tell the console what format you wish to display the data in:  text, bar or pie graph


    Gathering the data may require reading a file, running command(s), or some other actions.  The Tcl interpreter makes this relatively painless.  What follows are some simple code fragmants for reading files, and running commands.
     

    Example 1:  Gathering Data From a File
    The following example counts the number of filesystems being exported by a machine.
         # Check the OS type to determine where the file listing exports lies
        global mat_os
        switch -- $mat_os {
            linux | sunos | irix | hpux {
                set exports "/etc/exports"
            }
            solaris {
                set exports "/etc/dfs/dfstab"
            }
        }

        # Clear the data variable
        set data {}

        # Open the file
        set fid [ open "$exports" r ]

        # Read the data into the data list.
        while { [ gets $fid fout ] > 0 } {
            lappend data $fout
        }
        close $fid

        # The data variable contains the contents of the file.
        # It's now ready for parsing.  We will assume any non-blank
        # line not starting with a "#" is an exported filesystem.

        set counter 0
        foreach line $data {
            # Skip any lines starting with a "#"
            if { [regexp -- "^\#" $line ] == 1 } {
                continue
            }

            # Count the non-blank lines.
            # A solaris export entry will start with an "s" in the line.
            # All others will start with a "/", so just look for those.
            if { [regexp -- "^[s\/]" $line ] == 1 } {
                incr counter 1
            }
        }

        # That's it.  The counter variable contains the number of
        # filesystems this machine is configured to export.
        #

    The counter would have to be displayed in a meaningful format.  Output formatting will be covered later.  The next example will do the same, ,but will get the information from the "showmount command.
        # Check the OS type to determine where the file listing exports lies
        global mat_os
        switch -- $mat_os {
            linux {
                set shcmd "/usr/sbin/showmount"
                set discard 0
            }
            solaris | irix | hpux {
                set shcmd "/usr/sbin/showmount"
                set discard 1
            }
            sunos {
                set exports "/usr/etc/showmount"
                set discard 1
            }
        }
        set sharg "-e"

        # Now run the command
        set ds "set data \[exec $netstat $netarg 2>/dev/null \]"
        eval $ds
        set t [lrange [split $data "\n" ] $discard end ]
     

    Saving the Data

    After gathering the data it is necessary to store the data.  This is done by calling the  Util::Record function with the data points as shown:

      # Store the data
      Util::Record $data0 $data1 $dat2
       


    Initializing and Destroying

    It may be necessary to initialize variable and open files before gathering data.  An initializer procedure is needed for all monitored parameter scripts.  At a minimum it should look like:

      # Initialize
      proc Report::Initialize { } {
          Util::Initialize
          # Put your code here
      }
       
    To close files before shutting down a destroy function has to be provided.  It will be called before MATd terminates the interpreter.  It looks like:
      # Destroy
      proc Report::Destroy { } {
          Util::Destroy
          # Put your clean-up code here
      }
       

    Putting it All Together

    The following is the code for the monitoring the CPU consumption:
      # Cpuuse.scp
      # This script monitors the CPU consumption
      #
      # Availability:     Linux, Solaris, HPUX
      # Position:         0g
      # Function Number:  378
      #

      namespace eval Report {
          # Version of the script
          set version 1

          # Export the functions.  Do not export the Discover routine
          namespace export Discover Initialize Monitor Destroy
      }

      # Discover
      proc Report::Discover { } {
          # Discover every instance of the parameter that can be monitored by this scr
      ipt
          global mat_os
          if { $mat_os == "irix" } {
              return
          }
          set instanceData ""
          source "lib/cpuuse.jds"
          regsub -all -- "instanceData" $Description "$instanceData" instanceDescription
          set ol ""
          append ol "array set o2t \{378 \{ 0g h $IconName cpuuse.jds \"rClickMatd .tp
      .host.canvas 378 cpuuse\" \"$instanceDescription\" \}\}\n"
          append ol "MATD: interval 378 2 11 60000 0 0 var/cpuuse 720 cpuuse 99 95 -\n
      "
          return $ol
      }

      # Initialize
      proc Report::Initialize { } {
          Util::Initialize
      }

      # Monitor
      proc Report::Monitor { } {
          global mat_os
          global instanceData
          set vms "/usr/bin/vmstat"
          if { $mat_os == "irix" } {
              set vms "/usr/bsd/uptime"
          }
          set ds "set data \[exec $vms 1 2 2>/dev/null \]"
          eval $ds
          set t [lrange [split $data {\n} ] end end ]
          set t2 ""
          regsub -all {[ \t]+} $t { } t2
          set t [string trimright [split $t2 ] {\}} ]
          set l [llength $t ]
          set sy [lindex $t [expr $l - 2 ] ]
          set us [lindex $t [expr $l - 3 ] ]
          Util::Record $us $sy
      }

      # Destroy
      proc Report::Destroy { } {
          Util::Destroy
      }