From b6c7e863d3d7cf0d202145fa42097861d8bf30c2 Mon Sep 17 00:00:00 2001 From: Simon Westphahl Date: Thu, 14 Jun 2018 08:34:44 +0200 Subject: [PATCH] Allow mappings to match on metric types Co-authored-by: Simon Westphahl Signed-off-by: Simon Westphahl --- exporter.go | 6 +++++- mapper.go | 27 +++++++++++++++++---------- metric_type.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 metric_type.go diff --git a/exporter.go b/exporter.go index 1d56614..1de131e 100644 --- a/exporter.go +++ b/exporter.go @@ -182,6 +182,7 @@ type Event interface { MetricName() string Value() float64 Labels() map[string]string + MetricType() metricType } type CounterEvent struct { @@ -193,6 +194,7 @@ type CounterEvent struct { func (c *CounterEvent) MetricName() string { return c.metricName } func (c *CounterEvent) Value() float64 { return c.value } func (c *CounterEvent) Labels() map[string]string { return c.labels } +func (c *CounterEvent) MetricType() metricType { return metricTypeCounter } type GaugeEvent struct { metricName string @@ -204,6 +206,7 @@ type GaugeEvent struct { func (g *GaugeEvent) MetricName() string { return g.metricName } func (g *GaugeEvent) Value() float64 { return g.value } func (c *GaugeEvent) Labels() map[string]string { return c.labels } +func (c *GaugeEvent) MetricType() metricType { return metricTypeGauge } type TimerEvent struct { metricName string @@ -214,6 +217,7 @@ type TimerEvent struct { func (t *TimerEvent) MetricName() string { return t.metricName } func (t *TimerEvent) Value() float64 { return t.value } func (c *TimerEvent) Labels() map[string]string { return c.labels } +func (c *TimerEvent) MetricType() metricType { return metricTypeTimer } type Events []Event @@ -248,7 +252,7 @@ func (b *Exporter) Listen(e <-chan Events) { metricName := "" prometheusLabels := event.Labels() - mapping, labels, present := b.mapper.getMapping(event.MetricName()) + mapping, labels, present := b.mapper.getMapping(event.MetricName(), event.MetricType()) if mapping == nil { mapping = &metricMapping{} } diff --git a/mapper.go b/mapper.go index 55d6f3b..9b8f004 100644 --- a/mapper.go +++ b/mapper.go @@ -45,16 +45,19 @@ type metricMapper struct { mutex sync.Mutex } +type matchMetricType string + type metricMapping struct { - Match string `yaml:"match"` - Name string `yaml:"name"` - regex *regexp.Regexp - Labels prometheus.Labels `yaml:"labels"` - TimerType timerType `yaml:"timer_type"` - Buckets []float64 `yaml:"buckets"` - MatchType matchType `yaml:"match_type"` - HelpText string `yaml:"help"` - Action actionType `yaml:"action"` + Match string `yaml:"match"` + Name string `yaml:"name"` + regex *regexp.Regexp + Labels prometheus.Labels `yaml:"labels"` + TimerType timerType `yaml:"timer_type"` + Buckets []float64 `yaml:"buckets"` + MatchType matchType `yaml:"match_type"` + HelpText string `yaml:"help"` + Action actionType `yaml:"action"` + MatchMetricType metricType `yaml:"match_metric_type"` } func (m *metricMapper) initFromYAMLString(fileContents string) error { @@ -148,7 +151,7 @@ func (m *metricMapper) initFromFile(fileName string) error { return m.initFromYAMLString(string(mappingStr)) } -func (m *metricMapper) getMapping(statsdMetric string) (*metricMapping, prometheus.Labels, bool) { +func (m *metricMapper) getMapping(statsdMetric string, statsdMetricType metricType) (*metricMapping, prometheus.Labels, bool) { m.mutex.Lock() defer m.mutex.Unlock() @@ -165,6 +168,10 @@ func (m *metricMapper) getMapping(statsdMetric string) (*metricMapping, promethe matches, )) + if mt := mapping.MatchMetricType; mt != "" && mt != statsdMetricType { + continue + } + labels := prometheus.Labels{} for label, valueExpr := range mapping.Labels { value := mapping.regex.ExpandString([]byte{}, valueExpr, statsdMetric, matches) diff --git a/metric_type.go b/metric_type.go new file mode 100644 index 0000000..61163fd --- /dev/null +++ b/metric_type.go @@ -0,0 +1,43 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import "fmt" + +type metricType string + +const ( + metricTypeCounter metricType = "counter" + metricTypeGauge metricType = "gauge" + metricTypeTimer metricType = "timer" +) + +func (m *metricType) UnmarshalYAML(unmarshal func(interface{}) error) error { + var v string + if err := unmarshal(&v); err != nil { + return err + } + + switch metricType(v) { + case metricTypeCounter: + *m = metricTypeCounter + case metricTypeGauge: + *m = metricTypeGauge + case metricTypeTimer: + *m = metricTypeTimer + default: + return fmt.Errorf("invalid metric type '%s'", v) + } + return nil +}