diff --git a/Readme.md b/Readme.md index 259d396..0681601 100644 --- a/Readme.md +++ b/Readme.md @@ -216,6 +216,8 @@ metrics: help: Light state # The prometheus type for this metric. Valid values are: "gauge" and "counter" type: gauge + # according to prometheus exposition format timestamp is not mandatory, we can omit it if the reporting from the sensor is sporadic + omit_timestamp: true # A map of string to string for constant labels. This labels will be attached to every prometheus metric const_labels: sensor_type: ikea diff --git a/pkg/config/config.go b/pkg/config/config.go index 07a27a2..e20f80d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -133,6 +133,7 @@ type MetricConfig struct { SensorNameFilter Regexp `yaml:"sensor_name_filter"` Help string `yaml:"help"` ValueType string `yaml:"type"` + OmitTimestamp bool `yaml:"omit_timestamp"` ConstantLabels map[string]string `yaml:"const_labels"` StringValueMapping *StringValueMappingConfig `yaml:"string_value_mapping"` MQTTValueScale float64 `yaml:"mqtt_value_scale"` diff --git a/pkg/metrics/collector.go b/pkg/metrics/collector.go index 0016839..188957a 100644 --- a/pkg/metrics/collector.go +++ b/pkg/metrics/collector.go @@ -2,11 +2,12 @@ package metrics import ( "fmt" + "time" + "github.com/hikhvar/mqtt2prometheus/pkg/config" gocache "github.com/patrickmn/go-cache" "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" - "time" ) type Collector interface { @@ -77,7 +78,12 @@ func (c *MemoryCachedCollector) Collect(mc chan<- prometheus.Metric) { device, metric.Topic, ) - mc <- prometheus.NewMetricWithTimestamp(metric.IngestTime, m) + + if metric.IngestTime.IsZero() { + mc <- m + } else { + mc <- prometheus.NewMetricWithTimestamp(metric.IngestTime, m) + } } } diff --git a/pkg/metrics/parser.go b/pkg/metrics/parser.go index c08da3b..e1f13a2 100644 --- a/pkg/metrics/parser.go +++ b/pkg/metrics/parser.go @@ -99,10 +99,15 @@ func (p *Parser) parseMetric(metricPath string, deviceID string, value interface metricValue = metricValue * cfg.MQTTValueScale } + var ingestTime time.Time + if !cfg.OmitTimestamp { + ingestTime = now() + } + return Metric{ Description: cfg.PrometheusDescription(), Value: metricValue, ValueType: cfg.PrometheusValueType(), - IngestTime: now(), + IngestTime: ingestTime, }, nil } diff --git a/pkg/metrics/parser_test.go b/pkg/metrics/parser_test.go index 8d6a680..f712eb2 100644 --- a/pkg/metrics/parser_test.go +++ b/pkg/metrics/parser_test.go @@ -26,6 +26,32 @@ func TestParser_parseMetric(t *testing.T) { want Metric wantErr bool }{ + { + name: "value without timestamp", + fields: fields{ + map[string][]config.MetricConfig{ + "temperature": []config.MetricConfig{ + { + PrometheusName: "temperature", + ValueType: "gauge", + OmitTimestamp: true, + }, + }, + }, + }, + args: args{ + metricPath: "temperature", + deviceID: "dht22", + value: 12.6, + }, + want: Metric{ + Description: prometheus.NewDesc("temperature", "", []string{"sensor", "topic"}, nil), + ValueType: prometheus.GaugeValue, + Value: 12.6, + IngestTime: time.Time{}, + Topic: "", + }, + }, { name: "string value", fields: fields{