DX Unified Infrastructure Management

  • 1.  Simple Alarm Trigger Script

    Posted Mar 08, 2019 10:29 AM

    Bit f help required with a very simple trigger script.  I want to trigger a new alarm if I don't receive 3 alarms with the same text .......... i.e new arm if only 2 or more than 3

     

    Got this so far:

     

     

    print("testing script")

    local hostname = "TestHostname"

    local al=alarm.list("hostname",hostname)

    if al ~= nill then

    local count=0

    for i=1,#al do
    if (string.find (al[i].message,"XXXXXXX - Standby Response = in standby")) then
    count = count + 1
    else
    --printf("%02d %s %s %s %s",i,al[i].nimid,al[i].hostname,al[i].severity,al[i].message)
    end
    end

    if count ~= 3 then
    --print("multple matches have been found")
    --print (count)
    nimbus.alarm(4,"Alert Text","*********","30.2.111",hostname)
    end



  • 2.  Re: Simple Alarm Trigger Script

    Posted Mar 08, 2019 10:54 AM

    Couple things:

     

    alarm.list can take a more complex "where" clause:

     

    alarm1=alarm.list("where","robot = '" .. robot .. "' and supp_key = '" .. supp .. "'")

     

    It's poorly documented even for UIM but worth playing with as it can simplify your code.

     

    You can get the alarm that triggered this script to run with:

    local al = alarm.get ()

     

    Not sure with your logic if that matters since you might have an explicit set of criteria on the profile that makes the content of the triggering alarm irrelevant.

     

    When thinking about these sorts of scripts you need to think about what happens over time. When this script is triggered initially there will be no alarms matching which is fine and it satisfies the "count ~= 3" clause and so creates an alarm. When the second alarm comes in that also satisfies the "count ~= 3" clause and so creates an alarm - should make count=2 for the current alarm. What happens when the third one comes in, assuming that the triggering alarm is the alarm you are  counting? Nothing in your script matches that so the alarm will persist. Perhaps you need to close the alarm you are creating?

     

    The nimbus.alarm call is pretty inadequate. 

     

    I use these two functions to generate alarms - this is based on some code that has been floating around the community for a long time:

     

    -- Function to generates a nimid
    --
    function unique_id()
    local key, base

    key = ""
    base="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    --math.randomseed(os.time())
    math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )
    math.random();math.random()

    key = mid(base,math.random(1,26),1) .. mid(base,math.random(1,26),1) .. sprintf("%08d", math.random(1,100000000)) .. "-" .. sprintf("%05d",math.random(1,100000))
    return key
    end

    -----------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------
    -- rawalarm (source,severity,subsystem,message ]]]])
    -- returns 0 - ok, rest error
    ---
    function rawalarm (source,severity,subsystem,message,suppkey,domain,origin,robot,probe,visible,user_tag_1,user_tag_2, nimid)
    local hub_info, robot_info, msg, udata, t, rc

    -- expect following parameters
    if type(severity) ~= "number" then return 1 end
    if type(message) ~= "string" then return 1 end
    if type(subsystem) ~= "string" then return 1 end
    if type(source) ~= "string" then return 1 end

    -- set default values for optional parameters.
    if type(domain) ~= "string" then
    hub_info = nimbus.request ("hub", "get_info")
    domain = hub_info["domain"]
    origin = hub_info["hubname"]
    end
    if type(origin) ~= "string" then
    if hub_info == nul then
    hub_info = nimbus.request ("hub", "get_info")
    end
    origin = hub_info["hubname"]
    end
    if type(robot) ~= "string" then
    robot_info = nimbus.request ("controller", "get_info")
    robot = robot_info["robotname"]
    end
    if type(probe) ~= "string" then probe="lua-probe" end
    if type(suppkey) ~= "string" then suppkey="lua-suppkey" end
    if type(visible) ~= "number" then visible = 1 end

    msg = pds.create ()
    if ( nimid == nil ) then
    nimid = unique_id()
    end

    -- Create message header
    pds.putString (msg,"nimid",nimid)
    pds.putInt (msg,"nimts",timestamp.now() )
    pds.putString (msg,"subject","alarm")
    pds.putInt (msg,"pri",1)
    pds.putString (msg,"source",source)
    pds.putString (msg,"origin",origin)
    pds.putString (msg,"domain",domain)
    pds.putString (msg,"robot",robot)
    pds.putString (msg,"prid",probe)
    pds.putString (msg,"suppression","y+000000000#" .. suppkey)
    pds.putString (msg,"supp_key",suppkey)
    if type(user_tag_1) == "string" then pds.putString (msg,"user_tag_1", user_tag_1) end
    if type(user_tag_2) == "string" then pds.putString (msg,"user_tag_2", user_tag_2) end

    -- Add raw alarm data
    udata = pds.create()
    pds.putInt (udata,"level",severity)
    pds.putString (udata,"subsys",subsystem)
    pds.putString (udata,"message",message)
    pds.putString (udata,"visible",visible)

    pds.putPDS (msg,"udata",udata)

    pds.putInt (msg,"hop",0)
    pds.putString (msg,"hop0", origin)

    -- Post the message to the hub-spooler
    t,rc = nimbus.request ("spooler","hubpost",msg)

    pds.delete (udata)
    pds.delete (msg)
    return rc,nimid
    end

     

     

    And finally, Lua is a little twitchy about some things - like iterating over a table - so instead of using "for" with an index use pairs()

     

    for key, alarm in pairs(al) do

     

    end

     

    And the # operator is also implementation dependant. UIM seems to generate this number based on the largest sequential integer index.

     

    So if you have a[1]="x", a[2]="x", a[3]="x" then #a = 3 

     

    if you then do a[2] = nil what is #a? There are actually two valid answers, 1 and 2. I've not tried this in a long time but my recollection is that UIM returns #a = 1.