5 Replies Latest reply on Sep 15, 2017 3:31 PM by Geoff Smith

    Reusable alert templates

    Geoff Smith

      I've been working on some alert templates, and I think I like these.  There are a few others floating around, but these have everything I can think of.  They're re-usable for each kind of alert, so the Node Critical one can be used for all Critical Node Alert E-Mails (the "I want to alert on: Node" thing in the alert Wizard).  I've tried very hard to make it look good in the Android Outlook ap as well as in a normal Outlook window.

       

      A TON of it is stolen wholesale from other stuff on Thwack, or heavily modified.  I can't remember where it all came from, so you might see something familiar in the raw code!

       

      They use a few Custom Properties.

      For the alert there are 3 custom properties.  AlertingMessage, AlertClearMessage, and SpecialAlertMessage.

       

      AlertingMessage is what goes in the triggered alert, Clear gets used in the clear template, and the SpecialAlertMessage is for extra items.  I use it for Traps or Top 10 processes kind of alerts or if I want to add something special into an alert.

       

      Top 10 processes Special Message that reformats the Notes into a "nicer" table

      The top 10 processes running at the time of this poll are listed below:  <table border="1"><tr><td>${SQL: SELECT REPLACE(REPLACE ( '${N=Alerting;M=Notes} ', char(9) , '</td><td>' ),char(10),'</td></tr><tr><td>') }</tr></table>  (if there is no process list the system was too busy to provide one in the allotted time)<br>

       

      The ridiculous trap version that puts traps in nice tables.  I feel like my SQL is crummy when I look at this...

      Trap(s) in last 5 minutes: ------------------------------------------------------ <table border=1> ${SQL: select replace(replace(replace(replace(replace((SELECT    'Replace1 Received at: ',   max(FORMAT ( t.datetime, 'HH:mm:ss', 'en-US')) as datetime,   ' For: ${N=SwisEntity;M=Caption} Replace2',   (Max(Case when v.trapindex=0 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line0,    (Max(Case when v.trapindex=1 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line1,    (Max(Case when v.trapindex=2 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line2,    (Max(Case when v.trapindex=3 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line3,    (Max(Case when v.trapindex=4 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line4,    (Max(Case when v.trapindex=5 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line5,    (Max(Case when v.trapindex=6 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line6,    (Max(Case when v.trapindex=7 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line7,    (Max(Case when v.trapindex=8 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line8,    (Max(Case when v.trapindex=9 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line9,    (Max(Case when v.trapindex=10 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line10,    (Max(Case when v.trapindex=11 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line11,    (Max(Case when v.trapindex=12 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line12,    (Max(Case when v.trapindex=13 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line13,    (Max(Case when v.trapindex=14 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line14,    (Max(Case when v.trapindex=15 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line15,    (Max(Case when v.trapindex=16 then 'Replace4' + v.OIDName + 'Replace3' + v.OIDValue else '' end)) as line16,   'Replace5' FROM    [dbo].[TrapVarbinds] v  join   [dbo].[Traps] t  on    (t.trapid=v.trapid and t.nodeid=${NodeID} and DateTime between DATEADD(MI,-6,getdate()) and GETDATE() and t.Tag='SW-Critical')  group by v.trapid, t.DateTime Order By t.DateTime FOR XML PATH('')), 'Replace1', '<tr><th colspan=2 align=left>'), 'Replace2', '</th></tr>'), 'Replace3' , '</td><td>'), 'Replace4', '<tr valign=top><td>'), 'Replace5', '</td></tr>')} </table>

       

      In the Nodes I use a ProductionStatus (that could be Production or Test or whatever - I show it in the alert, but I only use it in the alert triggers) and the NodeAlertEmail property (just displays, but I use it to determine to whom to send the alert)

       

      Group, Application, and Component all use similar items to the node, and I'll leave that as an exercise for the reader

       

      Like I said, I try to include everything, so here's an example from the Component Warning alert, with private stuff blocked out

       

      Top section has the AlertMessage in the header (the Message displayed when this alert is triggered thing). the Alert section has the AlertinMessage Custom property.  For some reason you can't use the same variable in the AlertMessage and AlertingMessage or you'll get a circular refrence error (so, that seems to be a bug in Orion).  I included all likely Component info, so the Event Log info is in there if it's an event log alert, response time if it's an HTML test, and so on.  As expected, CPU and memory, response time.  I've included info on all drives, and on all monitored applications, with a last boot time and a time of alert at the bottom.

      Server information section has all your normal info about the server that shouldn't really be involved in an alert.

      Last section is other info: Node group membership, Application Group membership, alert frequency, and then when it alerted.

       

      Any suggestions as to something else to add to these guys, or better ways of doing some of it, I'm all ears.

       

      Have a great day!