Make mapper cache respect metric type

- Statsd allows users to provide a metric with the same name but
  differing types (counter, gauge, timer)
- The exporter allows this by letting users specify a
  "match_metric_type" in the mapping config
- However the mapper cache does not look at the metric type so it would
  return a MetricMapperCacheResult for the type of the first metric with
that name that the exporter saw
- Add MetricType to the signature for the cache and format the metric
  name with the type to provide unique keys for a metric with the same
name but differing type

Signed-off-by: Andy Paine <andy.paine@digital.cabinet-office.gov.uk>
This commit is contained in:
Andy Paine 2019-06-06 09:31:11 +01:00
parent 50d5932124
commit 0135b40c08
2 changed files with 22 additions and 17 deletions

View file

@ -237,7 +237,7 @@ func (m *MetricMapper) InitCache(cacheSize int) {
func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricType) (*MetricMapping, prometheus.Labels, bool) {
m.mutex.RLock()
defer m.mutex.RUnlock()
result, cached := m.cache.Get(statsdMetric)
result, cached := m.cache.Get(statsdMetric, statsdMetricType)
if cached {
return result.Mapping, result.Labels, result.Matched
}
@ -253,12 +253,12 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
labels[result.labelKeys[index]] = formatter.Format(captures)
}
m.cache.AddMatch(statsdMetric, result, labels)
m.cache.AddMatch(statsdMetric, statsdMetricType, result, labels)
return result, labels, true
} else if !m.doRegex {
// if there's no regex match type, return immediately
m.cache.AddMiss(statsdMetric)
m.cache.AddMiss(statsdMetric, statsdMetricType)
return nil, nil, false
}
}
@ -291,11 +291,11 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
labels[label] = string(value)
}
m.cache.AddMatch(statsdMetric, &mapping, labels)
m.cache.AddMatch(statsdMetric, statsdMetricType, &mapping, labels)
return &mapping, labels, true
}
m.cache.AddMiss(statsdMetric)
m.cache.AddMiss(statsdMetric, statsdMetricType)
return nil, nil, false
}

View file

@ -14,6 +14,7 @@
package mapper
import (
"fmt"
"github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
)
@ -34,9 +35,9 @@ type MetricMapperCacheResult struct {
}
type MetricMapperCache interface {
Get(metricString string) (*MetricMapperCacheResult, bool)
AddMatch(metricString string, mapping *MetricMapping, labels prometheus.Labels)
AddMiss(metricString string)
Get(metricString string, metricType MetricType) (*MetricMapperCacheResult, bool)
AddMatch(metricString string, metricType MetricType, mapping *MetricMapping, labels prometheus.Labels)
AddMiss(metricString string, metricType MetricType)
}
type MetricMapperLRUCache struct {
@ -57,42 +58,46 @@ func NewMetricMapperCache(size int) (*MetricMapperLRUCache, error) {
return &MetricMapperLRUCache{cache: cache}, nil
}
func (m *MetricMapperLRUCache) Get(metricString string) (*MetricMapperCacheResult, bool) {
if result, ok := m.cache.Get(metricString); ok {
func (m *MetricMapperLRUCache) Get(metricString string, metricType MetricType) (*MetricMapperCacheResult, bool) {
if result, ok := m.cache.Get(formatKey(metricString, metricType)); ok {
return result.(*MetricMapperCacheResult), true
} else {
return nil, false
}
}
func (m *MetricMapperLRUCache) AddMatch(metricString string, mapping *MetricMapping, labels prometheus.Labels) {
func (m *MetricMapperLRUCache) AddMatch(metricString string, metricType MetricType, mapping *MetricMapping, labels prometheus.Labels) {
go m.trackCacheLength()
m.cache.Add(metricString, &MetricMapperCacheResult{Mapping: mapping, Matched: true, Labels: labels})
m.cache.Add(formatKey(metricString, metricType), &MetricMapperCacheResult{Mapping: mapping, Matched: true, Labels: labels})
}
func (m *MetricMapperLRUCache) AddMiss(metricString string) {
func (m *MetricMapperLRUCache) AddMiss(metricString string, metricType MetricType) {
go m.trackCacheLength()
m.cache.Add(metricString, &MetricMapperCacheResult{Matched: false})
m.cache.Add(formatKey(metricString, metricType), &MetricMapperCacheResult{Matched: false})
}
func (m *MetricMapperLRUCache) trackCacheLength() {
cacheLength.Set(float64(m.cache.Len()))
}
func formatKey(metricString string, metricType MetricType) string {
return fmt.Sprintf("%s.%s", string(metricType), metricString)
}
func NewMetricMapperNoopCache() *MetricMapperNoopCache {
cacheLength.Set(0)
return &MetricMapperNoopCache{}
}
func (m *MetricMapperNoopCache) Get(metricString string) (*MetricMapperCacheResult, bool) {
func (m *MetricMapperNoopCache) Get(metricString string, metricType MetricType) (*MetricMapperCacheResult, bool) {
return nil, false
}
func (m *MetricMapperNoopCache) AddMatch(metricString string, mapping *MetricMapping, labels prometheus.Labels) {
func (m *MetricMapperNoopCache) AddMatch(metricString string, metricType MetricType, mapping *MetricMapping, labels prometheus.Labels) {
return
}
func (m *MetricMapperNoopCache) AddMiss(metricString string) {
func (m *MetricMapperNoopCache) AddMiss(metricString string, metricType MetricType) {
return
}