Chapter 2. RSPD

Table of Contents
Installation
Product Key Information
Configuration
Command Line Options
General Configuration File Options
History Configuration File Options
Module Configuration File Options
Thresholds Configuration File Options
Configuration File Examples
Configuration in Windows
RSP Status Window
Modules in RSPD
Linking with the Library (C versions)
Linking with the Java Version
Linking with the Perl Version
Structure of a module
C Function Reference
Java Function Reference
Perl Function Reference
Example Module Code - C
Example Module Code - Java
Example Module Code - Perl

The RSP Daemon (known as RSPD) can be considered the core of RSP, for it is the part which collects and stores system information. Running on every machine on which data is to be collected, the RSPD has a few concurrent tasks. First, it retrieves data on the machine as specified by the administrator. This data can be almost any statistic imaginable, including local data like CPU usage or memory consumption, or network data like active ports on a remote host. It can then "hand-out" the data to the RSP Web, and can also save some or all data for later analysis. In addition, the RSPD can collect hardware information on the machine on which it is running.

A user can also specify "thresholds" for data, that is, a point at which an administrator should be notified that the computer might not be running properly. So, in the middle of the night, a sysadmin could get an email from RSPD telling him/her that a web server (for instance) isn't running correctly. Some thresholds might be the maximum allowed memory usage, or the minimum amount of free disk acceptable on a certain hard drive.

Another important part of an administrator's job is to look for trends in computer activity, which may be signs of trouble in the future. For this reason, RSPD allows collected module data to be saved for future analysis. RSPD can save data to a remote database, either the custom RSP-specific database program known as a History Listener (discussed in Chapter 3), or to a popular Open Source database known as MySQL. History data saved by either of these methods can be viewed by the RSP Web program (see Chapter 5).

Installation

To install RSPD, please refer to the Installation section of Chapter 1 of this guide.

Product Key Information

The RSPD is the only program in the RSP suite of tools that requires a valid product key in order to run. This key should have been included with your purchase of RSP (if you did not get a key with your purchase, you should contact Draconis Software as soon as possible). When RSPD does not have a valid product key, it reverts to demonstration mode, which has a hard-coded expiration date (usually 30 days from the date it was downloaded). Once that expiration date is up, you will need to purchase a product key to continue using RSP.

The product key is first checked when the RSPD program is started. If the key is valid, then the RSPD will continue running (otherwise it will exit with an error message). When a monitor connects to the RSPD (via the RSP Lib API), an MD5 hash of your key will be transmitted. If the RSP Lib API detects multiple instances of the same MD5 hash being sent by multiple RSPD programs, it will alert you and cease to monitor the same-keyed RSPDs (excluding the first RSPD).

An MD5 hash is a one-way translation algorithm that creates a text code of the product key that cannot be reversed (but is nevertheless completely unique - no two product keys will ever hash to the same value). Transmitting this hash is safe, as no one can snoop the network to extract your license key.

Configuration

The RSPD application has a number of configurable options. On non-Windows systems, these options can be specified either at application start (via the command line) or through a configuration file (which eliminates the need for lengthy commands every time the RSPD is to be started). There also exist a number of options that cannot be specified through command line options. For this reason, a configuration file is always required in order to start the RSPD. On Windows systems, there are no command line options. Although the configuration file still exists (and be editted just as on Linux/UNIX systems), there exists a GUI interface for all options. Therefore non-Windows users should refer to the "Command Line Options" and "General Configuration File Options" sections, while Windows users should refer to the "Configuration in Windows" section.

Command Line Options

When RSPD is being run on a non-Windows computer, there are a few options that can be specified on the command line which affect the program's behavior. If a command line argument conflicts with an option in a configuration file, RSPD will choose the command line option over the configuration option. Listing 1-1 details the available command-line options that may be specified.

Table 2-1. Available RSPD Command Line Options

OptionDescription
--help (-h) Prints a help message and exits.
--debug (-d) Prevents RSPD from forking to the background (which is the default). Also displays all log messages to the console while running.
--config {file} Specifies the location to read a configuration file from. Must be followed by a space and then the location of a configuration file.
--syslog (-s) Sends all log messages to the syslog daemon instead of writing messages to an RSPD log file.
--logfile (-l) {file} Specifies where all log messages should be saved.
--port (-p) {port} Overrides the default port (3497) for communications and instead uses the specified port.
--ad (-a) {time} Uses AutoDiscover functionality to search the network for all available HistoryListeners.

General Configuration File Options

Configuration options specfic to saving history data or to modules exist within specified blocks. However options specifying the general behavior of RSPD do not exist within any blocks. One such option is for logging. Messages specifying the actions of RSPD can be written to log files so that one can be kept aware of errors or problems. Three types of log messages exist: notes, warnings, and errors. The user can set the verbosity of logging, which indicates to RSPD which types of messages to save: warnings and errors, or only errors. In addition, RSPD can use syslog (on UNIX and UNIX-equivalent systems only) to store log messages.

There are also general options for dealing with connections from monitors. The user can specify a timeout, which is the longest amount of time RSPD will wait for a response. It is also possible to set the maximum number of allowed connections.

To simplify monitoring of many RSPD applications on many computers, monitors can actively search for these computers running an RSPD on a network. If the RSPD is configured to use Auto Discover, then it will be able to tell monitors it is up and running. Auto Discover works, on the daemon end, by sending a multicast packet to a given group/port on a network, and on the viewer end, a listener is setup for these kinds of packets.

Because security is always important in a network, an administrator may not want to allow just any host to connect to an RSPD. A pair of configuration options - block and allow - specify exactly which remote hosts can make a connection to the RSPD. In addition, RSPD by default uses SSL to securely communicate over the network.

The following listing details each of the available configuration file options.

Table 2-2. Available RSPD General Configuration Options

