This tutorial covers some general topics on writing scripts using the Alertra Scripting Language. For more detail discussion of specific topics, please see the Articles section of the Alertra web site under the heading Scripting: Unlock the Power of Alertra
Note: Some of the sample code blocks have been reformatted to fit comfortably within your web browser. Lines that end with the underline character, "_" continue the same statement on the next line. When writing your own ASL scripts, you must include the entire statement on the same line. There is no line-continuation character in ASL.
2.1. Check a Site
The simplest script to write is one that checks an Internet resource and accepts the default actions when the script fails:
# Check the following URL and # take the default action if it fails dns "www.alertra.com" tcp $HTTP_PORT http get,redir "/"
The dns call looks up the given host name and stores the IP address for use by the other commands in the script. The tcp call makes a socket connection to port 80 (HTTP_PORT is a predefined constant representing the default connection port for HTTP servers) of the server. The http command actually retrieves the default page from the web server at the selected host. If there is a problem performing any of these tasks, an error is generated and notifications are generated based on the schedule for the script.
We can get a little fancier and check to see if the page has the size we expect and a required key phrase:
# Check a site, make sure the page is the correct # size and has the given key phrase. dns "www.alertra.com" tcp $HTTP_PORT http get "/login.asp?userid=jsmith&password=pocahontas" if not "Sample Site Corp" in $CONTENT then begin error "Returned page not correct" end if not $CONTENT_LENGTH > 1024 then begin error "Page not correct size" end
2.2. HTTP Parameters
We've already seen how you can pass parameters in the URL used to retrieve an HTTP document. Those used the GET method, but you can also use the POST method:
# Pass some parameters to an HTTP form dns "www.sample.com" tcp $HTTP_PORT form userid = "jsmith" form password = "pocahontas" http post "/login.asp"
In case you're wondering, the socket connection created by the tcp command doesn't need to be explicitly closed. Any of the other protocol commands (except send and recv) will automatically close the socket.
2.3. Error Handling
If you want, you can change the default error handling used by ASL. Normally, any problem with a command aborts the script immediately and an error notification is sent to all contacts scheduled to be notified for this script.
You can change this by creating your own error handler. The on error command allows you to either install your own handler:
on error goto error_handler
Or you can just ignore errors:
on error goto next
Here is an example of installing and using a custom error handler.
on error goto script_error # Get the IP address for the site dns "www.alertra.com" # Connect to the FTP server tcp $FTP_PORT # Request the readme.txt file with the anonymous login ID # Only get the first 512 bytes of the file ftp "/pub/readme.txt" "anonymous" "firstname.lastname@example.org" 512 # Make sure we got the right file if not "Alertra" in $CONTENT then error "Returned file not correct." goto exit :script_error # Ignore DNS errors if not $LAST_COMMAND = "dns" then goto send_error exit "DNS failed, site not checked." :send_error on error goto 0 error $LAST_MSG :exit
The first line of our script changes how ASL handles errors. Anytime the error command is called or an internal command generates an error, the script will jump to the ":script_error" label. This allows you to handle script errors in a central location. This script looks at the name of the command that generated the error ($LAST_COMMAND). If the command was a DNS lookup DNS, the script chooses to ignore the error, log the fact that it failed, and exit gracefully.
The final section of the error handler removes the error handler and then re-generates the error so ASL's normal notification mechanism will notify the scheduled contacts of the error.
In your scripts, there really isn't any reason to do this, but just to show that it can be done, lets recode the original example with a totally custom error handler:
on error goto next dns "www.alertra.com" if not $LAST_CODE = "0" then goto bad_dns tcp $HTTP_PORT if not $LAST_CODE = "0" then wait 20;tcp $HTTP_PORT if not $LAST_CODE = "0" then wait 20;tcp $HTTP_PORT if not $LAST_CODE = "0" then goto bad_socket http get,redir "/" if not $LAST_CODE = "0" then goto bad_http goto exit :bad_dns on error goto 0 info "(" + $LAST_CODE + ") " + $LAST_DESCRIPTION error "Unable to resolve DNS entry. Check primary " + "and secondary DNS servers." :bad_socket on error goto 0 info "(" + $LAST_CODE + ") " + $LAST_DESCRIPTION error "Unable to connect to host. " + "Make sure HTTP server is running on port " + $HTTP_PORT + "." :bad_http on error goto 0 info "(" + $LAST_CODE + ") " + $LAST_DESCRIPTION error "Unable to retrieve " + $LAST_RESOURCE + "." :exit
This example shows two other features of ASL scripting. While trying to make the socket connection to the server, we attempt the connection 3 times and wait 20 seconds between each attempt. The IF statement allows you to chain commands together with a semi-colon, so we can wait and retry the connection in one statement. You could also use the begin/end construct to accomplish the same thing:
if not $LAST_CODE = "0" then begin wait 20 tcp $HTTP_PORT end
2.4. Saving Data
You can save the contents of variables for use the next time your script is called. This can be used to determine when things change. For instance, if you want to know that the IP address the DNS server returns for your site changes you could do something like this:
dns "www.alertra.com" if $SAVE_IP = "" then set SAVE_IP = $LAST_IP if not $SAVE_IP = $LAST_IP then goto new_ip :check tcp $HTTP_PORT http get "/" goto exit :new_ip warning "IP address used to be " + $LAST_IP + " but is now " + $SAVE_IP goto check :exit set SAVE_IP = $LAST_IP save SAVE_IP
In this script, we check the site as normal. If ASL is unable to connect to the web server, an error notification will be sent to the scheduled contacts. However, we also check to see if the IP address has changed. After we retrieve the IP address from the DNS server, we compare it to what the IP address was last time the script ran. To do that we have to work a little magic.
If you ask for the contents of a variable and it doesn't exist, ASL returns an empty string. So our first IF checks to see if we have a valid SAVE_IP. If we don't then we set the SAVE_IP to the value of the current IP. This keeps the next IF statement from firing the first time we run the script. The last bit of magic is taken care of in the ":exit" section. The save command stores the contents of the variable. The next time the script is run, the variable will already exist which is what we want.
This final script demonstrates how you can detect if there have been changes made to your site.
dns "www.alertra.com" tcp $HTTP_PORT http get "/index.html" if $SAVE_DIGEST = "" then digest SAVE_DIGEST = $CONTENT digest HASH = $CONTENT if not $HASH = $SAVE_DIGEST then goto possible_hacker goto exit :possible_hacker error "Page has been modified." :exit set SAVE_DIGEST = $HASH save SAVE_DIGEST
The digest command creates a digest of the string it is given. The digest is like a fingerprint and it would be very difficult for someone to change the contents of a file in such a way that it would have different content but generate the same digest.
2.5. Low Level Functions
Low level functions can be used to interact with any socket based service that uses a text based protocol.
dns "www.alertra.com" tcp 5602 send "HELO\n" recv if $CONTENT = "Widget Server/1.0" then goto WidgetServer error "Server did not return proper version." :widgetserver recv "login:" send "jsmith\r\n" recv "password:" send "pocahontas\r\n" recv "READY.\r\n" goto exit :exit
The commands send and recv are low level functions that allow you to send and receive character data (and to a limited extent binary data) on an open socket. The send command is fairly straight forward; when called it sends the data provided to the server. You can include \r and/or \n to signifiy the carriage-return and new-line characters respectively.
The recv command acts a little differently depending on how it is called. In the first call to recv, the socket is read until no more data is available and that data is placed in the $CONTENT variable. If no data is received before the default timeout, an error is generated. Since we don't have an error handler installed, the script would be aborted.
In the later recv calls we tell recv the text we expect to receive. Instead of storing the response in a variable, the string you pass is compared to the data read from the socket. If the data read doesn't end with the string passed, an error is generated. Notice that in the receive string you can also pass \r and \n to signify the carrige-return and line-feed characters.
The for loop can be used to iterate over a fixed number of items:
for INTERATOR = START_INDEX to END_INDEX begin ... end
The for loop initializes ITERATOR to the value of START_INDEX. By default ITERATOR will then be incrememnted by 1 each time through the loop until it reaches END_INDEX.
for REC = 1 to $MYSQL_ROW_COUNT begin mysql cursor next if $MYSQL_COLUMN_status = "A" then begin info $MYSQL_COLUMN_0 + ", " + $MYSQL_COLUMN_email + ", Active" else info $MYSQL_COLUMN_0 + ", " + $MYSQL_COLUMN_email + ", Not Active" end end
In this example, the loop iterates the over the rows in a MySQL resultset. The variable REC will be set to the current index of the for loop through each iteration. In the example above, the loop will start at 1 and increment REC by 1 until REC is equal to the value of the variable $MYSQL_ROW_COUNT. The default increment is 1, but you can control this by using the step modifier. With step you can increment by any integer value as well as use negative values to run the loop backwards:
for I = 10 to 1 step -1 begin info $I end
Would result in the log containing the text:
10 9 8 7 6 5 4 3 2 1
If you only have one statement to execute in the loop, like the previous example, you could rewrite it like this:
for I = 10 to 1 step -1 info $I
The while loop allows a script to execute the same block of commands an indefinate number of times (note: ASL scripts are not allowed to execute more than 5,000 commands; a script that exceeds this limit will be killed by the system).
while EXPRESSION begin ... end
As long as the EXPRESSION remains true (1 is true in ASL while 0 is false), the loop will continue to execute. Once the EXPRESSION becomes false (0), then execution of the script will continue with the next statement after the while loop's end statement.
set N = 0 while $N <= 10 loop begin info "The value is " + $N set N = $N + 1 end
This example loops until the value of $N is greater than 10.
Alertra Script Language: Language Reference
Copyright © 2000-2013 Alertra, Inc. All rights reserved. Please read our privacy statement and our terms of service. [C]