Sign inSign up

thijsputman/sysmon-mqtt

By thijsputman

Updated about 1 month ago
Archived

Simple system monitoring over MQTT

Image
0

8.7K

thijsputman/sysmon-mqtt repository overview

sysmon-mqtt — Simple system monitoring over MQTT

The 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.

Metrics

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 memory
  • uptime — uptime in seconds
  • status – 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
    • For wireless adapaters, signal-strength is also reported (detection based on adapter name matching the wl*-pattern; requires iw-binary)
  • rtt – average round-trip (ie, ping) times in ms to one or more hosts

The metrics are provided as a JSON-object in the sysmon/[device-name]/state topic.

Heartbeat

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.

Home Assistant discovery

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.

Broker

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)...

Usage

The main configuration is passed to the container via its environment:

  • MQTT_BROKER — hostname or IP address of the MQTT-broker
  • DEVICE_NAMEhuman-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-ids
  • NETWORK_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)
    • If the adapter's name matches wl*, signal-strength is also reported
  • RTT_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 topic
  • SYSMON_HA_TOPIC (default: homeassistant) — base for the Home Assistant discovery topic
  • SYSMON_INTERVAL (default: 30) — set the interval (in seconds) at which metrics are reported
  • SYSMON_RTT_COUNT (default 4) — number of ping-requests to send per iteration over which to average the round-trip time
  • SYSMON_HA_VERSION (default: 202308) — specify Home Assistant version compatibility (as YYYYMM); based on this some behaviours are modified:

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.yml
version: "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.

Tag summary

Content type

Image

Digest

sha256:f2f02e7f4

Size

7.5 MB

Last updated

5 months ago

docker pull thijsputman/sysmon-mqtt