-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor metric extraction from MQTT
This commit allows to extract the metric name from the topic path. Now it can be configured if all metrics are in a object in a certain topic or if every topic contains exactly one metric. However, currently these modes can not be mixed. This should solve !26 TODO: * Update documentation * Add unit tests
- Loading branch information
Christoph Petrausch
committed
Nov 8, 2020
1 parent
b3442ec
commit be4af9f
Showing
13 changed files
with
330 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Hack Scenarios | ||
|
||
Required is a MQTT client. I use this: https://github.com/shirou/mqttcli | ||
|
||
## Shelly (Metric Per Topic) | ||
The scenario is the feature requested by issue https://github.com/hikhvar/mqtt2prometheus/issues/26. | ||
|
||
To start the scenario run: | ||
```bash | ||
docker-compose --env-file shelly.env up | ||
``` | ||
|
||
To publish a message run: | ||
```bash | ||
mqttcli pub --host localhost -p 1883 -t shellies/living-room/sensor/temperature '15' | ||
``` | ||
|
||
## DHT22 (Object Per Topic) | ||
The default scenario | ||
|
||
To start the scenario run: | ||
```bash | ||
docker-compose --env-file dht22.env up | ||
``` | ||
|
||
To publish a message run: | ||
```bash | ||
mqttcli pub --host localhost -p 1883 -t v1/devices/me/test -m '{"temperature":"12", "humidity":21}' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CONFIG=dht22.yaml |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CONFIG=shelly.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
mqtt: | ||
server: tcp://mosquitto:1883 | ||
topic_path: shellies/+/sensor/+ | ||
device_id_regex: "shellies/(?P<deviceid>.*)/sensor" | ||
metric_per_topic_config: | ||
metric_name_regex: "shellies/(?P<deviceid>.*)/sensor/(?P<metricname>.*)" | ||
qos: 0 | ||
cache: | ||
timeout: 24h | ||
metrics: | ||
- prom_name: temperature | ||
# The name of the metric in a MQTT JSON message | ||
mqtt_name: temperature | ||
# The prometheus help text for this metric | ||
help: shelly temperature reading | ||
# The prometheus type for this metric. Valid values are: "gauge" and "counter" | ||
type: gauge | ||
# A map of string to string for constant labels. This labels will be attached to every prometheus metric | ||
const_labels: | ||
sensor_type: shelly | ||
# The name of the metric in prometheus |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package metrics | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"github.com/hikhvar/mqtt2prometheus/pkg/config" | ||
gojsonq "github.com/thedevsaddam/gojsonq/v2" | ||
) | ||
|
||
type Extractor func(topic string, payload []byte, deviceID string) (MetricCollection, error) | ||
|
||
func NewJSONObjectExtractor(p Parser) Extractor { | ||
return func(topic string, payload []byte, deviceID string) (MetricCollection, error) { | ||
var mc MetricCollection | ||
parsed := gojsonq.New().FromString(string(payload)) | ||
|
||
for path := range p.config() { | ||
rawValue := parsed.Find(path) | ||
parsed.Reset() | ||
if rawValue == nil { | ||
continue | ||
} | ||
m, err := p.parseMetric(path, deviceID, rawValue) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse valid metric value: %w", err) | ||
} | ||
m.Topic = topic | ||
mc = append(mc, m) | ||
} | ||
return mc, nil | ||
} | ||
} | ||
|
||
func NewMetricPerTopicExtractor(p Parser, metricName *config.Regexp) Extractor { | ||
return func(topic string, payload []byte, deviceID string) (MetricCollection, error) { | ||
mName := metricName.GroupValue(topic, config.MetricNameRegexGroup) | ||
if mName == "" { | ||
return nil, fmt.Errorf("failed to find valid metric in topic path") | ||
} | ||
m, err := p.parseMetric(mName, deviceID, string(payload)) | ||
if err != nil { | ||
if errors.Is(err, metricNotConfigured) { | ||
return nil, nil | ||
} | ||
return nil, fmt.Errorf("failed to parse metric: %w", err) | ||
} | ||
m.Topic = topic | ||
return MetricCollection{m}, nil | ||
} | ||
} |
Oops, something went wrong.