OptionDescription
syslog Non-Windows only. Specifies whether syslog should be used for logging messages. Possible options are "true" or "1" if syslog should be used, and "false" or "0" if not. The default is to not use syslog.
logfile Indicates the location where the file of log messages should be stored, if syslog is not used. The default is the current directory, named RSPD.log.
verbose Specifies which levels of log messages should be written to the log file. Three options exist: (1) quiet, (2) normal, and (3) loud. The "quiet" value prints only error messages, "normal" prints both warning and error messages, and "loud" prints all log messages.
port Specifies the port on which RSPD should listen for incoming connections (from a viewer program). The default is 3497.
timeout Indicates the number of seconds that should be waited before declaring a connection "broken." Slower networks/machines may require this to be a higher value. The default is 5 seconds.
checkForUpdates The RSP checkForUpdates feature is designed to alert you to when new versions of the RSP software are available. There are two times it checks: every 48 hours, and when RSPD is first run. If there is a new update, RSPD will log a message to the RSPD log file. A value of "true" will enable these checks.
maxConnections Specifies the total number of monitor connections allowed at a given time. The default is 5.
allowAutoDiscover If set to true, other applications will be able to find this RSPD. Periodically sends out a "HERE I AM" message with the IP address and port of this system. The default value is true.
adMCastGroup Indicates to RSPD the multicast group that should be used for the Auto Discover functionality. This only applies if allowAutoDiscover is set to true. The default is 225.0.0.37.
adMCastPort Specifies the multicast port this RSPD should use to send Auto Discover packets. Like adMCastGroup, this option only applies if the allowAutoDiscover option is set to true. The default is 3498.
allowSSL Allows connecting monitors to use secure SSL communication. Values are 1 or 0. Default setting is on.
sslCertificateDir Only valid on non-Windows systems. Specifies an alternate directory for SSL certificates. The default location is /etc/rsp/ssl.
block/allow These two options are each lists. Therefore, they can be set to multiple values. Each value can be all or part of an IP address (using wildcards). Also, the word "all" can be used to indicate all addresses. An example may be:

   block = all
   allow = 10.0.1.*
   allow = 192.168.0.31

poll Specifies the default time (in seconds) to wait before polling each of the modules RSPD has a connection to. The default is 5 seconds.
productKey This value is the authorization code you should have received with your purchase from Draconis Software. Copy the code (without any dashes) exactly as given. The RSPD cannot run without a valid product key specified. If no product key is given the RSPD will run in demo mode.
collectHardware Specifies if RSPD should collect local hardware information. This information is only collected once when the RSPD starts up. This information gets sent the RSP Web upon request. Possible options are "true" or "1" if hardware information should be checked, and "false" or "0" if not. The default is value is true.

History Configuration File Options

An RSPD can be configured to save module statistics in a number of ways. By default it will not save any information, but it is possible to save data on a remote file server called a History Listener, and in a MySQL database. Some options apply to one or both of these methods. All history options appear within a "history" block (see examples below).

Table 2-3. Available RSPD History Configuration Options

OptionDescription
type Specifies which type of history saving should be done. Possible options are "none", "RemoteText", and "MySQL". The default is "none".
host Specifies the History Listener location (when combined with the RemoteText type variable) or the MySQL host (when combined with the MySQL type). Can be either a hostname or an IP address. Default is "localhost".
port When combined with the host variable, this option specifies which port to connect to on a remote host. The default, when combined with a RemoteText type, is 3496 (to connect to a History Listener), and 3306 when the MySQL type is specified.
secure Applies to RemoteText type. Specifies if the connection should be done securely, that is using SSL communication. Default is true.
retry Specifies whether the RSPD should attempt to reconnect to the remote host in the event of a connection failure. The default value is false.
persistent Specifies if connections should be persistent (remain connected). The alternative is to reconnect each time data needs to be saved. Default is true.
login/password/database These three options apply only to a MySQL database. They specify the login/password to use and the specific database to store history data to.

Module Configuration File Options

An RSPD can have any number of modules that it will start and collect data from. Every module is defined in its own block. At the very least RSPD must be given a location where the module is located. The RSPD can be told whether or not to save history, and how often history can be saved. Also, a module may also require configuration, that is, information detailing what data it should return. This is done within the "config" block. This is a block within the module block detailing configuration specific to the module. The configuration differs between each module, so the documentation of each module should be consulted before adding it to a configuration file.

Table 2-4. Available RSPD Module Configuration Options

OptionDescription
disabled If this variable is set to true, then this module will be ignored by the RSPD when it loads its modules. The reason for this setting is that it may be useful to keep the configuration options for a module, but temporarily disable it for a time.
location Specifies the location of the module.
poll Indicates how frequently (in seconds) RSPD will poll this module for updated data.
history/historyCount Both of these options deal with how history data should be saved for the given module. The history option specifies whether or not history data should be saved, and if only graph data or both graph and full data should be saved. Possible values are "none", "normal", or "all". The historyCount option specifies how often the collected system information should be saved. A value of 1 would mean that every time a module is polled, RSPD will save its data to a history file. A value of 2 would imply that every other time the module is polled its data is saved. The default value for history is true, and the default for historyCount is 1.
config This is not variable name but a separate block which contains configuration specific to the module. Please refer to the configuration examples as well as the specific module documentation.

Thresholds Configuration File Options

It is often important to know when a certain statistic goes from being normal to being a problem, and thresholds allow the modules to compare their data against a value past which a problem exists. The thresholds block contains all the thresholds that need to be checked. Once a threshold is crossed, the RSPD may send an email warning, issue a command, or both. One threshold may use AND and OR operators to compare values across different modules.

Multiple thresholds are defined within the thresholds block by first setting a name for the threshold, and then setting the appropriate fields. For example, threshold "uptimeCheck" would first be given a name by setting "name = uptimeCheck". Then to set the cross event, the event field is set with "uptimeCheck.event = email". Every option other than "name" can be paired up this way with a threshold name. Except for "threshold", they can also be given without a name, in which case the setting will be the default value. See configuration examples for more information.

Table 2-5. Available RSPD Thresholds Configuration Options

