MQTT Monitoring

The MQTT subagent (mqtt.nsm) enables NetXMS agents to subscribe to MQTT broker topics and collect data from published messages. It supports three collection methods: simple topic-to-metric mapping, structured data extraction from JSON/XML/text payloads, and event generation from topic messages.

Loading the Subagent

Add the following line to the agent configuration file (nxagentd.conf):

SubAgent = mqtt.nsm

The subagent requires the libmosquitto library to be installed on the system.

Broker Configuration

Each MQTT broker connection is defined in a [MQTT/Brokers/<name>] section of the agent configuration file, where <name> is an arbitrary identifier for the broker.

Table 1. Broker configuration parameters
Parameter Type Default Description

Hostname

String

127.0.0.1

MQTT broker hostname or IP address

Port

Integer

1883

MQTT broker port

Login

String

Username for authentication (leave empty for anonymous access)

Password

String

Password for authentication (plain text only; the subagent does not support passwords obfuscated with nxencpasswd)

Example configuration with two brokers:

SubAgent = mqtt.nsm

[MQTT/Brokers/LocalBroker]
Hostname = 127.0.0.1
Port = 1883

[MQTT/Brokers/RemoteBroker]
Hostname = mqtt.example.com
Port = 1883
Login = netxms
Password = your_password

The agent creates a unique MQTT client ID for each broker connection in the format nxagentd/<uuid>. If the connection to a broker fails, the agent retries every 60 seconds.

Global Settings

Table 2. Global MQTT subagent settings
Parameter Type Default Description

EnableTopicAutoRegistration

Boolean

true

When enabled, the agent automatically subscribes to new topics when they are first requested via MQTT.TopicData(*). When disabled, only topics explicitly configured in the agent configuration are available.

Example:

[MQTT]
EnableTopicAutoRegistration = true

Data Collection Methods

The MQTT subagent provides three methods for collecting data from MQTT topics: simple metrics, structured data extractors, and event generation.

Simple Metrics

Simple metrics map an MQTT topic directly to a named agent metric. The metric returns the last message payload received on the topic as a string.

Configure metrics in the [MQTT/Brokers/<name>/Metrics] section:

[MQTT/Brokers/Sensor/Metrics]
RoomTemperature = sensors/room1/temperature
RoomHumidity = sensors/room1/humidity
OutdoorTemp = weather/outdoor/temp

Each entry maps a metric name (left side) to an MQTT topic pattern (right side). The metric name becomes a directly queryable agent metric.

MQTT wildcard patterns are supported:

  • ` matches a single topic level (e.g., `sensors//temperature matches sensors/room1/temperature and sensors/room2/temperature)

  • matches any number of topic levels (e.g., sensors/ matches all topics under sensors/)

Generic Topic Access

The MQTT.TopicData(*) metric provides direct access to any topic’s last value without pre-configuring a named metric.

Table 3. MQTT.TopicData metric
Format Description

MQTT.TopicData(topic)

Returns last value from the specified topic on the first configured broker

MQTT.TopicData(broker:topic)

Returns last value from the specified topic on the named broker

Examples:

  • MQTT.TopicData(sensors/room1/temperature) — gets temperature from the default broker

  • MQTT.TopicData(RemoteBroker:weather/outdoor/temp) — gets temperature from the broker named RemoteBroker

If EnableTopicAutoRegistration is enabled, the agent automatically subscribes to the requested topic unless a configured topic pattern is equal to it as a string (compared case-insensitively). A wildcard subscription does not satisfy the check: with sensors/+/temperature configured, requesting MQTT.TopicData(sensors/room1/temperature) creates a duplicate subscription for the exact topic. The first request after auto-registration returns an error (no data yet); subsequent requests return the latest value.

Auto-registered topics are attached to the first configured broker unless the broker:topic form is used to name a specific broker. They are not persisted in the agent configuration and are lost on agent restart.

Structured Data Extractors

When MQTT messages contain structured data (JSON, XML, or formatted text), extractors parse the payload and expose individual fields as separate metrics and lists.

Configure extractors in the [MQTT/Brokers/<name>/Extractors/<extractor-name>] section:

[MQTT/Brokers/Sensor/Extractors/WeatherData]
Topic = weather/station1/data
ForcePlainTextParser = false
Description = Weather station data

