Problem using $HOSTNAME$ in a custom object macro

Support forum for Nagios Core, Nagios Plugins, NCPA, NRPE, NSCA, NDOUtils and more. Engage with the community of users including those using the open source solutions.
Locked
jv.goff
Posts: 2
Joined: Fri Mar 31, 2017 2:19 am

Problem using $HOSTNAME$ in a custom object macro

Post by jv.goff »

hello,
New to Nagios, sorry if this is a known issue, my searching so far didn't yield an answer on it.

I have a requirement to make an older version of Nagios (3.5.1) talk to Prometheus via check_prometheus_metric.sh (found on github). Eventually I had the need to pass an instance (host) into the Prometheus query, and I tried to derive that from $HOSTNAME$ like so:

Code: Select all

define command {
    command_name check_prometheus
    command_line $USER32$/check_prometheus_metric.sh -H '$_SERVICEPROMETHEUS_SERVER$:$_SERVICEPROMETHEUS_PORT$' -q '$ARG1$' -w '$ARG2$' -c '$ARG3$' -n '$ARG4$' -m '$ARG5$'
}

define service {
  use                               prometheus-service-template
  hostgroup_name            hbase
  service_description        HBase JVM GC Avg Time msec
  _promql                        HBase_GcTimeMillis{instance=~"$HOSTNAME$"}/HBase_GcCount{instance=~"$HOSTNAME$"}
  check_command           check_prometheus!$_SERVICEPROMQL$!200!500!hbase_gc_time_ms_avg!gt
}

That is to say, I wanted the $HOSTNAME$ to be substituted within the $_SERVICEPROMQL custom object macro, but instead the $HOSTNAME$ is passed to check_prometheus_metric.sh as-is. Tried a few variations such as using another custom object var+macro just for the $HOSTNAME$ part and even removing the _promql step, i.e.

Code: Select all

  check_command           check_prometheus!HBase_GcTimeMillis{instance=~"$HOSTNAME$"}/HBase_GcCount{instance=~"$HOSTNAME$"}!200!500!hbase_gc_time_ms_avg!gt
but the result is the same, $HOSTNAME$ ends up being passed literally to check_prometheus_metric.sh

Is this an unsupported use of $HOSTNAME$ ?

thanks.
-jeff
User avatar
mcapra
Posts: 3739
Joined: Thu May 05, 2016 3:54 pm

Re: Problem using $HOSTNAME$ in a custom object macro

Post by mcapra »

I haven't been able to replicate this so far using check_dummy. Both of these resolve the macros just fine on my Core 3.4.3 machine:

Code: Select all

check_command                   check_dummy!0!'hello $HOSTNAME$'
check_command                   check_dummy!0!"hello $HOSTNAME$"

So this certainly looks like a supported use of $HOSTNAME$. Can you share a copy of check_prometheus_metric.sh? As well as any errors produced when your check_command passes the "$HOSTNAME$" literal.
Former Nagios employee
https://www.mcapra.com/
jv.goff
Posts: 2
Joined: Fri Mar 31, 2017 2:19 am

Re: Problem using $HOSTNAME$ in a custom object macro

Post by jv.goff »

hi mcapra

Thanks for your comments. I also find that the hostname will be correctly substituted when it's put into the check_command, but not when it is within a custom object variable and then the resulting object macro. Below are some more detailed reproduction steps.

regards
-jeff

The following test script, named test_macro.sh

Code: Select all

#!/bin/bash

function _log {
  echo "`date`:$$:$@" >> /tmp/test_macro.log
}

while getopts 'q:z:' OPT "$@"; do
  case ${OPT} in
    q)        PROMETHEUS_QUERY="$OPTARG" ;;
    z)        TESTNUM="$OPTARG" ;;
  esac
done

_log "$TESTNUM query: [$PROMETHEUS_QUERY]"

together with these definitions:

Code: Select all

define hostgroup {
  hostgroup_name    test-macro
  alias             test
  members           dev1

}

