Generic Prometheus ⟷ MQTT Bridge

Promqtt: Prometheus ⟷ MQTT Bridge

Promqtt makes Prometheus MQTT capable in a truly generic way.

It has no assumptions on message payloads or topic layout.

Installation

Promqtt is best used with Docker, an image is available at shorez/promqtt.

If that is no option, Promqtt can also be installed from source using Go:

$ go install github.com/sh0rez/promqtt@latest

Promqtt accepts very little configuration which is exposed as command line flags:

promqtt <broker> [flags]

Arguments:

  • broker: Any MQTT broker (e.g. myBroker:1883)

Flags:

  • --client-id: The MQTT Client ID to use. Defaults to promqtt@HOSTNAME
  • --listen: The address to bind the HTTP server to. Defaults to :9337

Above list may be incomplete, consult promqtt --help for what your current build supports

Usage

In similar fashion to the blackbox_exporter and snmp_exporter, Promqtt acts as a general purpose relay, meaning you do not configure specific topics, etc. ahead of time.

Instead, these must be provided by Prometheus while scraping. Using clever relabeling it makes Prometheus look like it supported MQTT itself:

Basic

The most basic use-case assumes a sender literally publishes float64 compatible values (any kind of number really) to some MQTT topic:

Topic: diox/06FE2A3/co2
Payload: 42.0

A possible scrape_configs entry for looks like this:

- job_name: diox
  metrics_path: /mqtt # Promqtt serves MQTT metrics under this path
  static_configs:
    - targets:
        - diox/.+/.+ # regular expression matching some MQTT topic
  relabel_configs:
    # copy above address (diox/...) into the "topic" URL parameter
    - source_labels: [__address__]
      target_label: __param_topic
    # and also to the instance label
    - source_labels: [__param_topic]
      target_label: instance
    # make Prometheus scrape Promqtt at ADDRESS
    - target_label: __address__
      replacement: ADDRESS:9337

Considering above MQTT message, this would yield the following series:

# TYPE diox_06FE2A3_co2 gauge
diox_06FE2A3_co2{topic="diox/06FE2A3/co2", instance="diox/.+/.+"} 42.0

Regex

Obviously, not all MQTT devices publish perfect float values to distinct topics. To accompany for that, Promqtt lets you optionally a regular expression using named capture groups to extract parts of messages:

Topic: tele/tv/SENSOR
Payload:

{"Time":"2021-06-27T17:38:56","ENERGY":{"TotalStartTime":"2021-01-16T13:12:08","Total":56.040,"Yesterday":0.923,"Today":0.536,"Period":1,"Power":10,"ApparentPower":32,"ReactivePower":30,"Factor":0.32,"Voltage":233,"Current":0.136}}

We could use the following regular expression, to parse out the Power, Voltage and Current fields (Explanation):

"Power":(?P<_power>[\d.]+).*"Voltage":(?P<_voltage>[\d.]+).*"Current":(?P<_current>[\d.]+)

This gives us the following scrape_configs entry:

- job_name: tasmota
  metrics_path: /mqtt # Promqtt serves MQTT metrics under this path
  static_configs:
    - targets:
        - tele/.+/SENSOR # regular expression matching some MQTT topic
  params:
    regex:
      - '"Power":(?P<_power>[\d.]+).*"Voltage":(?P<_voltage>[\d.]+).*"Current":(?P<_current>[\d.]+)',
  relabel_configs:
    # copy above address (tele/...) into the "topic" URL parameter
    - source_labels: [__address__]
      target_label: __param_topic
    # and also to the instance label
    - source_labels: [__param_topic]
      target_label: instance
    # make Prometheus scrape Promqtt at ADDRESS
    - target_label: __address__
      replacement: ADDRESS:9337

The names of the capture groups (_power, _voltage and _current) are appended to the generated series name, yielding the following:

# TYPE tele_tv_SENSOR_power gauge
tele_tv_SENSOR_power{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR"} 10

# TYPE tele_tv_SENSOR_voltage gauge
tele_tv_SENSOR_voltage{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR"} 233

# TYPE tele_tv_SENSOR_current gauge
tele_tv_SENSOR_current{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR"} 0.136

Series renaming

Above series obviously don't quite comply with the Prometheus naming conventions.

But again, this can be fixed by adding some metric_relabel_configs. Continuing above example:

- job_name: tasmota
  # ...
  metric_relabel_configs:
    # rename series to tasmota_<field> style
    - source_label: [__name__]
      target_label: __name__
      regex: tele.+_SENSOR_(.+)
      replacement: tasmota_$1
    # extract device from topic to its own label
    - source_labels: [topic]
      target_label: dev
      regex: tele/(.+)/.+

Afterwards, we get the following:

# TYPE tele_tv_SENSOR_power gauge
tasmota_power{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR", dev="tv"} 10

# TYPE tele_tv_SENSOR_voltage gauge
tasmota_voltage{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR", dev="tv"} 233

# TYPE tele_tv_SENSOR_current gauge
tasmota_current{topic="tele/tv/SENSOR", instance="tele/.+/SENSOR", dev="tv"} 0.136
Owner
sh0rez
Cargo ship pilot at Grafana Labs. Creator of Tanka
sh0rez
Similar Resources

Simple BLE to MQTT gateway

BLE_to_MQTT_gw Simple BLE to MQTT gateway This app will scan for the Eddystone BLE advertisement packets from my ESP32 BLE sensor, and forward tempera

Dec 29, 2021

Smq - Simple MQTT Broker with golang

Simple MQTT Broker 关于 Golang MQTT Broker, Version 3.1.1, and Compatible for ecli

Jul 7, 2022

Dwarka - API gateway offers REST API to manage various device controlled using MQTT protocol

dwarka API gateway offers REST API to manage various device controlled using 'MQ

Sep 16, 2022

Courier Golang client library provides an opinionated wrapper over paho MQTT library to add features on top of it

Courier Golang Client Library Introduction Courier Golang client library provides an opinionated wrapper over paho MQTT library to add features on top

Nov 19, 2022

Read metrics from a Message Queue in Json format and expose them in a Prometheus compatible format

mq2prom Read metrics from a Message Queue in Json format and expose them in a Prometheus compatible format. Currently only works for MQTT compatible M

Jan 24, 2022

Gmqtt is a flexible, high-performance MQTT broker library that fully implements the MQTT protocol V3.1.1 and V5 in golang

中文文档 Gmqtt News: MQTT V5 is now supported. But due to those new features in v5, there area lots of breaking changes. If you have any migration problem

Jan 5, 2023

Vallox RS-485 MQTT gateway to integrate Vallox RS485 ventilation device to Home Assistant via MQTT.

Vallox RS-485 MQTT gateway to integrate Vallox RS485 ventilation device to Home Assistant via MQTT.

Vallox RS-485 MQTT gateway to integrate Vallox RS485 ventilation device to Home Assistant via MQTT. Implements Home Assistant MQTT discovery but can also be used without Home Assistant.

Dec 26, 2021

Sensirion SCD30 CO2 sensor MQTT gateway with Home Assistant MQTT discovery

Sensirion SCD30 CO2 sensor MQTT gateway for Home Assistant Overview This gateway can be used to publish measurements SCD30 to mqtt. It supports Home A

Oct 10, 2022

Lg-ess-mqtt - MQTT Firmware Extension for 1st generation LG ESS BESS

lg-ess-mqtt This projects is a firmware extension for the 1st generation LG ESS

Oct 19, 2022

Apex-api-bridge - Bridge between apexlegendsapi and ApeStats

apex-api-sync This app updates a mongo instance with the players most recent dat

Feb 17, 2022

Provider-generic-workflows - A generic provider which uses argo workflows to define the backend actions.

provider-generic-workflows provider-generic-workflows is a generic provider which uses argo workflows for managing the external resource. This will re

Jan 1, 2022

Go-generic-unboxing - A quick ready to ship demo for go generic using the official example

Go generic This repo contain basic demo for installing and running go1.18beta1 v

Feb 1, 2022

Generic - Golang generic example

泛型 场景 假设需要写一个列表总数计算的函数,根据不同数据类型,我们可能分别要写 SumInts(data []int),SumFloats(data []fl

Jan 27, 2022

This library implements the pub/sub pattern in a generic way. It uses Go's generic types to declare the type of the event.

observer This library implements the pub/sub pattern in a generic way. It uses Go's generic types to declare the type of the event. Usage go get githu

Nov 16, 2022

Prometheus Common Data Exporter can parse JSON, XML, yaml or other format data from various sources (such as HTTP response message, local file, TCP response message and UDP response message) into Prometheus metric data.

Prometheus Common Data Exporter can parse JSON, XML, yaml or other format data from various sources (such as HTTP response message, local file, TCP response message and UDP response message) into Prometheus metric data.

Prometheus Common Data Exporter Prometheus Common Data Exporter 用于将多种来源(如http响应报文、本地文件、TCP响应报文、UDP响应报文)的Json、xml、yaml或其它格式的数据,解析为Prometheus metric数据。

May 18, 2022

Export Prometheus metrics from journald events using Prometheus Go client library

journald parser and Prometheus exporter Export Prometheus metrics from journald events using Prometheus Go client library. For demonstration purposes,

Jan 3, 2022

Prometheus-elasticache-sd - Prometheus Service Discovery for AWS ElastiCache

Prometheus AWS ElastiCache Service Discovery ElastiCache SD allows retrieving sc

Dec 15, 2022

Hermes is a tiny MQTT compatible broker written in Go.

Hermes Hermes is a tiny MQTT compatible broker written in Go. The goals of the project are as below Easy to compile, and run Tiny footprint Extensible

Sep 9, 2022

IP Camera Alarm Server to MQTT

IP Camera Alarm Server Universal Alarm Server for all your IP cameras in one place! Integrates well with Home Assistant, Node-Red, etc. Runs great on

Dec 8, 2022
Comments
  • /mqtt target doesn't start

    /mqtt target doesn't start

    ./promqtt 10.8.0.2:1883 
    2021/12/17 10:10:39 listening at :9337
    2021/12/17 10:10:39 subscribed to '#'
    

    mosquitto_pub -h localhost -t diox/06FE2A3/co2 -m "42.0"

    mosquitto_sub -t '#' --host 10.8.0.2
    42.0
    
    
    wget http://localhost:9337/mqtt
    --2021-12-17 10:13:25--  http://localhost:9337/mqtt
    Resolving localhost (localhost)... ::1, 127.0.0.1
    Connecting to localhost (localhost)|::1|:9337... connected.
    HTTP request sent, awaiting response... 400 Bad Request
    2021-12-17 10:13:25 ERROR 400: Bad Request.
    
    

    /mqtt target doesn't start

    why? How to check it?

  • JSON mode?

    JSON mode?

    JSON can already parsed using the regex support, but only if the actors emit JSON in a strict way (same ordering, etc).

    We could possibly add a native JSON mode that turns all fields into series

  • Series closing

    Series closing

    Currently, when an actor stops sending messages to MQTT, promqtt will export the last received value forever.

    How shall we deal with this?

    1. Not. Leave as is. This appears to be what the Pushgateway does as well.
    2. Add a timeout (e.g. 5m, etc).
    3. Use special topics to "close" series, which makes promqtt remove them from its output. This could play well with LWT (Last will & testament), so that devices that disconnect from the broker are automatically removed.

    I personally like (3), because it could leverage the quite unique MQTT property of LWT.

    Thoughts? @RichiH?

  • Project name

    Project name

    As per last dev summit, we are trying to come up with new terminology for this use case. "push exporter" is least bad atm.

    https://docs.google.com/document/d/11LC3wJcVk00l8w5P3oLQ-m3Y37iom6INAMEu2ZAGIIE/edit?ts=60d93074#

Sensirion SCD30 CO2 sensor MQTT gateway with Home Assistant MQTT discovery

Sensirion SCD30 CO2 sensor MQTT gateway for Home Assistant Overview This gateway can be used to publish measurements SCD30 to mqtt. It supports Home A

Oct 10, 2022
Lg-ess-mqtt - MQTT Firmware Extension for 1st generation LG ESS BESS

lg-ess-mqtt This projects is a firmware extension for the 1st generation LG ESS

Oct 19, 2022
Hermes is a tiny MQTT compatible broker written in Go.

Hermes Hermes is a tiny MQTT compatible broker written in Go. The goals of the project are as below Easy to compile, and run Tiny footprint Extensible

Sep 9, 2022
IP Camera Alarm Server to MQTT

IP Camera Alarm Server Universal Alarm Server for all your IP cameras in one place! Integrates well with Home Assistant, Node-Red, etc. Runs great on

Dec 8, 2022
handle multiple mqtt server/cluster based on paho client

pakhshi Introduction Consider you have an array of brokers but you want to publish and subscribe on all of them at the same time. Why you may need thi

Nov 9, 2022
MQTTtimer is based mqtt protocol sync timer

MQTTTimer is based mqtt protocol sync timer. You can used ntp sync time protocol in IoT without ntp server. used mqtt protocol sync time is tcp connne

Oct 27, 2021
An embeddable lightweight Go/Golang MQTT broker(server) for IoT.
An embeddable lightweight Go/Golang MQTT broker(server) for IoT.

Snple MQTT 简体中文 Note: The API of this library is still unstable and has not been sufficiently tested, please do not use it in production environments.

Sep 12, 2022
mqtt-rewriter is a tool that can forward data from a topic to another topic.

mqtt-rewriter Background mqtt-rewriter is a tool that can forward data from a topic to another topic. Install Todo... Usage Currently only supports tw

Feb 18, 2022
A robust and easy to use MQTT rule engine
A robust and easy to use MQTT rule engine

⚙ MQTT COMMANDER A robust and easy to use MQTT rule engine Configure your MQTT Rules via easy to use YML Files Supports JSON encoded MQTT Messages Sup

Sep 21, 2022
Send IR command through MQTT

Introduction This program can be used in two different modes: Either it is waiting for an id button on a MQTT topic and execute the corresponding LIRC

Nov 9, 2022