Simple system monitoring over MQTT
8.7K
sysmon-mqtt — Simple system monitoring over MQTTThe sysmon-mqtt-script is used on a variety of single board computers (mainly
Raspberry Pis) to provide basic performance metrics to Home Assistant.
These used to be retrieved via SNMP. That works fine, but felt a bit archaic and somewhat overkill for the purpose: Not all metrics were directly addressable via SNMP (e.g., retrieving CPU temperature required defining a custom OID and calling a shell-script) and most other metrics required further processing in Home Assistant to be usable.
Hence, sysmon-mqtt: A simple shell-script to capture a handful of common
metrics and push them over MQTT to Home Assistant.
For more details, see the GitHub-repository.
Currently, the following metrics are provided:
cpu_load — the 1-minute load as a percentage of maximum nominal load (e.g.
for a quad-core system, 100% represents a 1-minute load of 4.0)cpu_temp — CPU temperature in degrees Celsius (read from
/sys/class/thermal/thermal_zone0/temp – omitted if not available)mem_used — memory in use (excluding buffers and caches) as a percentage of
total available memoryuptime — uptime in secondsstatus – overall status of the system (systemd-only;
as reported by systemctl is-system-running)bandwidth — average bandwidth (receive and transmit) for individual network
adapters in kbps during the monitoring interval
wl*-pattern; requires iw-binary)rtt – average round-trip (ie, ping) times in ms to one or more hostsThe metrics are provided as a JSON-object in the sysmon/[device-name]/state
topic.
A persistent sysmon/[device-name]/connected topic is provided as an indication
of whether the script is active. Its value works as a "heartbeat": It contains
the Unix timestamp of the most recent reporting iteration, -1 while the script
is initialising, and 0 if the script was gracefully shutdown.
In case a stale timestamp is present, it may be assumed the script (or the machine its running on) has crashed / dropped from the network. Stale is best defined as three times the reporting interval. For the default configuration that would amount to 90 seconds.
When the script starts, a heartbeat of -1 is reported until the script's
second iteration; this is done because some of the metrics (bandwidth, rtt
and apt) are – due to various technical reasons – only reported from the
second iteration onwards...
Additionally, the version of the running sysmon-mqtt-script is provided in
sysmon/[device-name]/version.
By default, the script publishes
Home Assistant discovery
messages to the homeassistant/sensors/sysmon topic.
These messages are retained. Any new instance of the script started with an
already present device-name will re-use the existing sensor-entity unique_id
values (and thus "adopt" the previous instance's sensors in Home Assistant).
This behaviour is intended to allow "fixed" sensor-entities in Home Assistant
(which can easily be customised via the GUI).
To unregister (a set of) metrics from Home Assistant, simply remove their
topics/messages from the homeassistant/sensors/sysmon tree with (for example)
mosquitto_pub.
The script assumes the MQTT broker to be Mosquitto (and uses this assumption to validate the broker configuration).
Furthermore, the script relies on
MQTT-persistence to persist
unique_id values for Home Assistant sensor-entities in between restarts (of
either the script or the MQTT broker). Ensure the broker has persistence (for at
least QoS level-1 messages) enabled. Otherwise, the unique ids used in Home
Assistant will be dynamic (causing duplicate entities to be created after each
restart)...
The main configuration is passed to the container via its environment:
MQTT_BROKER — hostname or IP address of the MQTT-brokerDEVICE_NAME — human-friendly name of the device being monitored (e.g.,
"My Raspberry Pi"); a low-fidelity version (my_raspberry_pi) is
automatically generated and used to construct MQTT-topics and Home Assistant
entity-idsNETWORK_ADAPTERS (optional) — one or more network adapters to monitor as a
space-delimited list (e.g., 'eth0 wlan0'; mind the quotes when specifying
more than one adapter)
wl*, signal-strength is also reportedRTT_HOSTS (optional) — one or more hosts to which to monitor the round-trip
time as a space-delimited list (e.g., '8.8.8.8 google.com'; mind the quotes
when specifying more than one hostname)The following optional environment variables can be used to further influence the script's behaviour:
SYSMON_HA_DISCOVER (default: true) — set to false to disable publishing
to Home Assistant discovery topicSYSMON_HA_TOPIC (default: homeassistant) — base for the Home Assistant
discovery topicSYSMON_INTERVAL (default: 30) — set the interval (in seconds) at which
metrics are reportedSYSMON_RTT_COUNT (default 4) — number of ping-requests to send per
iteration over which to average the round-trip timeSYSMON_HA_VERSION (default: 202308) — specify Home Assistant version
compatibility (as YYYYMM); based on this some behaviours are modified:
>= 202308 do not prepend device name to sensor name
(home-assistant/core#95159)For bandwidth monitoring to work, you'll need to mount the host's /sys-sysfs
into the container (as is done in the below
📄 docker-compose.yml). Alternatively, you can use
network_mode: host – if you need WiFi signal-strength measurements, use the
latter approach (iw relies on the physical network adapter being accessible;
mounting /sys doesn't suffice).
The /sys-approach is preferred as it's more flexible (i.e., it can be used to
gather additional information such as the device model) and offers better
security: The container's network remains isolated; instead it gains read-only
access to /sys with Docker's AppArmor policies applied to prevent access to
sensitive information.
These AppArmor policies currently prevent reporting the device model from
inside the container though 😵 — see
moby#434199 for details. Until that
issue is resolved, you'll need to run a privileged container (easiest, if
slightly too broad, is via privileged: true) which is not worth the risk
just to have the device model reported.
If you don't care about bandwidth monitoring (and/or the device model), the
/sys-mount can be removed.
docker-compose.ymlversion: "2.3"
services:
sysmon-mqtt:
image: thijsputman/sysmon-mqtt:latest
restart: unless-stopped
# Mount host's /sys-sysfs (read-only) into the container
volumes:
- /sys:/sys:ro
environment:
- MQTT_BROKER=
- DEVICE_NAME=
# Optional: Specify network adapters for bandwidth monitoring and/or
# hostnames for round-trip times
- NETWORK_ADAPTERS=
- RTT_HOSTS=
# Optional: Drop permissions to the provided UID/GID-combination
- PUID=
- PGID=
The optional environment variables provided above can of course be passed into the Docker-container to further modify its behaviour.
Content type
Image
Digest
sha256:f2f02e7f4…
Size
7.5 MB
Last updated
5 months ago
docker pull thijsputman/sysmon-mqtt