mirror of
https://github.com/hikhvar/mqtt2prometheus.git
synced 2026-02-14 18:09:53 +00:00
Parse more value types
* Parse bools as 0 for false and 1 for true * Allow mapping between string and float values
This commit is contained in:
@@ -11,7 +11,7 @@ mqtt:
|
||||
qos: 0
|
||||
cache:
|
||||
# Timeout. Each received metric will be presented for this time if no update is send via MQTT
|
||||
timeout: 2min
|
||||
timeout: 2m
|
||||
# This is a list of valid metrics. Only metrics listed here will be exported
|
||||
metrics:
|
||||
# The name of the metric in prometheus
|
||||
@@ -46,4 +46,23 @@ metrics:
|
||||
type: gauge
|
||||
# A map of string to string for constant labels. This labels will be attached to every prometheus metric
|
||||
const_labels:
|
||||
sensor_type: dht22
|
||||
sensor_type: dht22
|
||||
- prom_name: state
|
||||
# The name of the metric in a MQTT JSON message
|
||||
mqtt_name: state
|
||||
# The prometheus help text for this metric
|
||||
help: Light state
|
||||
# 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: ikea
|
||||
# When specified, enables mapping between string values to metric values.
|
||||
string_value_mapping:
|
||||
# A map of string to metric value.
|
||||
map:
|
||||
off: 0
|
||||
low: 0
|
||||
# Metric value to use if a match cannot be found in the map above.
|
||||
# If not specified, parsing error will occur.
|
||||
error_value: 1
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"time"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
@@ -40,11 +41,19 @@ type MQTTConfig struct {
|
||||
|
||||
// Metrics Config is a mapping between a metric send on mqtt to a prometheus metric
|
||||
type MetricConfig struct {
|
||||
PrometheusName string `yaml:"prom_name"`
|
||||
MQTTName string `yaml:"mqtt_name"`
|
||||
Help string `yaml:"help"`
|
||||
ValueType string `yaml:"type"`
|
||||
ConstantLabels map[string]string `yaml:"const_labels"`
|
||||
PrometheusName string `yaml:"prom_name"`
|
||||
MQTTName string `yaml:"mqtt_name"`
|
||||
Help string `yaml:"help"`
|
||||
ValueType string `yaml:"type"`
|
||||
ConstantLabels map[string]string `yaml:"const_labels"`
|
||||
StringValueMapping *StringValueMappingConfig `yaml:"string_value_mapping"`
|
||||
}
|
||||
|
||||
// StringValueMappingConfig defines the mapping between from string to float
|
||||
type StringValueMappingConfig struct {
|
||||
// ErrorValue is used when no mapping is found in Map
|
||||
ErrorValue *float64 `yaml:"error_value"`
|
||||
Map map[string]float64 `yaml:"map"`
|
||||
}
|
||||
|
||||
func (mc *MetricConfig) PrometheusDescription() *prometheus.Desc {
|
||||
|
||||
@@ -45,30 +45,55 @@ func (i *Ingest) store(deviceID string, rawMetrics MQTTPayload) error {
|
||||
var mc MetricCollection
|
||||
|
||||
for metricName, value := range rawMetrics {
|
||||
if cfg, found := i.validMetrics[metricName]; found {
|
||||
var floatValue float64
|
||||
var isFloat bool
|
||||
var err error
|
||||
floatValue, isFloat = value.(float64)
|
||||
if !isFloat {
|
||||
stringValue, isString := value.(string)
|
||||
cfg, cfgFound := i.validMetrics[metricName]
|
||||
if !cfgFound {
|
||||
continue
|
||||
}
|
||||
|
||||
if !isString || ! validNumber.MatchString(stringValue) {
|
||||
return fmt.Errorf("got data with unexpectd type: %T ('%s')", value, value)
|
||||
var metricValue float64
|
||||
|
||||
if boolValue, ok := value.(bool); ok {
|
||||
if boolValue {
|
||||
metricValue = 1
|
||||
} else {
|
||||
metricValue = 0
|
||||
}
|
||||
} else if strValue, ok := value.(string); ok {
|
||||
|
||||
// If string value mapping is defined, use that
|
||||
if cfg.StringValueMapping != nil {
|
||||
|
||||
floatValue, ok := cfg.StringValueMapping.Map[strValue]
|
||||
if ok {
|
||||
metricValue = floatValue
|
||||
} else if cfg.StringValueMapping.ErrorValue != nil {
|
||||
metricValue = *cfg.StringValueMapping.ErrorValue
|
||||
} else {
|
||||
return fmt.Errorf("got unexpected string data '%s'", strValue)
|
||||
}
|
||||
|
||||
floatValue, err = strconv.ParseFloat(stringValue, 64)
|
||||
} else {
|
||||
|
||||
// otherwise try to parse float
|
||||
floatValue, err := strconv.ParseFloat(strValue, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("got data with unexpectd type: %T ('%s') and failed to parse to float", value, value)
|
||||
}
|
||||
metricValue = floatValue
|
||||
|
||||
}
|
||||
|
||||
mc = append(mc, Metric{
|
||||
Description: cfg.PrometheusDescription(),
|
||||
Value: floatValue,
|
||||
ValueType: cfg.PrometheusValueType(),
|
||||
})
|
||||
} else if floatValue, ok := value.(float64); ok {
|
||||
metricValue = floatValue
|
||||
} else {
|
||||
return fmt.Errorf("got data with unexpectd type: %T ('%s')", value, value)
|
||||
}
|
||||
|
||||
mc = append(mc, Metric{
|
||||
Description: cfg.PrometheusDescription(),
|
||||
Value: metricValue,
|
||||
ValueType: cfg.PrometheusValueType(),
|
||||
})
|
||||
}
|
||||
i.collector.Observe(deviceID, mc)
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user