Email and SMS alerts
There are two kinds of alerts to consider: Notification Alerts and Custom Alerts.
Inactivity alerts
Notification alerts or rules are managed through Iguana Settings in the Settings > Monitoring section. Here’s some good advice for smart way to use them.
- Set up a Channel Group which has all your production channels. i.e. the ones you care about if they go down.
- Set up two channel inactivity rules:
- One should be during working hours and should have a short time of inactivity.
- The second should be out of working hours with a longer period for inactivity.
This means you end up with relatively little configuration work to do for these types of rules.
Custom alerts
Whenever you use an iguana.logInfo()
statement from within a Lua Translator channel the output will get logged into the logs for that channel. This provides a great hook for implementing custom email notification logic.
The idea is this:
- Make yourself a helper function like this:
function Alert(Message) iguana.logInfo("ALERT:n"..Message) end
- From your Lua code you can invoke this function based on any arbitrary rule you like. That’s dead easy to do since it’s a full language and you can access any part of the data. i.e.
if ZID[3]:nodeValue() == 'VIP' then Alert("VIP patient - call the special team!") end
- Set up one standard notification rule that have the text query expression set to “ALERT” in an Informational message.
So now whenever the custom function is invoked it puts that into the logs which triggers the custom notification rule.
Soon there should be an interface for generating an email directly from Lua which will provide an alternative approach for doing this.
Sending an Email from Lua [top]
Sending an email using the Translator is easy with the built in SMTP facility:
function main(Data) -- Set up the parameters to be used with sending an email local smtpparams={ header = {To = 'sales@interfaceware.com'; From = 'testuser@mailserver.com'; Date = 'Thu, 23 Aug 2001 21:27:04 -0400'; Subject = 'Test Subject';}, username = 'user', password = 'password', server = 'smtp://domain.mailserver.com:25', -- note that the "to" param is actually what is used to send the email, -- the entries in header are only used for display. -- For instance, to do Bcc, add the address in the 'to' parameter but -- omit it from the header. to = {'sales@interfaceware.com','admin@interfaceware.com'}, from = 'Test User <testuser@mailserver.com>', body = 'This is the test body of the email', use_ssl = 'try' } net.smtp.send(smtpparams) end
As always auto-completion and help are close at hand:
Some commonly used header fields are:
Header Field | Description | Comment |
---|---|---|
From: | The email address, and optionally the name of the author(s). In many email clients this cannot be changed except by changing account settings. | Mandatory |
To: | The email address(es), and optionally name(s) of the message’s recipient(s). Indicates primary recipients (multiple allowed), for secondary recipients see Cc: and Bcc: below. | |
Subject: | A brief summary of the topic of the message. | |
Date: | The local time and date when the message was written. Like the “From:” field, many email clients fill this in automatically when sending. The recipient’s client may then display the time in the format and time zone local to him/her. | Mandatory |
Message-ID: | Also an automatically generated field; used to prevent multiple delivery and for reference in In-Reply-To: (see below). | |
Bcc: | Blind Carbon Copy; addresses added to the SMTP delivery list but not (usually) listed in the message data, remaining invisible to other recipients. | |
Cc: | Carbon copy; Many email clients will mark email in your inbox differently depending on whether you are in the To: or Cc: list. | |
Content-Type: | Information about how the message is to be displayed, usually a MIME type. | Non-standard |
In-Reply-To: | Message-ID of the message that this is a reply to. Often used to link related messages together. | |
Precedence: | Commonly with values “bulk”, “junk”, or “list”; used to indicate that automated “vacation” or “out of office” responses should not be returned for this mail, e.g. to prevent vacation notices from being sent to all other subscribers of a mailing list. | Non-standard |
Received: | Tracking information generated by mail servers that have previously handled a message, in reverse order (last handler first). | |
References: | Message-ID of the message that this is a reply to, and the message-id of the message the previous was reply a reply to, etc. | |
Reply-To: | Address that should be used to reply to the message. | |
Sender: | Address of the actual sender acting on behalf of the author listed in the From: field (secretary, list manager, etc.). | |
Return-Path: | When the delivery SMTP server makes the “final delivery” of a message, it inserts a return-path line at the beginning of the mail data. This use of return-path is required; mail systems MUST support it. The return-path line preserves the information in the from the MAIL command. | |
Errors-To: | Indicates where error messages should be sent. In the absence of this line, they go to “Sender:”, and absent that, “From:”. | Non-standard |
X-* | No standard header field will ever begin with the characters “X-“, so application developers are free to use them for their own purposes. | Extensions |
Tip: Fields like “X-Sender:” and “X-Mailer:” are common, but they are not part of the standard. In fact, any header fields not expressly defined in the RFC, is allowed, and ignored by most e-mail systems. So, we could have an e-mail message that uses headers like:
…
X-Sender: testuser@mailserver.com
X-Mailer: QUALCOMM Windows Eudora Version 4.3.2
Date: Thu, 23 Aug 2001 21:27:04 -0400
To: testuser@interfaceware.com
From: Test User <testuser@interfaceware.com>
Sender: <testuser@interfaceware.com>
In-Reply-To: <4.3.2.7.2.20010415150149.00b08080@mail.example.com>
Favorite-Color: Red
Cocktail: Martini, up, olive
Subject: test
…
Additional Information
- Wikipedia: Email provides a good overview, with many links to RFCs etc.
- RFC 5321 is the current email standard
- RFC 5322 is the current email message standard, with header fields
- RFC 4021 is a older standard containing mail and MIME header fields (including some fields omitted from 5322
Monitoring Queue Sizes [top]
If the queue count exceeds the threshold the script will log “ALERT:” followed by a description of the problem. That makes it very easy to detect this condition using a standard notification rule.
There are two examples given of calling this function. If no arguments are given then the script defaults to the current channel name and will raise an alert if the channel count exceeds 100.
These defaults can be overridden which is what the second example shows:
Source Code
You can load the code into the Translator from this project zip file MonitorQueueSize-FromTranslator, or copy and paste from below.
main module:
require 'queuemon' function main() -- Using default parameters queuemon.checkQueue() -- Setting the channel name and count explicitly queuemon.checkQueue{channel = '<your channel name>', count = 10000} end
queuemon module:
require 'iguanaconfig' queuemon = {} local function CheckChannel(Chan, Count, Name) if Chan.Name:nodeValue() == Name then local QC = tonumber(Chan.MessagesQueued:nodeValue()) if QC > Count then iguana.logDebug('ALERT:\n Channel '..Name..' has '..QC..' messages queued.') return true end end end function queuemon.checkQueue(Param) -- We default to a queue count of 100 if not Param then Param = {} end if not Param.count then Param.count = 100 end if not Param.channel then Param.channel= iguana.channelName() end local url = '' local webConfig = iguanaconfig.config().iguana_config.web_config -- use http or https for API query based on Iguana settings if webConfig.use_https:S() == 'true' then url = 'https://localhost:' else url = 'http://localhost:' end url = url .. webConfig.port..'/status.html' iguana.logDebug(tostring(url)) trace(url) -- We need a user login here - using *admin* for demo only (as it usually works) -- Best to use a user with minimal permissions. local S = net.http.get{url=url, parameters={UserName='admin',Password='password', Format='xml'}, live=true} trace(S) S = xml.parse{data=S} for i = 1, S.IguanaStatus:childCount('Channel') do local Chan = S.IguanaStatus:child("Channel", i) local QC = CheckChannel(Chan, Param.count, Param.channel) if QC then return QC end end return end
iguanaconfig module (used by the queuemon module):
-- This module does a lazy load of the Iguana Configuration file - it only loads the file once iguanaconfig={} -- relative path (from working directory) to the config file -- you can substitute with the *absolute* path if you have problems local CONFIG_FILE = 'IguanaConfigurationRepo/IguanaConfiguration.xml' -- We open the configuration file once at compile time local F = io.open(CONFIG_FILE, 'r') local C = F:read('*a') F:close() -- best practice to close (open filehandle can prevent Iguana updating config file on Win machines) function iguanaconfig.config(A) return xml.parse{data=C} end
The iguanaconfig module just loads the IguanaConfiguration.xml file and returns it as a XML document. It’s extremely useful for all sorts of things.
In this case we use it to pull back the port number that the Iguana instance is listening on.
This module uses the web monitoring URL to pull back the XML summary and parses it to find the queue counts for the channel. In this case we are only selecting one channel to check the queue count but there is no reason we could not check all the channels or even parse a group of channels and only check the queue counts on that channel group.
If you would like to see this script extended in that manner please contact support at support@interfaceware.com.