Icinga 2 DSL Feature: Namespaces coming in v2.10

Under the hood, Icinga 2 uses many constants and reserved keywords, e.g. “Critical” or “Zone” which are respected by the config parser and compiler. This sometimes leads to errors when users accidentally override such things, or re-define their own global constants. v2.10 introduces namespaces for this purpose, and ensures that such accidents won’t happen anymore.
 

What exactly is a namespace?

Think of a defined “room” for variables, functions, etc. which can be defined similar to constants. They are isolated from other namespaces and must be loaded by the user/developer. Namespaces need a defined name – we prefer to use a capitalized string, e.g. “MyNamespace”. This helps to immediately qualify this as customization when reading the configuration.
Icinga 2 v2.10 uses namespaces which are registered and loaded by default. In order to test this, open the debug console on a test VM which has the snapshot packages installed. Fetch the keys in global namespace “globals” first.
(more…)

Icinga 2 v2.8.0 released

We are happy to bring you Icinga 2 v2.8.0 with lots of cool features this time 🙂 Advanced certificate signing in distributed environments, Elasticsearch feature, and much more – read on.
Thanks to all contributorsMichael, KonstantinMike, Sebastian, Claudio, Irina, Roland, Ryan, Lee, Jean-Louis, Rudy, Robin, Dirk, Yannick, you are doing an awesome job! 🙂
Many thanks to VW for sponsoring the Elasticsearch and CA-Proxy & On-Demand Signing features in v2.8.0!
(more…)

Monthly Snap March: Icinga Camp, Partners, Trainings, Icingabeat, approved Puppet module

March was all about our lovely community. We’ve had Icinga Camp Berlin and San Francisco, and also joined FLOSSUK. You’ll also recognize that our Puppet module for Icinga 2 was officially approved by Puppet. Blerim released icingabeat and blogged about it at the Elastic blog. And many more things happened …
We’ve also thought about 1st of April, but hey – we have so many great things to share and work on, we’ll skip it for 2017 😉
(more…)

Analyse Icinga 2 problems using the console & API

Lately we’ve been investigating on a problem with the check scheduler. This resulted in check results being late and wasn’t easy to tackle – whether it’ll be the check scheduler, cluster messages or anything else. We’ve been analysing customer partner environments quite in deep and learned a lot ourselves which we like to share with you here.
One thing you can normally do is to grep the debug log and analyse the problem in deep. It is also possible to query the Icinga 2 API fetching interesting object attributes such as “last_check”, “next_check” or even “last_check_result”.
But what if you want to calculate things for better analysis e.g. fetch the number of all services in a HA cluster node where the check results are late? (more…)

Icinga 2: Host state calculation from all services

There is a variety of questions answered in the community support channels. Sometimes we just hack away fancy solutions directly inside the Icinga 2 DSL. Some of these examples are collected inside the documentation, others are posted on the community channels. Or they are just provided in hands-on workshops at customers waiting for sharing their stories to the world 🙂
This time there was the this question over at monitoring-portal.org – a host object collects a bunch of passive services and should calculate its overall state and output from the (worst) state of all referenced services.
Sounds easy. You could go for business process check returning the calculated value. Or you stick with many of the Icinga 2 configuration language features and put them altogether.

For a small test environment, I’ve generated 5 services using the random check (replace that with your real world scenario).
 

for (j in range(5)) {
  object Service "host-servicestatus-" + j {
    check_command = "random"
    check_interval = 30s
    retry_interval = 15s
    host_name = "host-servicestatus"
  }
}

The host object called “host-servicestatus” just uses the “dummy” check command provided by the ITL. This check command expects two custom attributes: “dummy_state” and “dummy_text”.
Now for the fun part – implement two lambda functions for these custom attributes using the available methods.

  vars.dummy_state = {{ ... }}
  vars.dummy_text = {{ ... }}

We want to calculate the worst state for all services on this specific host. Therefore we’ll use a temporary variable to save and update the worst state.

    var worst_state = 0

At first glance we want to selectively iterate over all service objects using the object accessor method “get_objects” with “Service” type. Then we’ll compare the service “host_name” attribute to the local scope (our host and its name). We’ll just skip all services not matching.

    for (s in get_objects(Service)) {
      if (s.host_name != host.name) {
        continue; //skip all services not referencing this host object
      }

The local to the loop variable “s” provides us with access to the all attributes for the current service object. Check whether its state is greater than 0 (not OK) and greater than the previously collected worst state. If so, store it in the local variable “worst_state”.

      if (s.state > 0 && s.state > worst_state) {
        worst_state = s.state
      }
    }

After the loop is finished, just return the “worst_state” variable for this function.

    return worst_state

In terms of generating an additional output text with all service names and their state, we’re using the same loop and conditional checking as above. Except we are using a temporary variable as an array of strings like this:

    var output = []

Inside the loop we’ll add the current service name and its state as string element to the “output” array.

      output.add(s.name + ": " + s.state)

Once the loop is finished, join the array elements with the separator “, ” concatenate the final output string and return it.

    return "Service summary: " + output.join(", ")

We could also concatenate the string as is but then we would need to think about the last loop run not adding the “,” character. The array join method just simplifies that step.
icinga2_host_servicestatus_web2The final solution works like a charm 🙂 If you say – hey I am not a coder – it helps to know Javascript, or Python or something similar of course. After all it is a pretty neat solution for helping a community member 🙂
 

object Host "host-servicestatus" {
  check_command = "dummy"
  vars.dummy_state = {{
    var worst_state = 0
    for (s in get_objects(Service)) {
      if (s.host_name != host.name) {
        continue; //skip all services not referencing this host object
      }
      if (s.state > 0 && s.state > worst_state) {
        worst_state = s.state
      }
    }
    return worst_state
  }}
  vars.dummy_text = {{
    var output = []
    for (s in get_objects(Service)) {
      if (s.host_name != host.name) {
        continue; //skip all services not referencing this host object
      }
      output.add(s.name + ": " + s.state)
    }
    return "Service summary: " + output.join(", ")
  }}
}