How do I monitor a tcp port?

  • Version used (icinga2 --version)
    Compiler: GNU 11.2.1
    Build host: runner-hh8q3bz2-project-575-concurrent-0
    OpenSSL version: OpenSSL 1.0.2k-fips 26 Jan 2017
  • Operating System and version
    Red Hat Linux 7.9
  • Enabled features (icinga2 feature list)
    Disabled features: compatlog debuglog elasticsearch gelf icingadb influxdb influxdb2 journald livestatus opentsdb perfdata syslog
    Enabled features: api checker command graphite ido-mysql mainlog notification opsgenie

I’m trying to just monitor whether or not a TCP port is responding. Here’s the config I’m trying to use:

object Service "webproxy_ports" {
    check_command = "tcp" 
    host = "webproxyprodapp01.mycompany.com"
    check_interval = 1m
    vars.tcp_ports = [3128]
    display_name = "Webproxy ports 3128"

    apply Service {
        for (port in vars.tcp_ports) {
            check_command = "tcp" 
            -H "x.x.x.x" 
            -p "$port"
        }
    }
}

But it keeps throwing errors that either the port or the host (-p and -H) are wrong. I’ve been through the docs for days and I can’t figure out where I’ve gone wrong.

you probably want something like this:

object Host "host with webproxy" {
  ...
  address = "x.x.x.x"
  vars.tcp_ports = [ 3128 ]
}

apply Service "TCP Webproxy " for (port in host.vars.tcp_ports) {
  ...
  check_command = "tcp"
   display_name = "Webproxy ports 3128"
   vars.tcp_port = port
}

Apparently, “check_command” cannot be empty on my hosts? I got this error when trying to restart icinga2:

Error: Validation failed for object 'webprxprdapp01' of type 'Host'; Attribute 'check_command': Attribute must not be empty.

Indeed, I kinda implied that.
Some basic Icinga2 stuff, you have two kind of “Monitoring Objects”, Hosts and Services. The main difference is, that a Service is always attached to a Host.
Therefore you have to have at least one Host. Most of the time you’ve got more since you will map existing Machines (Hardware or VM) to Host objects in Icinga2.

Services then can be attached to one Host. In my example, through some config magic address (a Host attribute) is used as an address for the tcp CheckCommand, that’s why I did not configure it in the Service apply rule.

I think I got it:

object Host "webprxprdapp01" {
    address = "x.x.x.x"
    vars.tcp_ports = [3128]
    check_command = "hostalive"
}

apply Service "TCP Webproxy" for (port in host.vars.tcp_ports) {
    check_command = "tcp"
    display_name = "Webproxy tcp ports 3128"
    vars.tcp_port = port
}

Now you should a Host " webprxprdapp01" and a Service “TCP Webproxy3128” in your webinterface :slight_smile:

1 Like

Thanks lorenz!

Hello,
The use of a static display name “Webproxy tcp ports 3128” leads me to think you will only ever check one port on that host, i.e., port 3128.
The complexity of the solution above (the for construct “for (port in host.vars.tcp_ports)”) is made to handle a list of ports.
Perhaps you should consider simplifying the configuration if you need to check only one port.
My two cents,
Jean

Simplified like this?

I haven’t verified but this should work:

object Host "webprxprdapp01" {
    address = "x.x.x.x"
    check_command = "hostalive"
}

apply Service "TCP Webproxy" {
    check_command = "tcp"
    display_name = "Webproxy tcp port 3128"
    vars.tcp_port = 3128
    assign where host.name == "webprxprdapp01"
}

It can of course be further simplified if you don’t need to “apply” the service to multiple hosts, and wish to define it on just that single host…

BTW, there is also a port check in our Linuxfabrik Monitoring Plugins collection: monitoring-plugins/check-plugins/network-port-tcp at main · Linuxfabrik/monitoring-plugins · GitHub