Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/jpmens/check-mqtt

A Nagios/Icinga plugin for testing an MQTT broker
https://github.com/jpmens/check-mqtt

Last synced: 9 days ago
JSON representation

A Nagios/Icinga plugin for testing an MQTT broker

Awesome Lists containing this project

README

        

# 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 ] [-P ] [-u ]
[-p ] [-m ] [-e ]
[--sleep ] [-a ] [-C ]
[-k ] [-n] [-t ] [-s ] [-r]
[-l ] [-j ] [-v ]
[-o ] [-w ] [-c ] [-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 , --host
mqtt host to connect to (default: 'localhost')
-P , --port
network port to connect to (default: 1883)
-u , --username
MQTT username (default: None)
-p , --password
MQTT password (default: None)
-m , --max-wait
maximum time to wait for the check (default: 4
seconds)
-e , --keepalive
maximum period in seconds allowed between
communications with the broker (default: 60 seconds)
--sleep main loop sleep period in seconds (default: 0.1
seconds)
-a , --cafile
cafile (default: None)
-C , --certfile
certfile (default: None)
-k , --keyfile
keyfile (default: None)
-n, --insecure suppress TLS verification of server hostname
-t , --topic
topic to use for the active check (default:
'nagios/test')
-s , --subscription
topic to use for the passive check (default: 'None')
-r, --readonly just read the value of the topic
-l , --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
if given, payload is interpreted as JSON string and
value is extracted using (default: 'None')
-v , --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 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 , --warning
Exit with WARNING status if is true (default:
'None'). can be any Python expression, use
within expression for current payload value.
-c , --critical
Exit with CRITICAL status if is true (default:
'None'). can be any Python expression, use
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.


hostname, port, username, password

used to connect to a MQTT broker

cafile certfile keyfile insecure

optional used for an encrypted TLS connection, for details see mosquitto.conf - Certificate based SSL/TLS Support.

max_wait

is the time (integer) we're willing to wait for a SUB to the topic we PUBlish on. If we don't receive the MQTT PUB within this many seconds we exit with _CRITICAL_


keepalive

maximum period in seconds (integer) allowed between communications with the broker. If no other messages are being exchanged, this controls the rate at which the client will send ping messages to the broker

sleep

period in seconds (float) to sleep in main loop - may reduce cpu load if a lot of processes (>100) are running.

topic

topic where the payload will be published when we have received the subscribed message.

payload


payload to publish on topic.

subscription

topic to use for the passive check - read only. If subscription is not given it will be set to topic

readonly

just read on subscription, do not publish any payload on topic

jsonpath

a JSONPath expression refering to a JSON structure (for JSONPath syntax see JSONPath expressions)

value, operator


value to compare against received payload. The comparison is done using one of the listed (see help above) operators. The returned status is OK if the comparison is true, otherwise it will return CRITICAL. If -w (--warning) or -c (--critical) argument is used, value and operator will be ignored.

warning, critical

a warning and/or critical expression. Use the word payload within your formular to refer to the read payload value.
If both are given (warning and critical) the critical expression overrule the warning. <exp> can be any valid pyhton expression inclusive build-in and standard library functions e. g. conversion like str(), float()...
Using one of them a possible --value and/or --operator argument will be ignored.

short

if set it will use a short string layout for returned message

## 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
}
```

[nagios]: http://nagios.org
[icinga]: http://icinga.org
[mqtt]: http://mqtt.org