Merge pull request #286 from bakins/273-fsm-cache

Use correct name when multiple names match same FSM match
This commit is contained in:
Matthias Rampke 2020-01-13 09:58:44 +00:00 committed by GitHub
commit 3a88bd3ddb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 1 deletions

View file

@ -245,7 +245,8 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
if m.doFSM { if m.doFSM {
finalState, captures := m.FSM.GetMapping(statsdMetric, string(statsdMetricType)) finalState, captures := m.FSM.GetMapping(statsdMetric, string(statsdMetricType))
if finalState != nil && finalState.Result != nil { if finalState != nil && finalState.Result != nil {
result := finalState.Result.(*MetricMapping) v := finalState.Result.(*MetricMapping)
result := copyMetricMapping(v)
result.Name = result.nameFormatter.Format(captures) result.Name = result.nameFormatter.Format(captures)
labels := prometheus.Labels{} labels := prometheus.Labels{}
@ -299,3 +300,11 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
m.cache.AddMiss(statsdMetric, statsdMetricType) m.cache.AddMiss(statsdMetric, statsdMetricType)
return nil, nil, false return nil, nil, false
} }
// make a shallow copy so that we do not overwrite name
// as multiple names can be matched by same mapping
func copyMetricMapping(in *MetricMapping) *MetricMapping {
var out MetricMapping
out = *in
return &out
}

View file

@ -887,3 +887,56 @@ mappings:
} }
} }
} }
// Test for https://github.com/prometheus/statsd_exporter/issues/273
// Corrupt cache for multiple names matching in fsm
func TestMultipleMatches(t *testing.T) {
config := `---
mappings:
- match: aa.bb.*.*
name: "aa_bb_${1}_total"
labels:
app: "$2"
`
mapper := MetricMapper{}
err := mapper.InitFromYAMLString(config, 0)
if err != nil {
t.Fatalf("config load error: %s ", err)
}
names := map[string]string{
"aa.bb.aa.myapp": "aa_bb_aa_total",
"aa.bb.bb.myapp": "aa_bb_bb_total",
"aa.bb.cc.myapp": "aa_bb_cc_total",
"aa.bb.dd.myapp": "aa_bb_dd_total",
}
scenarios := []struct {
cacheSize int
}{
{
cacheSize: 0,
},
{
cacheSize: len(names),
},
}
for i, scenario := range scenarios {
mapper.InitCache(scenario.cacheSize)
// run multiple times to ensure cache works as expected
for j := 0; j < 10; j++ {
for name, expected := range names {
m, _, ok := mapper.GetMapping(name, MetricTypeCounter)
if !ok {
t.Fatalf("%d:%d Did not find match for %s", i, j, name)
}
if m.Name != expected {
t.Fatalf("%d:%d Expected name %s, got %s", i, j, expected, m.Name)
}
}
}
}
}