Awesome
check-mqtt
A Nagios/Icinga plugin for checking connectivity to an MQTT broker. Or with --readonly monitor an mqtt application. Or for checking the status of MQTT clients maintaining the status on an MQTT broker.
This plugin connects to the specified broker and subscribes to a topic. Upon successful subscription, a message is published to said topic, and the plugin expects to receive that payload within max_wait
seconds.
Prerequisite
This module can use jsonpath-rw. To install, use $ pip install jsonpath-rw
Configuration
Configuration can be done via the following command line arguments:
usage: check-mqtt.py [-h] [-d|--debug] [-H <hostname>] [-P <port>] [-u <username>]
[-p <password>] [-m <seconds>] [-e <seconds>]
[--sleep <seconds>] [-a <cafile>] [-C <certfile>]
[-k <keyfile>] [-n] [-t <topic>] [-s <subscription>] [-r]
[-l <payload>] [-j <jsonpath>] [-v <value>]
[-o <operator>] [-w <expr>] [-c <expr>] [-S] [-V]
Nagios/Icinga plugin for checking connectivity or status of MQTT clients on an
MQTT broker.
optional arguments:
-h, --help show this help message and exit
-d, --debug enable MQTT logging
-H <hostname>, --host <hostname>
mqtt host to connect to (default: 'localhost')
-P <port>, --port <port>
network port to connect to (default: 1883)
-u <username>, --username <username>
MQTT username (default: None)
-p <password>, --password <password>
MQTT password (default: None)
-m <seconds>, --max-wait <seconds>
maximum time to wait for the check (default: 4
seconds)
-e <seconds>, --keepalive <seconds>
maximum period in seconds allowed between
communications with the broker (default: 60 seconds)
--sleep <seconds> main loop sleep period in seconds (default: 0.1
seconds)
-a <cafile>, --cafile <cafile>
cafile (default: None)
-C <certfile>, --certfile <certfile>
certfile (default: None)
-k <keyfile>, --keyfile <keyfile>
keyfile (default: None)
-n, --insecure suppress TLS verification of server hostname
-t <topic>, --topic <topic>
topic to use for the active check (default:
'nagios/test')
-s <subscription>, --subscription <subscription>
topic to use for the passive check (default: 'None')
-r, --readonly just read the value of the topic
-l <payload>, --payload <payload>
payload which will be PUBLISHed (default: PiNG). If it
starts with an exclamation mark (!) the output of the
command will be used
-j <jsonpath>, --jsonpath <jsonpath>
if given, payload is interpreted as JSON string and
value is extracted using <jsonpath> (default: 'None')
-v <value>, --value <value>
value to compare against received payload (default:
'PiNG'). If it starts with an exclamation mark (!) the
output of the command will be used
-o <operator>, --operator <operator>
operator to compare received value with value. Choose
from ['eq', 'equal', 'lt', 'lessthan', 'gt',
'greaterthan', 'ct', 'contains'] (default: 'equal').
'eq' compares Strings, the other convert the arguments
to float before compare
-w <expr>, --warning <expr>
Exit with WARNING status if <expr> is true (default:
'None'). <expr> can be any Python expression, use
<payload> within expression for current payload value.
-c <expr>, --critical <expr>
Exit with CRITICAL status if <expr> is true (default:
'None'). <expr> can be any Python expression, use
<payload> within expression for current payload value.
-S, --short use a shorter string on output
-V, --version show program's version number and exit
There are no required arguments, defaults are displayed using --help
. If --warning
and/or --critical
is used then possible given --operator
and --value
arguments are ignored.
Examples
simple
./check-mqtt.py -H localhost -P 1883 -u user -p password -t nagios/test -m 10
OK - message from nagios/test at localhost in 0.00 | response_time=0.10 value=PiNG
Status check
./check-mqtt.py -H localhost -t devices/mydevice/lastevent -v '!expr `date +%s` - 216000' -r -o greaterthan
OK - message from devices/mydevice/lastevent at localhost in 0.05s | response_time=0.05 value=1472626997
Ping Pong check
./check-mqtt.py -H localhost -t nagios/ListenForPing -s nagios/PublishPongTo -l ping -v pong
OK - message from nagios/PublishPongTo at localhost in 0.05s | response_time=0.05 value=pong
Jsonpath check
./check-mqtt.py -H localhost -t devices/mydevice/sensor -v '950' -j '$.BME280.Pressure' -r -o greaterthan
OK - message from devices/mydevice/sensor at localhost in 0.06s | response_time=0.06 value=1005.0
Jsonpath check using range (warning if lower than 4° or higher than 28°, critical if minus or higher than 35°)
./check-mqtt.py -H localhost -t devices/mydevice/sensor -v '950' -j '$.BME280.Temperature' -r --warning 'payload < 4 or payload >28' --critical 'payload < 0 or payload >35'
OK - message from devices/mydevice/sensor at localhost in 0.06s | response_time=0.06 value=20.1
Nagios Configuration
command definition
define command{
command_name check_mqtt
command_line $USER1$/check_mqtt
}
define command{
command_name check_myapplication
command_line $USER1$/check_mqtt -i pong -t mytopic/test/myapplication
}
icinga2 command definition
object CheckCommand "check-mqtt" {
import "plugin-check-command"
command = [ PluginDir + "/check-mqtt.py" ] //constants.conf -> const PluginDir
arguments = {
"-H" = "$mqtt_host$"
"-u" = "$mqtt_user$"
"-p" = "$mqtt_password$"
"-P" = "$mqtt_port$"
"-a" = "$mqtt_cafile$"
"-c" = "$mqtt_certfile$"
"-k" = "$mqtt_keyfile$"
"-t" = "$mqtt_topic$"
"-m" = {
set_if = "$mqtt_max$"
value = "$mqtt_max$"
}
"-l" = "$mqtt_payload$"
"-v" = "$mqtt_value$"
"-o" = "$mqtt_operator$"
"-r" = {
set_if = "$mqtt_readonly$"
description = "Don't write."
}
"-n" = {
set_if = "$mqtt_insecure$"
description = "suppress TLS hostname check"
}
}
}
service definition
define service{
use local-service
host_name localhost
service_description mqtt broker
check_command check_mqtt
notifications_enabled 0
}
define service{
use local-service
host_name localhost
service_description check if myapplication is running
check_command check_myapplication
notifications_enabled 0
}
icinga2 host definition
object Host "wemos1" {
import "generic-host"
check_command = "check-mqtt"
vars.homie = true
vars.lastevent = true
vars.mqtt_host = "localhost"
# vars.mqtt_port = 1883
# vars.mqtt_user = "user"
# vars.mqtt_password = "password"
# vars.mqtt_cafile = "cafile"
# vars.mqtt_certfile = "certfile"
# vars.mqtt_keyfile = "keyfile"
vars.mqtt_prefix = "devices/mydevice"
vars.mqtt_topic = vars.mqtt_prefix + "/$$online"
vars.mqtt_payload = "true"
vars.mqtt_value = "true"
vars.mqtt_operator = "equal"
vars.mqtt_readonly = true
vars.os = "Homie"
vars.sla = "24x7"
}
icinga2 service definition
apply Service "mqtt-health" {
import "generic-service"
check_command = "check-mqtt"
assign where host.vars.mqtt == true
ignore where host.vars.no_health_check == true
}
apply Service "homie-health" {
import "generic-service"
check_command = "check-mqtt"
vars.mqtt_topic = host.vars.mqtt_prefix + "/$$online"
vars.mqtt_payload = "true"
vars.mqtt_value = "true"
vars.mqtt_operator = "equal"
vars.mqtt_readonly = true
assign where host.vars.homie == true
ignore where host.vars.no_health_check == true
}
apply Service "lastevent-health" {
import "generic-service"
check_command = "check-mqtt"
vars.mqtt_topic = host.vars.mqtt_prefix + "/lastevent"
vars.mqtt_payload = "true"
vars.mqtt_value = "!expr `date +%s` - 21600"
vars.mqtt_operator = "greaterthan"
vars.mqtt_readonly = true
assign where host.vars.lastevent == true
ignore where host.vars.no_health_check == true
}