Multiple Service Check implementation

Hi beloved community !

As in Icinga statusdata is deprecated, and we rely on this to check multiple Services (check_multi),
I had to come up with a new way to that.
But I am not sure, what I have done is really a good idea. (but it works)

As I would like to avoid a rewrite, I would like to know what I wrote is considered OK, or is it a bad idea,
particularly passing a function from Service to a Checkcommand.

Thank you for your response : ) (I hope i am not offtopic with this.)
These are the results:

object CheckCommand "multi_check" {
    import "plugin-check-command"
    command = {{
        var arrCommand        = [PluginDir + "/check_dummy" ]
        var strHostFilter     = macro("$service.vars.hostfilter$")
        var strServiceFilter  = macro("$service.vars.servicefilter$")
        var dictStatus        =  {}
        functFilterfunction   = macro("$service.vars.filterfunction$")
        var strReturnstring   = "\n"
        var intReturncode     = 0
        for (var objService  in (get_objects(Service))){
            if (match(strHostFilter,objService.host.name) && match(strServiceFilter,objService.name)){
                strReturnstring+=objService.host.name +" --> "+objService.last_check_result.output + "\n"
                if ( objService.last_check_result.state == 0   ){
                   dictStatus["OK"]["Count"] +=1
                   dictStatus["OK"][objService.host.name][objService.name] = 1
                }else if(  objService.last_check_result.state == 1 ){
                   dictStatus["WARNING"]["Count"] +=1
                   dictStatus["WARNING"][objService.host.name][objService.name] = 1
                }else if ( objService.last_check_result.state == 2 ){
                   dictStatus["ERROR"]["Count"] +=1
                   dictStatus["ERROR"][objService.host.name][objService.name] = 1
                }else if(  objService.last_check_result.state == 3 ){
                   dictStatus["UNKNOWN"]["Count"] +=1
                   dictStatus["UNKNOWN"][objService.host.name][objService.name] =1
               }

            }
        }
        intReturncode=functFilterfunction(dictStatus)
        arrCommand+=[intReturncode,strReturnstring + dictStatus.to_string() + intReturncode ]
        return arrCommand
    }}
}
 apply Service "multi_service" {
    import "generic-service"
    check_command = "multi_check"
    vars.servicefilter = "*pudding*"
    vars.hostfilter    = "*pizza*" 

    vars.filterfunction =  {{
      function(status){
          if (status["OK"]["Count"]   <  4 ){
              return  1
          }
      }
    }}
    assign where host.vars.os == "ilovecookies"
}

2 Likes

Hi,

from a first peek, the code looks good. Especially the function object as callback is really nice. I had to read the code in full to get an idea what it is doing.

Some thoughts, but I am not sure how to really make them work:

  • dummy as CheckCommand is executed in-memory since 2.10 or so. If you rewrite the code to use that CheckCommand just prints dummy_state and dummy_text based on the returned function values.
  • Hide the filterfunction in a template, or at least add comments in the code. I bet your colleagues will have a hard time understanding it :wink:
  • dictStatus is a nested dictionary. It may be the case that the upper key is not initialized, causing the secondary key access to fail then. This loudly breaks then and is hard to see. You might want to add sanity checks (if not initialized, then either do it now or log something) to be prepared. But that’s only my defensive programming mood, I don’t like too see things crash and burn :slight_smile:

Cheers,
Michael

2 Likes

Hi @gyuszi, did you evolve your script according to Michael thoughts ?
I’m quite interested in this concept to create an host status from other service on another hosts…

Hi @Alesck ,
not really, not something I have tested (I had no time…) :sweat_smile: , just some stupid comments .

But I have here in some draft to expand the script with:

if(dictStatus["OK"]["Count"] == null){
 dictStatus["OK"]["Count"]=0
}

and so on …

But if you have any question ,I will try to answer ^ _ ^

1 Like

This is a totally amazing approach to replace check_multi with icinga on-board features. It worked right away for me, and it was even easily understandable for me as a relatively young icinga 2 user.

Thank you very much! This should be an example in the advanced docs.

Greetings
Marc

1 Like