[MQTT/Brokers/Sensor/Extractors/WeatherData/Metrics]
Temperature = .temperature
Temperature.description = Current temperature in Celsius
Temperature.dataType = int32
Humidity = .humidity
Humidity.description = Current relative humidity
Humidity.dataType = int32
WindSpeed = .wind.speed
WindSpeed.description = Wind speed in m/s
WindSpeed.dataType = float

[MQTT/Brokers/Sensor/Extractors/WeatherData/Lists]
Alerts = .alerts
Alerts.description = Active weather alerts
Table 4. Extractor configuration parameters
Parameter Type Default Description

Topic

String

required

MQTT topic pattern to subscribe to

ForcePlainTextParser

Boolean

false

When set to true, always parse the message payload as plain text using regex, even if it looks like JSON or XML

Description

String

Description for the generic ExtractorName(*) metric and list only. Named metrics need their own MetricName.description sub-entry. When no description is given, the generated metric or list description defaults to MQTT topic <topic>.

Metric and List Definitions

Each metric entry in the Metrics sub-section maps a metric name to a query expression. The query syntax depends on the detected data format:

Table 5. Query syntax by data format
Format Detection Query Syntax

JSON

Payload starts with { or [

jq expressions (e.g., .field, .nested.field, .[0].name)

XML

Payload starts with <

XPath expressions (e.g., /root/element/text(), /root/element/@attribute)

Plain text

Default, or when ForcePlainTextParser = true

PCRE regular expressions with capture groups (first capture group is returned)

JSON extraction requires an agent built with the libjq library. Agents built without libjq cannot evaluate jq expressions.

Each metric definition supports optional sub-entries:

  • MetricName.description — description text for the metric

  • MetricName.dataType — data type hint: int32, uint32, int64, uint64, string, float, counter32, counter64, null (int and uint are accepted as legacy aliases). Default is string; unrecognized values silently fall back to string.

List definitions in the Lists sub-section use the same query syntax. For JSON, a query pointing to an array returns each element as a list item. For XML, an XPath returning a node set returns each node’s text as a list item.

Accessing Extractor Data

Extractors register two types of agent metrics:

Named metrics

Each metric defined in the Metrics section is registered as a standalone agent metric with the specified name (e.g., Temperature, Humidity).

Generic metric

An ExtractorName(*) metric allows arbitrary queries at runtime. For example, WeatherData(.pressure) extracts the pressure field from the JSON payload even though it was not pre-configured.

Named lists

Each list defined in the Lists section is registered as an agent list.

Generic list

An ExtractorName(*) list allows arbitrary list queries at runtime.

JSON Extraction Example

Given the following MQTT message on topic weather/station1/data:

{
  "temperature": 22.5,
  "humidity": 65,
  "wind": {
    "speed": 3.2,
    "direction": "NW"
  },
  "alerts": ["frost warning", "high UV"]
}

The extractor configuration above would produce:

  • Temperature → 22.5

  • Humidity → 65

  • WindSpeed → 3.2

  • WeatherData(.wind.direction) → NW (via generic metric)

  • Alerts list → frost warning, high UV

XML Extraction Example

[MQTT/Brokers/Sensor/Extractors/DeviceStatus]
Topic = devices/+/status
ForcePlainTextParser = false

[MQTT/Brokers/Sensor/Extractors/DeviceStatus/Metrics]
CPUTemp = /status/cpu/temperature/text()
CPUTemp.dataType = float
FanSpeed = /status/fan/@rpm
FanSpeed.dataType = int32

Given an XML payload:

<status>
  <cpu><temperature>45.2</temperature></cpu>
  <fan rpm="2400"/>
</status>

Results: CPUTemp → 45.2, FanSpeed → 2400.

Plain Text Extraction Example

[MQTT/Brokers/Sensor/Extractors/SensorReading]
Topic = sensors/raw/output
ForcePlainTextParser = true

[MQTT/Brokers/Sensor/Extractors/SensorReading/Metrics]
Value = READING:\s+(\d+\.?\d*)
Value.dataType = float
Unit = UNIT:\s+(\w+)

Given a plain text payload:

READING: 42.7
UNIT: celsius
STATUS: OK

Results: Value → 42.7, Unit → celsius.

Event Generation

Topics configured in the Events section trigger NetXMS events when messages are received, instead of storing values for metric collection.

[MQTT/Brokers/Sensor/Events]
MqttAlert = alerts/#
MqttDeviceStatus = devices/+/status-change

Each entry maps an event name (left side) to an MQTT topic pattern (right side). When a message matching the topic pattern is received, the agent posts a NetXMS event with the specified name and the following named parameters:

  • topic — the actual MQTT topic the message was received on

  • message — the message payload

The event must be pre-defined in the NetXMS event configuration.

Using MQTT as a DCI Data Origin

In addition to using the MQTT subagent for agent-side collection, NetXMS server supports MQTT as a DCI data origin. When creating a DCI, select "MQTT" as the origin. The DCI metric name specifies the MQTT topic.

The server does not connect to the MQTT broker itself. Instead, it resolves the node’s MQTT proxy (by default, the agent on the management node) and queries the MQTT.TopicData(topic) metric from that agent. Therefore, the proxy agent must have mqtt.nsm loaded and the broker configured for collection to work.

See Data Origins for details on configuring DCI data origins.

Provided Table

The subagent provides one table metric:

Table 6. MQTT.Brokers table columns
Column Type Description

GUID

String

Unique broker identifier

NAME

String

Broker name from configuration

HOSTNAME

String

Broker hostname

PORT

Integer

Broker port

LOGIN

String

Authentication username

IS_LOCAL

String

Whether the broker is defined in the local agent configuration (in practice always 1)

TOPICS

Integer

Number of subscribed topics

IS_CONNECTED

Integer

1 if currently connected to broker, 0 otherwise

Complete Configuration Example

SubAgent = mqtt.nsm

[MQTT]
EnableTopicAutoRegistration = false

# IoT sensor broker
[MQTT/Brokers/IoTBroker]
Hostname = iot-mqtt.example.com
Port = 1883
Login = collector
Password = collector_password

# Simple metrics - direct topic-to-metric mapping
[MQTT/Brokers/IoTBroker/Metrics]
ServerRoomTemp = building/floor3/serverroom/temperature
ServerRoomHumidity = building/floor3/serverroom/humidity
UPSBattery = ups/main/battery-level

# Structured data extraction from JSON payloads
[MQTT/Brokers/IoTBroker/Extractors/EnvironmentSensor]
Topic = building/floor3/serverroom/environment
Description = Server room environment sensor data

[MQTT/Brokers/IoTBroker/Extractors/EnvironmentSensor/Metrics]
EnvTemperature = .temperature
EnvTemperature.description = Temperature in Celsius
EnvTemperature.dataType = float
EnvHumidity = .humidity
EnvHumidity.description = Relative humidity percentage
EnvHumidity.dataType = int32
EnvCO2 = .co2_ppm
EnvCO2.description = CO2 concentration in ppm
EnvCO2.dataType = int32

# Event generation for alerts
[MQTT/Brokers/IoTBroker/Events]
IoTAlarm = building/+/+/alarm
DeviceOffline = devices/+/offline

Troubleshooting

Enable debug logging for the MQTT subagent by adding the following to the agent configuration:

DebugTags = mqtt:7,data.extractor:8

The mqtt tag covers broker connections and message handling; extractor parse and query diagnostics are written under the data.extractor tag.

Debug levels for the mqtt tag:

  • Level 2: Library version and initialization status

  • Level 3: Broker connections and disconnections, libmosquitto non-debug messages, and the topic registration summary

  • Level 4: Topic subscriptions, subscription confirmations, and connection retries

  • Level 6: Individual message reception (can be very verbose)

  • Level 7: libmosquitto debug-level messages

Common issues:

Connection failures

Verify the broker hostname and port. Check that the MQTT broker is running and accessible from the agent host. If authentication is required, ensure the login and password are correct.

No data returned

If EnableTopicAutoRegistration is disabled, ensure the topic is explicitly configured. After auto-registration, the first request returns an error — data becomes available after the first message is received.

Structured data parsing errors

Verify that the payload format matches the expected type (JSON, XML, or text). Use ForcePlainTextParser = true if the payload contains markup-like characters but should be parsed as plain text.