HotSaNIC
HTML overview to System and Network Information Center
by Bernd Pissny ( hotsanic@bernisys.prima.de / http://www.bernisys.prima.de )



HotSaNIC - how to create my own module

First of all, if you have any suggestions on improving this (in fact just-thrown-together-on-request) documentation, or if you encountered any important facts or questions which are not discussed here, please contact us!

In fact it's not too hard to hack your own module. For example all parsing of settings and commandline parameters will be done by a set of functions in HotSaNIC.pm and return a quite easy to use hash or array. I'll discuss this later in this document.

If you intend to write a module, best thing would be to take a closer look at the other modules to understand what's going on at all. In this document I'll give you a brief overview about the scripts and their roles.

First thing is to understand the underlying structure:
I splitted each module in some functional parts, this was easier to handle than a one-in-all script, since some parts get called only once and some (read-data) will be called every 10sec. and this way i spare some compilation-time since everything is only parsed/compiled when really needed.
  • setup
    • called by main setup
    • creates settings file and sets initial configuration

  • init (optional)
    • called when starting rrdtimer
    • initializes the module if necessary (e.g. create filter-rules in iptables etc.)

  • makerrd
    • called by read-data.pl when a database dosn't exist
    • creates a database

  • makeindex.pl
    • will be called by main makeindex
    • creates the html files and some data for the tables on the main page

  • diagrams(.pl)
    • called by rrdtimer every "DTIME" minutes
    • generates the diagrams

  • read-data(.pl)
    • called by rrdtimer every 10 sec.
    • queries datasources
    • fills the databases

How the data will be queried and stored is up to you, you just have to follow some simple rules:

read-data(.pl)

  • you should include HotSaNIC.pm since it contains some vital functions
  • read-data(.pl) accepts some commandline arguments which are being passed to it by rrdtimer in order to speed-up execution (main settings need not to be parsed) or to debug a module. These options are parsed by HotSaNIC::arg2opt which passes you a hash with the options as element names. (see HotSaNIC.pm for details - applies to HotSaNIC >=0.4.1)
    option
    value
    MODNAMEname of module (uppercase)
    DEBUGLEVELa value >=100 to enable some module-debugging (0-99 are reserved to debug rrdtimer - the debugging code is up to you.)
    OSTYPEreturn value of "uname"
    SNMPWALKpath to snmpwalk
    SNMPGETpath to snmpget
  • to avoid zombi processes, the modules have to be initialized and terminated properly. There is a function HotSaNIC::dupe_control (see HotSaNIC.pm for details)
  • the modules' settings will be parsed by HotSaNIC::read_settings which passes you an array of only the important data. Comments and such will be stripped. (see HotSaNIC.pm for details)
  • to separate a configuration line into name and value (i.e. split it by "="), you may use HotSaNIC::parse_line. This function also applies some regexes to strip unwanted spaces, comments behind a line, quotation chars etc. (see HotSaNIC.pm for details)
Usually read-data.pl looks like this:

#!/usr/bin/perl -w

# include RRDs.pm (from rrdtool) and HotSaNIC.pm using its relative path...
#
use lib "..";
use HotSaNIC;
use RRDs;

# get cmdline arguments (i.e. options passed by the daemon)
# and other global parameters
#
%ARGS=arg2opt(@ARGV);

dupe_control("start",$ARGS{"MODNAME"},"");

# read module-specific settings
#
foreach (read_settings("."),$ARGS{"MODNAME"}) {
($var,$values)=parse_line($_);
... (evaluation) ...
}

... (query data) ...

... (store data) ...

dupe_control("stop",$ARGS{"MODNAME"},"");

Best thing is to take a closer look at the other modules to learn more about it.

makeindex.pl

the script creates a file "idxdata" and some .html files in the "index" directory of the module. The format of idxdata has to be as follows:

0## <td colspan=2 align=center valign=top> <font size="+3">modulename</font><br>
0## <a href="modulename/6h.html">6 hours</a>(optional)
0## <a href="modulename/week.html">week</a>
0## </td>
1## <td><a href="modulename/device1.html"><img src="modulename/thumb-device1.gif"></a></td>
1## <td valign=top><a href="modulename/device1.html">device1</a><br><font size="-2">description 1</font></td>
2## <td><a href="modulename/device2.html"><img src="modulename/thumb-device2.gif"></a></td>
2## <td valign=top><a href="modulename/device2.html">device2</a><br><font size="-2">description 2</font></td>
...

modulename is the name of the module in lower-case, device... and description... refer to some datasources you wish to show. The main makeindex script parses these files to create the main index page (the overview) and moves the files in the modules' "index" directories to the proper places. The numbers preceding each line refer to the position where the devices will be placed in the main index.html - lines beginning with 0## will be üplaced in the title.

diagrams(.pl)

The only really important thing is that you should take care that the weekly graphs should be generated, because the thumbnails for the main index page will be derived from the weekly graphs. The function HotSaNIC::get_diagram_properties will help you to retrieve all necessary information used in the diagrams. (see HotSaNIC.pm for details)

useful hints

Since HotSaNIC samples every 10sec., you should take a closer look at how much time will be spent on sampling the data. If it takes much longer than let's say 5sec., please take a closer look at the PING module, this mod uses an own timebase for exactly the above reaseon.

future changes

Please be prepared to "modularize" your module (nice wordplay ;D), because we want to change our concept a bit. This probably would dramatically increase processing speed, since perl does not need to re-compile each script every 10sec. any more.

As a side-effect there would then be a separate .pm for each OS in each module that keeps the module's OS-specific parts. This will make debugging a hell of a lot easier.

When all this is done, we probably are able to offer a kind of a "skeleton" for homwbrewn modules which holds the core functions.