OptionDescription
name Each threshold is given a unique name to identify it. Once a name is given, its fields (such as the threshold itself, cross event, or email address), are given by setting the name followed by a dot (".") and then the fields, possible ones following below.
threshold This sets the threshold itself. This is the only option which cannot have a default setting (since presumably each threshold would be different. The form of a threshold is one or more module expression separated by ANDs or ORs (but not both within one threshold). Each module expression depends on the module being referenced and module documentation should be read for specifics on any given module.
event Sets the action which will occur when the threshold is crossed. Can be "none" if no action should be taken, "email" if an email alert should be sent to each of the mailto addresses, "command" if RSPD should attempt to execute a specified command, or "both" if an email should be sent and a command should be executed.
command If the threshold is set to run a command when a threshold is crossed, then this option indicates what that command should be.
mailto A list of email addresses to which the RSPD should send warning messages when a threshold is crossed.
mailfrom The address that should be put into the From field of any email messages, indicated where it originated from. The address does not need to be a valid email address, though the domain should be a valid domain. For instance, "RSPD@somedomain.com" would be a valid address.
smtp The SMTP server that is to be used to relay warning email messages through. The server can require authentication, as the RSPD supports remote SMTP authentication.
smtp_login Specifies the login to use for a previously defined SMTP server, if the server requires a login.
smtp_pass Specifies the password to use for a previously defined SMTP server, if the server requires a login.

Configuration File Examples

In this section a possible configuration file and all of its related sections are presented. This should help illustrate how the various options relate to each other.

To start, here are three examples of hour logging in RSPD might be configured:

# Example 1
logFile = /var/log/rspserver.log
verbose = normal

# Example 2
syslog = false
logFile = ./rspserver.log

# Example 3
syslog = 1
			

In the first example, a location is given for the logfile, and the verbosity setting of "normal" tells RSPD that it should only log messages labeled as errors. Note the syslog option is not set in this example, because the default value of false is what we want. Example two shows that we can still set syslog to false, although it is redundant. Also note that the verbose option is not set, meaning RSPD will use the default setting of "normal" (log only errors). Finally, in the third example, syslog is set to 1, so logFile and verbose do not need to be set to anything. Note that for boolean values like syslog, "1" and "true" are equivalent, as are "0" and "false".

The RSPD daemon includes facilities for allowing or denying certain hosts, using its block/allow directives. The following examples help to show how these options work:

# Example 1
allow = 10.*
block = 192.*

# Example 2
block = all
allow = 192.168.*
allow = 10.0.1.1
			

It should first be noted that the default action for a given host is to allow it to connect. Therefore, if no block/allow directives are specified, every host will be allowed access. In the first example, the allow directive is actually redundant. The block directive tells RSPD to deny connections from any host whose IP address starts with 192. Since the default action is to allow a host, it is considered good practice to block all hosts, and then only allow specific groups, like in Example 2. In this case, 172.0.1.1 and 10.0.1.2 would be blocked, but 10.0.1.1 and 192.168.1.2 would be allowed.

If desired, RSPD can save the data it collects from the modules, as previously described. All history options are put in a block labeled "history". If no history block is declared, then RSPD will not save any history data by default. Below are some examples of how history data might be saved:

# Example 1
history
{
	type = RemoteText
	host = 192.168.0.1
	retry = true
	secure = true
}

# Example 2
history
{
	type = MySQL
	host = dbserver
	login = rsp
	password = history
	database = rspHistory
}
			

In the first example, history data is given to a History Listener located on 192.168.0.1. Since no port is specified, RSPD will use the default of 3496. If RSPD loses the connection to this History Listener, or fails to connect to it in the first place, the retry variable states that it should keep trying to connect. It will also use SSL for secure network communication. In example 2, we see data being saved in a MySQL database. To connect to the MySQL host, RSPD will use the login "rsp" and password "history", and will attempt to save data in the rspHistory database. Also, when saving history data, RSPD will use the default rolling value of "daily" and create a new table each day (since no rolling type was otherwise specified).

Each RSP module is specified in its own block along with its name. Since an RSPD may have many modules whose poll time is the same, a global "poll" option can be declared outside of any block. The following example shows how modules may be defined:

# Global poll setting
poll = 5

module Uptime
{
	location = modules/uptime.rsp
}

module CPUInfo
{
	poll = 10

	location = modules/cpuinfo.rsp
}

module DiskFree
{
	location = modules/diskFree.rsp
	historyCount = 10

	config
	{
		checkDrive = /
	}
}
			

Since poll is defined outside of a block, both modules will use the poll time of 5 seconds. The first module, Uptime, simply sets its location. The default poll time of 5 will be used since no other is given. However the second module, CPUInfo, gives a different poll time of 10 seconds. The value within a module block always takes precedence over a default value, so 10 will be used for CPUInfo. For the third module, DiskFree, note the historyCount setting. Presumably somewhere else in this configuration file history information is specified, and since by default module history is saved if it can be (this can be changed with the "history" setting within a module block), RSPD would save the data for DiskFree. Also, since historyCount is set to 10, RSPD will save data every 5 updates, which, in this context, means every 50 seconds because the poll time is 5 seconds. Finally, note that DiskFree contains a config block. This module lets the user specify details about which partition or drives they would like to check. Any module which allows for additional configuration, like DiskFree, uses the config block to get information. Any config settings within the block are sent to the module. Please read module documentation for specific settings on any module.

All threshold settings exist within their own block. Users can create as many thresholds as they like, which can send emails, issue commands, or both when they are crossed. Any one theshold may combine multiple modules using AND or OR operators. For example:

# Example thresholds
thresholds
{
	# Default settings
	event = email
	mailto = root@localhost
	smtp = smtp.myserver.com

	# A threshold referencing one module
	name = uptime_thresh
	uptime_thresh.threshold = Uptime.uptime > 1 day

	# Only cross the threshold if both parts are true
	name = cpu_mem
	cpu_mem.threshold = CPUInfo.idle < 5% AND MemStat.user > 50%
	cpu_mem.event = command
	cpu_mem.command = /home/user/script.pl

	# Either part crosses the threshold in this case
	name = disk_net
	disk_net.threshold = DiskStat.transfers/s > 50 OR NetStat.icmpInMsgs > 20
	disk_net.event = none
}
			

The first part of the thresholds block sets some default values. These do not have to be at the start of block, however it improves readability by placing them first. These three statements set the default event when a threshold is crossed to sending an email notice. It also sets the mailto address to root@localhost and the SMTP server to smtp.myserver.com. An email will be sent both when the threshold is crossed and when it becomes uncrossed.

The first threshold is uptime_thresh. After declaring its name, we can set information specific to uptime_thresh. The only required setting is "threshold", since without it there is no point in declaring a threshold in the first place. The threshold in this case relates to the uptime module. Most thresholds are in the form of a logical expression like this, with a module name followed by a dot and a module specific field. They are always true/false statements, and when the module determines that the value has been crossed (in this case that uptime is greater than 1 day, it will tell the RSPD that the threshold is now crossed. Since we don't give any additional settings for uptime_thresh, the default values are used. So if and when this threshold becomes crossed, an email will be sent to root@localhost. The actual form of allowed thresholds for a module is given in its own documentation.

The next threshold, cpu_mem, shows how two different modules can be referenced in the same threshold. In order for the threshold to become crossed, both expressions must be true. If only one is true, then the threshold will remain uncrossed and no threshold events will occur. There is no limit to the number of expressions that can be ANDed (or ORed) together. However AND and OR operators cannot be used together in the same threshold. Also, the operators are case insensitive, so "AND" or "and" could both be used. Also, by setting the event for this threshold to command, we override the default of mailto. Instead the given command will be issued.

The final example shows how OR operators can be used as well. The threshold will become crossed if either (or both) of the given expressions become true. Also by setting the event to none, so event will be taken when the threshold is crossed. However RSP Web will still see that this threshold is in the crossed state.

Finally, just to show how everything fits together, here is a full configuration file that RSPD might use:

# Global settings
logFile = ./rspserver.log
timeout = 30

# Only let localhost and 192.168.0.* connect
block = all
allow = 127.0.0.1
allow = 192.168.0.*

# History settings
history
{
	type = RemoteText
	host = 192.168.0.5
}

# Global module poll setting
poll = 30

# Threshold settings
thresholds
{
	name = uptime_thresh
	uptime_thresh.threshold = Uptime.uptime > 10 days
}

# Modules: uptime and diskfree
module Uptime
{
	location = modules/uptime.rsp
}

module DiskFree
{
	location = modules/diskFree.rsp
	
	config
	{
		checkType = ext2
	}
}
			

In practice a configuration file would be very similar to this, except that there would probably be many more modules declared.

Configuration in Windows

Although Windows users are welcome to edit configuration files, the simpler way of doing things is to graphically configure the RSPD with the Configuration dialog box. It is accessed by starting up RSPD and either double clicking on its icon in the taskbar, or right clicking on the icon and selecting the "Configure..." menu item.

This dialog box is organized into a number of tabs. The first tab is the "General" tab and is displayed in Figure 1.

Figure 2-1. RSPD "General" Tab

The controls in this tab are described in the following listing.

Table 2-6. General Configuration Options

OptionDescription
Module Poll Time Specifies the default time (in seconds) to wait before polling each of the modules RSPD has a connection to. The default is 5 seconds.
Product Key Only applies to Enterprise Edition. This value is the authorization code you should have received with your purchase from Draconis Software. Copy the code (without any dashes) exactly as given. The RSPD cannot run without a valid product key specified. If no product key is given the RSPD will run in demo mode.
Log File Verbosity Specifies which levels of log messages should be written to the log file. Three options exist: (1) quiet, (2) normal, and (3) loud. The "quiet" value prints only error messages, "normal" prints both warning and error messages, and "loud" prints all log messages.
Log File Location Indicates the location where the file of log messages should be stored. The default is the current directory, named RSPD.log.
Check For Updates The RSP Check For Updates feature is designed to alert you to when new versions of the RSP software are available. There are two times it checks: every 48 hours, and when RSPD is first run. If there is a new update, RSPD will log a message to the RSPD log file.
Collect Hardware Information Specifies if RSPD should collect local hardware information. This information is only collected once when the RSPD starts up. This information gets sent the RSP Web upon request. The default setting is true.

The second tab is "Network", which allows the user to configure settings related to incoming monitor connections.

Figure 2-2. RSPD "Network" Tab

Table 2-7. Network Configuration Options

OptionDescription
Timeout Indicates the number of seconds that should be waited before declaring a connection "broken." Slower networks/machines may require this to be a higher value. The default is 5 seconds.
Maximum Connections Specifies the total number of monitor connections allowed at a given time. The default is 5.
Allow SSL Connections Allows connecting monitors to use secure SSL communication.
Listener Port Specifies the port on which RSPD should listen for incoming connections (from a viewer program). The default is 3497.
Allow Discovery If turned on, other applications will be able to find this RSPD. Periodically sends out a "HERE I AM" message with the IP address and port of this system. The default value is true.
Multicast Group Indicates to RSPD the multicast group that should be used for the Auto Discover functionality. This only applies if AutoDiscover is allowed. The default is 225.0.0.37.
Multicast Port Specifies the multicast port this RSPD should use to send Auto Discover packets. Like "Multicast Group", this option only applies if Discovery is allowed. The default is 3498.
Blocked/Allowed The "Blocked" and "Allowed" entries are lists of IP addresses or IP address ranges which should be allowed or disallowed access. IP ranges are given with asterixes. So "127.0.0.1", "10.*", or "192.168.0.*" would all be acceptable. The word "all" is also acceptable. A common practice is to block all connections by default, and then only allow certain known IP ranges. Such is the case in the figure above.

The third tab is "History", which configures settings related to the archiving of data from the modules.

Figure 2-3. RSPD "History" Tab

Table 2-8. Network Configuration Options

OptionDescription
History Type Specifies which type of history saving should be done. Possible options are "none", "RemoteText", and "MySQL". The default is "none".
Connect securely Applies to RemoteText type. Specifies if the connection should be done securely, that is using SSL communication. Default is true.
Persistent Connections Specifies if connections should be persistent (remain connected). The alternative is to reconnect each time data needs to be saved. Default is true.
Reconnect Specifies whether the RSPD should attempt to reconnect to the remote host in the event of a connection failure. The default value is false.
Host Specifies the History Listener location (when combined with the RemoteText type) or the MySQL host (when combined with the MySQL type). Can be either a hostname or an IP address. Default is "localhost".
Port When combined with the host variable, this option specifies which port to connect to on a remote host. The default, when combined with a RemoteText type, is 3496 (to connect to a History Listener), and 3306 when the MySQL type is specified.
Login/Password/Database These three options apply only to a MySQL database. They specify the login/password to use and the specific database to store history data to.

The fourth tab is "Thresholds", which allows users to set thresholds and be warned when they are crossed through emails or commands. All of the settings except for the threshold itself can have default values, which are set by selecting "defaults" from the list on the left.

Figure 2-4. RSPD "Thresholds" Tab

Table 2-9. Thresholds Configuration Options

OptionDescription
Threshold This sets the threshold itself. This is the only option which cannot have a default setting (since presumably each threshold would be different. The form of a threshold is one or more module expression separated by ANDs or ORs (but not both within one threshold). Each module expression depends on the module being referenced and module documentation should be read for specifics on any given module.
Event Sets the action which will occur when the threshold is crossed. Can be "none" if no action should be taken, "email" if an email alert should be sent to each of the mailto addresses, "command" if RSPD should attempt to execute a specified command, or "both" if an email should be sent and a command should be executed.
Command If the threshold is set to run a command when a threshold is crossed, then this option indicates what that command should be.
Mail From The address that should be put into the From field of any email messages, indicated where it originated from. The address does not need to be a valid email address, though the domain should be a valid domain. For instance, "RSPD@somedomain.com" would be a valid address.
SMTP The SMTP server that is to be used to relay warning email messages through. The server can require authentication, as the RSPD supports remote SMTP authentication.
SMTP Login/Password Specifies the login/password to use for a previously definied SMTP server, if the server requires a login.
Addresses A list of email addresses to which the RSPD should send warning messages when a threshold is crossed.

The fifth and final tab is "Modules". In this tab all of the modules are added and configured. Use the "Add..." and "Remove" buttons in the bottom left of the window to add and remove modules from the list. Selecting a module name loads its settings. There are two tabs containing options for the modules: General and Configuration. The controls in the General tab are described in the table below. The information in Configuration changes depending on the module. Some modules modules require no additional configuration, while others may allow or require further setting.

Figure 2-5. RSPD "Modules" Tab

Table 2-10. Modules Configuration Options

OptionDescription
Disabled If this setting is set to true, then this module will be ignored by the RSPD when it loads its modules. The reason for this setting is that it may be useful to keep the configuration options for a module, but temporarily disable it for a time.
Module Poll Time Indicates how frequently (in seconds) RSPD will poll this module for updated data.
Location Specifies the location of the module.
Save data/Save every __ cycles Both of these options deal with how history data should be saved for the given module. The first option specifies whether or not history data should be saved, and which type of dat should be saved. The second specifies how often the collected system information should be saved. A value of 1 would mean that every time a module is polled, RSPD will save its data to a history file. A value of 2 would imply that every other time the module is polled its data is saved. The default value is 1.

RSP Status Window

One of the latest features in RSP is the new RSP Status Window. This allows Microsoft Windows users to view local system details collected by the RSP agent without opening a web browser.

To get this information, first start the RSP Collector in Windows. Once started, an icon appears in your Windows Start Menu System Tray (likely at the bottom-right of your screen - it looks like a small light-bulb). Right clicking on this icon brings up a menu, from which you can select the RSP Status Window feature. A window similar to that shown in Figure 6 appears.

Figure 2-6. RSP Status Window: Performance Tab

Note that there are three tabs at the top of the window: Performance, Hardware, and Logs. Each of these shows different details about your computer and the current statistics collected by the RSP agent. On the Performance tab, you'll see a table of real-time system statistics gathered by the agent, including network bandwidth usage (and breakdowns by protocol), CPU and disk usages, and other information. Each entry in this table corresponds to an RSP Module. For instance, if you have the NetStat module turned off, you won't see it display in this table. See the chapter on Module in RSPD for more details about RSP Modules.

Clicking on the Hardware tab in this window brings up a slightly different view of your system, focusing instead on what hardware is currently installed on your system (see Figure 7). In this example, notice that the CPU type and speed, memory usage, and other information is displayed.

Figure 2-7. RSP Status Window: Hardware Tab

Finally, the Logs tab (shown in Figure 8) displays the current operating status of the RSP Agent. If you're fine-tuning your installation of RSP (say by adding or removing modules), look to this window to see what's currently being reported by the agent.

Figure 2-8. RSP Status Window: Logs Tab

To close the Status Window, click either the Close button (located at the bottom-right of the window), or the small X button at the top-right. You can also use the Status Window to startup the RSP Web interface software, simply by clicking the Launch Viewer button (located at the lower-right of the window). This will startup the RSP Web interface server (a splash-screen is displayed noting it's being started), and another icon will appear in your Windows Start Menu System Tray. This allows you to open a web browser to connect to the RSP Web interface and view the statistics of both this local RSP agent and any other agents you may have running on other critical computer systems. See the chapter on RSP Web for more details.

Modules in RSPD

One of the most significant features of the RSP collection process is the fact that RSPD doesn't itself retrieve data, but instead uses various programs called modules. There is one module for every resource or statistic that is to be collected. For example, there is one module that gives information on memory usage, one for the number of running processes, one to check ports, and many others. Users can even write their own modules, which make the types of data that can be monitored almost limitless. However, RSP comes with a number of pre-made modules that collect important information about computers and networks, such as uptime, CPU and memory usage, drive space, process activity, available hosts and others. When RSPD is first started, it starts each module and sets up a communications channel with it, collecting and storing data when specified.

Developing custom modules is a relatively easy process, and can be done in a number of popular programming languages (including C, C++, Perl and Java). These modules are treated as sub-processes on a computer system with an IPC (Inter-Process Communications) wrapper allowing communication between the module and the RSPD. If you do write a module, please consider sharing it with others by visiting Module Central at the Draconis Software webpage: http://www.dracoware.com/modules/index.php.

Linking with the Library (C versions)

There are two ways to link the RSP Module API into your C programs: either as a static object, or as a shared library. Either method is acceptable, though your project requirements may dictate which method is preferable. Keep in mind that linking with the static library means a new version of your software must be built whenever your users wish to use the latest version of the RSP Module API. Shared object libraries solve this problem, but create more of a hassle in maintaining version dependencies (say your program requires a certain version of the RSP Module API and is incompatible with different versions). Be sure to keep these considerations in mind when deciding which linking method to use.

The shared object version of the RSP Module API is available in the librspmod.so file. If you are using GCC (a free compiler and linker popular on the Linux and UNIX platforms, though also available for Windows and Macintosh), simply add the command -lrspmod to the end of your link command:

gcc -o PROGRAM_NAME SOURCE_CODE.c -lrspmod
			

In order for the above command to work, it is imperative that GCC be able to find the librspmod.so file. Therefore, you can either install the file into a common library location on your system (usually /usr/local/lib on Linux and UNIX platforms), or give GCC an explicit command to find the shared library (using the -L parameter). Check with your linker's documentation for complete details on linking C code with shared object libraries.

To link with the static version of the C library, you need to use the librspmod.a file, which contains the object code needed to build your application. When your program is linked, the contents of this library are copied into your application's executable, making its file size grow (though not by very much, as the RSP Module API is a fairly small library).

Using the GCC compiler/linker, simply include the librspmod.a file along with all of your code object files (usually named with a .o suffix), such as in the following example:

gcc -o PROGRAM NAME SOURCE_CODE.o /PATH/TO/librspmod.a
			

Again, be sure to check with your linker's documentation for detailed instructions on including static libraries into your applications.

Once you are building your applications using either version of the RSP Module API, you need to include the RSP Module API header file into all appropriate C coded files (which is done using the #include <rsp.h> directive). Note that your compiler needs to be able to find this file, so it either needs to be placed in a standard location (such as /usr/include on Linux and UNIX platforms), or in a directory that can be otherwise found by your compiler. Using GCC, the -I option can be used to specify a directory that contains header files. Check with your compiler's documentation for specific instructions on including files (and how to locate them on your system).

Once you have successfully built an application, including linking against either the shared object or static versions of the library, as well as placing a #include <rsp.h> line into your source coded file(s), you are ready to begin programming with the library.

Linking with the Java Version

To build a Java application using the Java version of the RSP Module API, you compile your code with the rspmod.jar archive file. This file contains a number of Java class files, assembled together into a single Java Archive file (JAR). If you are using Sun Microsystems's compiler on a Linux or UNIX system, you can use a command similar to the following:

javac -classpath /PATH/TO/rspmod.jar SOURCE_CODE.java
			

Be sure to check with your specific compiler for details on compiling against a JAR file.

To reference the Java code located within this JAR file, you must place appropriate import lines into your Java files, such as

import com.dracoware.*;
			

Alternatively, you can reference each class specifically (there are 3):

  • RspGraphReturnData

  • RspModuleBackend

  • RspModuleException

Once you have completed both of these steps, you are now ready to begin developing your RSP Lib API-aware Java application.

Linking with the Perl Version

The Perl version of the RSP Module API is used in a slightly different way than the Java or C versions of the library. The Perl version is made up of two parts: the C shared object library and the Perl wrapper interface. When developing with the library, you call the wrapper routines, which in turn call the C version of the routine.

To begin developing in Perl, install the appropriate version of the C library and the Perl wrapper using the included installation script (install_perl_files.sh on Linux and UNIX systems). Once this has been done, place the following line at the top of your Perl code file(s):

use rspmod;
			

This will reference the rspmod.pm module. Once this line has been added to your Perl file(s), build the application like you would normally build it. You can now begin using the RSP Module API software in your Perl program.

Structure of a module

All modules, regardless of the language in which they are written, follow the same basic structure. At the beginning of a program, a module object is created and initialized. This object is a structure in C, and a class in Java and Perl. This object is referenced in other function calls to communicate with the RSPD and access data related to the module.

Many modules require additional information from the user to perform correctly. Any variables set within the "config" block of the RSPD's configuration file is sent directly to the module itself. Using a few functions, the module can directly access this data and use it.

It is up to the module to update (that is, give current data to the RSPD) on its own. The module gets the poll time and may choose to sleep during that time or perform other functions. When the time has passed, the module checks any set thresholds to see if they should be crossed or uncrossed. It then sets the updated data, as well as graphable data it it desires. It then posts all the data to the RSPD. At any time, the module can send log messages to the RSPD which will be viewable by the user as a method of communication.

There are also a number of functions which exist to help convert different types of strings into number values which can be used as graph data. For example, one function can take time strings such as "1 day, 2 hours, 3 minutes" and convert it into a number representing seconds.

C Function Reference

Table of Contents
RSP_init -- Initializes RSP Module library.
RSP_log -- Log a module message to the RSPD.
RSP_waitNextEvent -- Waits the specified number of seconds, or until an event occurs.
RSP_getConfigValue -- Gets the first piece of data associated with the given name.
RSP_getConfig -- Gets the config element associated with the given name.
RSP_nextConfigData -- Gets the next value associated with the given config element.
RSP_nextConfigName -- Gets the next name of config elements that have been set.
RSP_nextThreshold -- Get next threshold in chain.
RSP_giveData -- Send update to RSPD.
RSP_setThreshold -- Indicate a threshold has been crossed.
RSP_giveGraphData -- Send graph data to RSPD.
RSP_postMessage -- Send graph and module data to RSPD.
RSP_getPolltime -- Get update interval for this module.
RSP_cleanup -- Clear all API memory.
RSP_timeConvert -- Converts time value to long.
RSP_smallTimeConvert -- Converts small time value to double.
RSP_bigSizeConvert -- Converts size value to double.
RSP_smallSizeConvert -- Converts small size value to double.
RSP_percentConvert -- Converts percent value to decimal.
RSP_boolConvert -- Converts boolean value to T/F.

This section details each of the functions available to the C version of the library. It should be noted all of the functions listed have corresponding error codes and messages in such cases where they occur. When an error happens, the function will generally return a value with signals this (such as NULL or -1). In addition, the integer rsp_error will be set to the error value, and the string rsp_errorstr will contain to the error message. To access these variables, simply add the following two lines to your code:

extern int rsp_error;
extern char rsp_errorstr[RSP_ERROR_SIZE];
		

Java Function Reference

Note that the Java functions are broken down by Class and are included in a separate reference guide: the Module Developer Javadoc HTML Documentation, available here.

Perl Function Reference

The perl functions for writing modules are very similar to those in C, as the perl module in fact uses the compiled C library. The main difference is that the functions are called directly from the object in object-oriented style.

A module object is created by creating a new RSP_moduleBackend object, passing to it the name of the module. From then on, functions are called from the object itself. For example:

use rspmod;

$mod = new rspmod::RSP_moduleBackend("Uptime");

# later in the code...
$mod->giveData($newModuleData);
$mod->log(1, "Here is a log message);
		

Once the object is created functions are called directly from it. Most of the functions described in this reference are called from the module object. However there are two other possible objects. The first is a config element. When a user sets values to variable names in the config block (in the RSPD configuration file), you can access this data in a few ways. One way is to get a config element object with getConfig(). This object has one function, nextConfigData() which iterates through all data for this object. For example:

$config_elt = $mod->getConfig("checkDrive");

# iterate through all the values
while(defined($val = $config_elt->nextConfigData())) {
	...
}
		

Another type of object is the RSP_graphReturnData object. This object represents a piece of graph data which is to be returned to the RSPD. It has three fields which are set when created: type, key and data. They can be created and accessed as follows:

$graph_data = new rspmod::RSP_graphReturnData(1, "uptime", "3600");

# Get the settings back
$type = $graph_data->getType();
$key = $graph_data->getKey();
$data = $graph_data->getData();

# Now we give this data to be sent to the RSPD
$mod->giveGraphData($graph_data);
		

The details of what the graph types mean are described in the description of the giveGraphData() function.

Module Object Functions

Table of Contents
RSP_moduleBackend -- Creates a new module object.
log -- Log a module message to the RSPD.
waitNextEvent -- Waits the specified number of seconds, or until an event occurs.
getConfigValue -- Gets the first piece of data associated with the given name.
getConfig -- Gets the config element associated with the given name.
nextConfigName -- Gets the next name of config elements that have been set.
nextThreshold -- Get next threshold in chain.
giveData -- Send update to RSPD.
setThreshold -- Indicate a threshold has been crossed.
giveGraphData -- Send graph data to RSPD.
postMessage -- Send graph and module data to RSPD.
getPolltime -- Get update interval for this module.
timeConvert -- Converts time value.
smallTimeConvert -- Converts small time value.
bigSizeConvert -- Converts size value.
smallSizeConvert -- Converts small size value.
percentConvert -- Converts percent value to decimal.
RSP_boolConvert -- Converts boolean value to T/F.

These are the details of all of the functions available to the module object.

Example Module Code - C


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "rsp.h"

void update(void);
long getUptime(void);

extern char rsp_errorstr[RSP_ERROR_SIZE];
RSP_moduleBackend* mod;

int main ()
{
	int returnVal;
	
	// initialize this module (and register its name)
	if((mod = RSP_init("Uptime")) == NULL)
	{
		// we failed to startup
		RSP_cleanup(mod);
		exit(0);
	}
	
	while(1)
	{
		update();
		
		returnVal = RSP_waitNextEvent(mod, RSP_getPolltime(mod));
		if(returnVal == -1)
		{
			RSP_cleanup(mod);
			exit(0);
		}
	}

	return 0;
}

void update(void)
{
	int nDays = 0, nHours = 0, nMinutes = 0, nSeconds;
	char uptime[100], name[] = "uptime", nowData[256], *threshold;
	long now;
	RSP_graphReturnData graphData;

	now = getUptime();

	nDays = (int)(now / 86400);
	nHours = ((int)(now / 3600)) - (nDays * 24);
	nMinutes = ((int)(now / 60)) - (((nDays * 24) + nHours) * 60);
	nSeconds = now - (((int)(now / 60)) * 60);

	sprintf (uptime, "%d days, %d hours, %d minutes, %d seconds", nDays, nHours, nMinutes, nSeconds);

	// Give our data to the library
	RSP_giveData(mod, uptime);

	// Go through each threshold (if any) and determine if it's crossed
	while((threshold = RSP_nextThreshold(mod)) != NULL)
	{
		char szVariable[256], szOp[20], szValue[255];
		int curr = 0;
		long thresh;

		// Parse the threshold into a variable, operator, and value
		// For example: "uptime < 2 hours"
		while((threshold[curr] != '<') && (threshold[curr] != '>') &&
		  (threshold[curr] != '=') && (threshold[curr] != '!') && (threshold[curr] != '\0'))
			curr++;

		if(curr != 0)
			strncpy(szVariable, threshold, curr);

		szVariable[curr] = '\0';

		if(curr == (int)strlen(threshold))
			szOp[0] = '\0';
		else
		{
			curr++;
			if(threshold[curr] == '=')
			{
				strncpy(szOp, threshold + curr - 1, 2);
				szOp[2] = '\0';
				curr++;
			}
			else
			{
				strncpy(szOp, threshold + curr - 1, 1);
				szOp[1] = '\0';
			}
		}

		if(curr != (int)strlen(threshold))
			strncpy(szValue, threshold + curr, strlen(threshold) - curr);

		szValue[strlen(threshold) - curr] = '\0';

		// Remote beginning and trailing whitespace, and any quotes around the value
		while((szVariable[strlen(szVariable) - 1] == ' ') || (szVariable[strlen(szVariable) - 1] == '\t'))
			szVariable[strlen(szVariable) - 1] = '\0';

		while((*szValue == ' ') || (*szValue == '\t') || (*szValue == '"'))
			strcpy(szValue, szValue + 1);

		if(szValue[strlen(szValue) - 1] == '"')
			szValue[strlen(szValue) - 1] = '\0';

		if(strcasecmp(szVariable, "uptime") != 0)
		{
			RSP_log(mod, RSP_WARN, "Invalid threshold: %s. Must start with `uptime'.", threshold);
			continue;
		}
		else if(strlen(szOp) == 0)
		{
			RSP_log(mod, RSP_WARN, "Invalid threshold: %s.  Does not contain operator.", threshold);
			continue;
		}

		thresh = RSP_timeConvert(szValue);

		if(thresh == -1)
		{
			RSP_log(mod, RSP_WARN, "Invalid value for threshold: %s. Not a valid time.", szValue);
			continue;
		}

		if(strcmp(szOp, "<") == 0)
		{
			if(now < thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else if(strcmp(szOp, "<=") == 0)
		{
			if(now <= thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else if(strcmp(szOp, ">") == 0)
		{
			if(now > thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else if(strcmp(szOp, ">=") == 0)
		{
			if(now >= thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else if(strcmp(szOp, "==") == 0)
		{
			if(now == thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else if(strcmp(szOp, "!=") == 0)
		{
			if(now != thresh)
				RSP_setThreshold(mod, threshold, 0);
		}
		else
			RSP_log(mod, RSP_WARN, "Invalid operator for threshold: %s.", szOp);
	}

	// We want to be able to graph the uptime.
	sprintf(nowData, "%ld", now);
	graphData.iType = GRAPH_TIME;
	graphData.szKey = name;
	graphData.szData = nowData;

	// Give this graph data
	RSP_giveGraphData(mod, &graphData);

	// Post the message
	if(RSP_postMessage(mod) == -1)
	{
		RSP_log(mod, RSP_WARN, "Error while sending data to RSPD: %s Quitting.", rsp_errorstr);
		RSP_cleanup(mod);
		exit(0);
	}
}
		

Example Module Code - Java

import com.dracoware.module.*;
import java.util.Enumeration;
import java.util.Random;
import java.io.IOException;

public class javaModule
{
	RspModuleBackend mod;

	public static void main(String[] args)
	{
			javaModule j = new javaModule();
	}

	public javaModule()
	{
		try {
			mod = new RspModuleBackend("javaModule");

			while(true)
			{
				if(mod.waitNextEvent(mod.getPolltime()))
					System.exit(0);

				update();
			}
		} catch (RspModuleException e) {
			System.exit(0);
		}
	}

	public void update()
	{
		// Just as an example, give random data
		Random x = new Random();

		mod.giveData("Random data is " + x.nextInt());

		RspGraphReturnData graphdata = new RspGraphReturnData(0, "data", "2");
		mod.giveGraphData(graphdata);
	
		try {
			// This would give us all the possible config names
			String[] names = mod.getConfigNames();

			// All the values of "myArray" variable
			String[] values = mod.getConfigData("myArray");	

			// Get all the thresholds and set the first one
			String[] thresholds = mod.getThresholds();
			mod.setThreshold(thresholds[0], true);

			// Post our data to the RSPD
			mod.postMessage();
		} catch (RspModuleException e) {
			System.exit(0);	
		}
	}
}
		

Example Module Code - Perl

#!/usr/bin/perl

# An example perl module which checks the number
# of processes.

use strict;
use lib "modules/rsp-interfaces/perl";
use rspmod;
use Proc::ProcessTable;

my $mod;

sub update() {
	my $t = new Proc::ProcessTable;

	my $argument = $mod->getConfigValue("procCheck");

	if(!defined($argument)) {
		my $count = scalar(@{$t->table});
		my $proccount = "$count processes running";

		$mod->giveData($proccount);

		my $graphData = new rspmod::RSP_graphReturnData(0, "count", "$count");
		$mod->giveGraphData($graphData);

		while(defined(my $threshold = $mod->nextThreshold())) {
			if($threshold =~ /^\s*count\s*([!=<>]=?)\s*(.*)/) {
				if($1 eq "<") {
					$mod->setThreshold($threshold) if $count < $2;
				} elsif($1 eq "<=") {
					$mod->setThreshold($threshold) if $count <= $2;
				} elsif($1 eq ">") {
					$mod->setThreshold($threshold) if $count > $2;
				} elsif($1 eq ">=") {
					$mod->setThreshold($threshold) if $count >= $2;
				} elsif($1 eq "!=") {
					$mod->setThreshold($threshold) if $count != $2;
				} elsif($1 eq "==") {
					$mod->setThreshold($threshold) if $count == $2;
				}
			}
		}
	}
	else {
		my $proccount;
		foreach my $arg (split(/[ |\t]/, $argument)) {
			my $count = 0;
			foreach my $p (@{$t->table}) {
				$count++ if $p->cmndline =~ /$arg/;
			}

			$proccount .= "$count instances of $arg, ";

			my $graphData = new rspmod::RSP_graphReturnData(0, $arg, $count);
			$mod->giveGraphData($graphData);

			while(defined(my $threshold = $mod->nextThreshold())) {
				if($threshold =~ /$arg\s+(.)\s+(.*)/) {
					if($1 eq "<") {
						$mod->setThreshold($threshold) if $count < $2;
					} elsif($1 eq "<=") {
						$mod->setThreshold($threshold) if $count <= $2;
					} elsif($1 eq ">") {
						$mod->setThreshold($threshold) if $count > $2;
					} elsif($1 eq ">=") {
						$mod->setThreshold($threshold) if $count >= $2;
					} elsif($1 eq "!=") {
						$mod->setThreshold($threshold) if $count != $2;
					} elsif($1 eq "==") {
						$mod->setThreshold($threshold) if $count == $2;
					}
				}
			}
		}

		$mod->giveData(substr($proccount, 0, length($proccount) - 2));
	}

	eval { $mod->postMessage(); };
	exit if $@;
}

$mod = new rspmod::RSP_moduleBackend("ProcCount");

while(1) {
	my $returnVal;

	eval {
		$returnVal = $mod->waitNextEvent($mod->getPolltime());
	};

	if($@) {
		if($returnVal == -1) {
			$mod->log(1, "Message from RSPD was not recieved correctly.  Quitting");
		}

		exit();
	}

	update();
}