Posts by dnsmichi

    That's the way how the job runner fetches the data - it retrieves the full object name and sorts by problem severity. That is "hostname!servicename" and the listing just takes that into account.

    1. severity_stats = []
    2. icinga.service_problems_severity.each do |name, state|
    3. severity_stats.push({ "label" => icinga.formatService(name) })
    4. end

    You could populate your own attribute inside the icinga class in lib/icinga2.rb which returns a slightly different result set. Keep in mind that display_name might not be unique.

    1. getProblemServices()

    populates icinga.service_problems_severity. That one doesn't retrieve display_name yet, that needs to be adopted by yourself.

    Untested diff:

    michi@mbmif ~/coding/icinga/dashing-icinga2 (feature/display_name *) $ git diff

    diff --git a/jobs/icinga2.rb b/jobs/icinga2.rb

    index 48dd130..2db3a70 100644

    --- a/jobs/icinga2.rb

    +++ b/jobs/icinga2.rb

    @@ -51,7 +51,8 @@ SCHEDULER.every '5s', :first_in => 0 do |job|

    severity_stats = []

    icinga.service_problems_severity.each do |name, state|

    #severity_stats.push({ "label" => icinga.formatService(name), "color" => icinga.stateToColor(state.to_int, false)})

    - severity_stats.push({ "label" => icinga.formatService(name) })

    + #severity_stats.push({ "label" => icinga.formatService(name) })

    + severity_stats.push({ "label" => name })


    puts "Severity: " + severity_stats.to_s

    diff --git a/lib/icinga2.rb b/lib/icinga2.rb

    index 5824bba..00f94f3 100644

    --- a/lib/icinga2.rb

    +++ b/lib/icinga2.rb

    @@ -382,7 +382,7 @@ class Icinga2

    @service_problems = {}

    # only fetch the minimal attribute set required for severity calculation

    - all_services_data = getServiceObjects([ "name", "state", "acknowledgement", "downtime_depth", "last_check" ], nil, [ "", "host.state", "host.acknowledgement", "host.downtime_depth", "host.last_check" ])

    + all_services_data = getServiceObjects([ "name", "display_name", "state", "acknowledgement", "downtime_depth", "last_check" ], nil, [ "", "host.display_name", "host.state", "host.acknowledgement", "host.downtime_depth", "host.last_check" ])

    all_services_data.each do |service|

    #puts "Severity for " + service["name"] + ": " + getServiceSeverity(service).to_s

    @@ -406,7 +406,9 @@ class Icinga2



    - name = obj["name"]

    + #name = obj["name"]

    + name = obj["attrs"]["display_name"] + " - " + obj["joins"]["host"]["display_name"]


    @service_problems_severity[name] = obj["attrs"]["state"]

    count += 1

    Custom attributes can be named like you desire. "notification" and "users", "groups" is just a made up example for the example configuration located in conf.d/.

    You don't necessarily need to follow that.

    One thing you should understand is how dictionaries ("hash", "key value store") work and how they can be accessed - via ["key"] and also using the short index operator ".".

    In fact, if your assign where expression is looking for a boolean value, the following happens:

    • host - yep, that object is in my scope (inside notification apply rules)
    • is the "vars" attribute defined?
    • Is there a key called "notification" inside the "vars" dictionary?
    • Yep, there is
    • Now we are here: host.vars.notification. This is a dictionary and has as value (a dictionary)
    • Is there a key called "telegram" defined inside the value of "notification" (which is a nested dictionary)
    • Yep there is.
    • Now we are here: host.vars.notification.telegram
    • Since the existence of a key also returns boolean "true", the assign where expression matches

    Assigning the value works in a similar fashion. You just add some steps.

    • Is there a key called "users" inside the dictionary "telegram"
    • Yes there is
    • Its value is an array of string elements.
    • Perfect, let's just assign that value to our local attribute
    • users = host.vars.notification.telegram.users

    All those language details can be found inside the library and language reference chapters. Some of them are explained in-depth in various documentation chapters, but still not perfect. It is really hard to find the right examples for the numerous possibilities the Icinga 2 DSL provides. Mostly a matter of time though to document "everything".

    Yep :)

    You could rewrite it like this to prefer a service definition and fallback to hosts. Or you split it up into two apply rules.

    Du könntest dir auch einen Check vom Master aus einrichten mittels "tcp" bzw "ssl" CheckCommand, sodass du das historisch mitbekommst ob und wann der Socket nicht verfügbar war.

    Wenn du da etwas findest, können wir das auch gerne in die Troubleshooting Docs mitaufnehmen :)

    Merging check results on-the-fly is a tough topic. Especially if you take multiple cluster instances into account.

    It would also need sort of a merge rule engine which does not exist. Workaround: Use existing service objects and object accessors for calculating runtime stats. I've seen that inside Eduard Güldner's talk at Icinga Camp Berlin this year (check icinga's youtube channel).

    Sounds complicated. I guess you also install apache2, php, perl, python and whatnot to different paths then and not follow the main package paths.

    Either way, you would need to create your own custom packages with different prefixes, be it for Icinga 2 or Grafana.

    Just keep in mind that such custom setups are hard to support when it comes to problems and questions. We as Icinga project only support official packages for that reason.

    I can only speak for Icinga 2's API, I have never used the Director API. Config packages, creates, modifies, deletes are documented very well. Config packages are basically a bundle of configuration files where you can just write configuration into it, as you would put into zones.d or conf.d.

    Before continuing theoretically I'd suggest to fire up a Vagrant box and play with it.