forked from mirrors/statsd_exporter
Use correct name when multiple names match same FSM match
Signed-off-by: Brian Akins <brian@akins.org>
This commit is contained in:
parent
20006621cc
commit
b234e1dd4e
2 changed files with 63 additions and 1 deletions
|
@ -245,7 +245,8 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
|
|||
if m.doFSM {
|
||||
finalState, captures := m.FSM.GetMapping(statsdMetric, string(statsdMetricType))
|
||||
if finalState != nil && finalState.Result != nil {
|
||||
result := finalState.Result.(*MetricMapping)
|
||||
v := finalState.Result.(*MetricMapping)
|
||||
result := copyMetricMapping(v)
|
||||
result.Name = result.nameFormatter.Format(captures)
|
||||
|
||||
labels := prometheus.Labels{}
|
||||
|
@ -299,3 +300,11 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
|
|||
m.cache.AddMiss(statsdMetric, statsdMetricType)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue