[![Build](https://img.shields.io/github/workflow/status/tg44/mqtt-prometheus-message-exporter/ci)](https://github.com/tg44/mqtt-prometheus-message-exporter/actions/workflows/build-and-publish.yaml) [![DockerImage](https://img.shields.io/badge/docker-latest-brightgreen?style=flat-square)](https://github.com/tg44/mqtt-prometheus-message-exporter/pkgs/container/mqtt-prometheus-message-exporter) [![Docker Hub](https://img.shields.io/badge/docker_hub-latest-brightgreen?style=flat-square)](https://hub.docker.com/r/tg44/mqtt-prometheus-message-exporter) # MQTT Prometheus Message Exporter It's a small service which will convert mqtt messages to prometheus metrics. ## How it works: For getting mqtt messages we need to subscribe to topics, and also to parse and convert the messages to metrics we need some "pattern" syntax. #### Path generation For any given pattern the app will figure out which topic its need to subscribe. After the subscribes it will try to parse messages as jsons. If the given result is a single number that is our "measure". If the given result is a json-object, we flatten that object. At each message we will get a list of "path" + value. For example the topic is `my/thermostat`, and the json message is: ```json { "num": 10, "inner": { "num": 5, "arr": [1, 2, 3], "str": "test", "bool": false, "null": null }, "so": { "deep": { "really": { "really": 8 } } } } ``` We will end up with these paths: ``` "my/thermostat/num" -> 10, "my/thermostat/inner/num" -> 5, "my/thermostat/inner/bool" -> 0, "my/thermostat/so/deep/really/really" -> 8 ``` The app will parse: - json numbers, as is - json booleans to 0/1 - json strings to 0/1 if they follows https://yaml.org/type/bool.html (+online/offline) - json objects (as flattened) The app will drop: - json null-s - json strings which can't be converted to bools - json arrays #### Pattern to prometheus metric The paths can be matched and converted to prometheus metrics with three operators: - `[[prefix]]` will use the matching segment in the metric name - `[[prefixes]]` should be only in tail position and it will use all the remaining segments in the metric name - `[[any]]` will match to any segment and "drops" it - `<