Dynamic Label and Alert Text
When you edit a device label, notifier title, or notifier message, you can use a number of techniques to dynamically control the resulting text.
Showing Parameter or Variable Values in a Device Label
When editing a device label, you can show probe parameters, probe variables, and device export attributes in the label.
- Probe parameters - any field in the selected probe's Set Probe pane, specified in the <parameters> section of the probe.
- Probe variables - variables defined in the probe. In SNMP probes, specified in the <snmp-device-variables> section of the probe.
- Device attributes - any attribute of a device exported using the Data File command (available from the File menu's Export submenu).
Use the following syntax:
${param:<name of parameter, variable, or attribute>}
For example, to show the connect time in a device label corresponding to a TCP probe, your label might look similar to the following:
<Smart Name>
Time to establish connection: ${param:_connect} msec.
Notice, there is no space after the param: and the name of the variable. (The underscore is part of the variable name. Most names do not have the underscore.) Any variable that can be shown in the <snmp-device-display>, <script-output>, or <command-display> section of the probe can be used in a label using this syntax. You can show a parameter of the Basic OID probe just as well. For example,
Getting data from: ${param:Object ID}
You can show device export fields as follows:
Belongs to map: ${param:MapName}
Using JavaScript in a Device Label or Notifier
You can also use JavaScript in a device label or notifier to collect information, process it programatically, and include the results in the label or notifier. Use the following label syntax in a label:
<? write( "Hello World" + "\n"); ?>
The <? and ?> markers indicate the beginning and end of the JavaScript.
Variables and Scope in JavaScript
Important: JavaScript in labels and notifiers runs in the global scope within Intermapper. If you declare a variable within the global scope, rather than within a function, the variable is accessible for reading and writing by JavaScript running in any other device label within Intermapper. This can produce unexpected results if you attempt to run the same script in multiple devices.
JavaScript functions are supported and you can store values within devices and notifiers, which are remembered between polls. Fortra recommends using these techniques when you need to protect a variable from being overwritten. For more information on setting variables in devices, see Remembering Values from One Poll to the Next.
Example: Simple Scripted Label
The following is a more complex example:
<Smart Name>
<?
for (var i=1; i<=3; i++) {
writeln( "Hello World #" + i);
}
?>
The displayed label above appears as follows:
write and writeln Functions
The following functions are used to write output to the label:
- The write function sends its output to the label without a line break.
- The writeln function sends its output to the label and appends line break at the end, so you do not need to explicitly append the "\n" in your JavaScript code.
Accessing Probe Parameters
Use JavaScript to access probe parameters using the following syntax:
<? writeln( "Getting data from: " + self.get( "Object ID")); ?>
The self object refers to the device whose label you are setting. The self object is always available when using JavaScript to generate a label. Use the same syntax to get access to a probe variable as well. For example,
<?
var connTime = self.get( "_connect");
writeln( "Time to establish connection: " + connTime);
?>
JavaScript Error Handling
If you misspell the name of your variable, (by using _conect in the previous example) the label is displayed as follows:
If you look in the debug log, you see the following message:
12:15:46 JS> [Device: map 'Exporting Fields', device 'nitro.dartware.com.', probe
'SNMP Traffic']:BAD ARG: There is no variable called '_conect'. It should be the name of a probe variable without '$' or curly braces.
The error message tells you the map, device, and probe in which the error occurred as well as details about what caused the problem.
A JavaScript syntax error results in the following label:
The debug log contains the exception message, but give details about the syntax problem.
Execution Time Limit
The execution time of a script is limited to 50 and 100 msec. This prevents the script from monopolizing the CPU. This is more than adequate time to produce a complex label or notifier output.
For example, the following:
<?
for (var i = 0; i < 1000000; i++) {
if(i%10000 == 0) {
writeln( "testing the timeout " + i);
}
}
?>
Generates the following label:
Three ticks is approximately 50 msec.
Remembering Values From One Poll to the Next
You can retain the value of a variable from execution of the JavaScript to the next using one of the following techniques:
- JavaScript Global Variables - any JavaScript variable declared at global scope is retained from one execution of JavaScript to the next. The variable is visible regardless of which device is running the script. The variable is also visible regardless whether the JavaScript is running to generate label text or a notifier's text. Keep this in mind when using the same script for more than one device; you might unexpectedly overwrite a global variable.
- Device JavaScript Variables - a piece of data can be stored in a device. An advantage of these variables over global variables is that each device can have the same named variable but the value will be different for each device. You can use self.get(...) and self.set(...) to read and write this data. The name of the variable must be different than any probe parameter or probe variable.
Example: Storing a Value With a Device
To read the value stored in the device's variable “MyInformation” into myinfo:
var myinfo = self.get( "MyInformation" );
To write the value of myinfo out to the device's variable “MyInformation”:
storedinfo = self.set( "MyInformation", myinfo );
The function self.set(...) returns the stored value. If the value cannot be saved, for instance, if you try to save to an existing probe parameter or probe variable, the returned value is the actual value of the parameter or variable, not the one you tried to save.
Example: Incrementing Counter
The following examples shows how to implement a counter that increments each time the label is drawn. Note that the first time the script runs, the counter variable does not exist.
This script below gets the value of “Count”, displays it, increments it, and saves it. The first time the script runs, self.get() returns the “BAD ARG, see debug log” string . Since JavaScript cannot turn this value into a number, you can use the JavaScript isNaN() function to determine that n is NaN (Not a Number), and thus has not been initialized.
<?
var n = Number( self.get( "Count"));
if (isNaN(n)) n = 0;
writeln( "Count is " + n);
n++;
self.set("Count", n);
?>
A similar technique would also work for JavaScript global variables as well.
Accessing Device Attributes
You can also use JavaScript to access device attributes. The syntax is different than for accessing probe parameters and variables. It still uses the self object, but the attribute names are simply properties of the self object. The syntax looks like this:
<?
var rtt = self.RoundTripTime;
writeln( "Round-trip time is \n" + rtt + " msec");
?>
The above JavaScript reads the last round-trip time into rtt, and displays it as follows:
If you misspell a device attribute, the error shows up as a JavaScript syntax error because the misspelling is not JavaScript data, but actual language syntax. “JS EXCEPTION, see debug log” is shown in the label and a detailed explanation in the debug log.
Any device attribute can be used in a label. For a list of device attributes, see Device Attributes.
Accessing Interface Attributes
Devices connect to networks through interfaces. Each device has a property called interfaces. In JavaScript, this property is displayed as an array of Interface objects. The following example below lists all down interfaces:
<?
var downInterfaces = 0;
for (var i =0; i < self.interfaces.length; i++) {
var ifc = self.interfaces[i];
if ((ifc.Enabled == "TRUE") && (ifc.Status == "down")) {
downInterfaces++;
write( ifc.Index + ". ");
write(ifc.Alias.length > 0 ? ifc.Alias : ifc.Name );
writeln( " : " + ifc.Status);
}
}
writeln();
writeln(downInterfaces + "/" + self.interfaces.length + " interfaces down");
?>
Any interface attribute can be used in a label. For a list of interface attributes, see Interface Attributes.