define command {
    command_name test_macro
    command_line $USER32$/test_macro.sh -q '$ARG1$' -z '$ARG2$'
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test1
  _promql               HBase_GcTimeMillis{instance=~\"'$HOSTNAME$''\\'..*\"}/HBase_GcCount
  check_command         test_macro!$_SERVICEPROMQL$!test1
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test2
  _i                    instance=~\"'$HOSTNAME$''\\'..*\"
  _promql               HBase_GcTimeMillis{$_SERVICEI$}/HBase_GcCount{$_SERVICEI$}
  check_command         test_macro!$_SERVICEPROMQL$!test2
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test3
  _i                    instance=~\"'$HOSTNAME$''\\'..*\"
  check_command         test_macro!$_SERVICEI$!test3
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test4
  _i                    $HOSTNAME$
  check_command         test_macro!$_SERVICEI$!test4
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test5
  _i                    qwertyuiop
  check_command         test_macro!$_SERVICEI$!test5
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test6
  check_command         test_macro!"blahblahblah $HOSTNAME$ blahblah"!test6
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test7
  check_command         test_macro!$HOSTNAME$!test7
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test8
  check_command         test_macro!HBase_GcTimeMillis{instance=~"$HOSTNAME$"}/HBase_GcCount!test8
}

define service {
  use                   prometheus-service-template
  hostgroup_name        test-macro
  service_description   test9
  check_command         test_macro!HBase_GcTimeMillis{instance=~\"'$HOSTNAME$''\\'..*\"}/HBase_GcCount{instance=~\"'$HOSTNAME$''\\'..*\"}!test9
}

yields the following results

Code: Select all

Sat Apr  1 02:38:22 PDT 2017:12093:test1 query: [HBase_GcTimeMillis{instance=~\"$\..*\"}/HBase_GcCount]
Sat Apr  1 02:38:28 PDT 2017:14563:test2 query: [HBase_GcTimeMillis{$_SERVICEI$}/HBase_GcCount{$_SERVICEI$}]
Sat Apr  1 02:38:34 PDT 2017:15374:test3 query: [instance=~\"$\..*\"]
Sat Apr  1 02:38:42 PDT 2017:15756:test4 query: [$HOSTNAME$]
Sat Apr  1 02:38:47 PDT 2017:16286:test5 query: [qwertyuiop]
Sat Apr  1 02:38:54 PDT 2017:17065:test6 query: ["blahblahblah dev1 blahblah"]
Sat Apr  1 02:38:46 PDT 2017:16019:test7 query: [dev1]
Sat Apr  1 02:38:23 PDT 2017:12181:test8 query: [HBase_GcTimeMillis{instance=~"dev1"}/HBase_GcCount]
test1 - HOSTNAME$ literal removed, nothing inserted. Note that all the escaping of quotes and period etc. is required for the promql query to be handled successfully by the prometheus server

test2 - not sure if Nagios allows macro within macro, it doesn't work and $_SERVICEI$ remains as literal

test3 - similar to test1

test4 - attempt to put only $HOSTNAME$ into a custom object var, remains literal all the way to the script.

test5 - sanity check that custom object var macro is actually working - OK

test6 - similar to your test result, works fine when the $HOSTNAME$ is in the check_command - OK

test7 - same as test 6 - OK

test8 - similar to test 7 and 6 - OK

test9 - does not run, I think the escaped quotes etc. cause it to have a problem.
User avatar
mcapra
Posts: 3739
Joined: Thu May 05, 2016 3:54 pm

Re: Problem using $HOSTNAME$ in a custom object macro

Post by mcapra »

Ah, your assessment is correct that you cannot use macros to create other macros; In Nagios Core 3, they will always be parsed literally. I did this to test it:

Code: Select all

#resource.cfg
$USER10$=foo
$USER11$=$USER10$bar
In which case, when using $USER11$ in a check_command, it uses the $USER10$bar literal. The same applies to any and all system macros. The macros defined in resource.cfg are not recursively parsed. The same goes for Nagios Core 4.

You're welcome to raise an issue on GitHub if you think recursively parsed macros would be a neat feature:
https://github.com/NagiosEnterprises/nagioscore
Former Nagios employee
https://www.mcapra.com/
Locked