forked from mirrors/statsd_exporter
Merge pull request #115 from bakins/bakins/match-actions
Add drop action for matches
This commit is contained in:
commit
25c9946cf3
5 changed files with 177 additions and 1 deletions
21
README.md
21
README.md
|
@ -204,6 +204,27 @@ mappings:
|
||||||
job: "${1}_server_other"
|
job: "${1}_server_other"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You may also drop metrics by specifying a "drop" action on a match. For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
mappings:
|
||||||
|
# This metric would match as normal.
|
||||||
|
- match: test.timing.*.*.*
|
||||||
|
name: "my_timer"
|
||||||
|
labels:
|
||||||
|
provider: "$2"
|
||||||
|
outcome: "$3"
|
||||||
|
job: "${1}_server"
|
||||||
|
# Any metric not matched will be dropped because "." matches all metrics.
|
||||||
|
- match: .
|
||||||
|
match_type: regex
|
||||||
|
action: drop
|
||||||
|
name: "dropped"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can drop any metric using the normal match syntax.
|
||||||
|
The default action is "map" which does the normal metrics mapping.
|
||||||
|
|
||||||
## Using Docker
|
## Using Docker
|
||||||
|
|
||||||
You can deploy this exporter using the [prom/statsd-exporter](https://registry.hub.docker.com/u/prom/statsd-exporter/) Docker image.
|
You can deploy this exporter using the [prom/statsd-exporter](https://registry.hub.docker.com/u/prom/statsd-exporter/) Docker image.
|
||||||
|
|
42
action.go
Normal file
42
action.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// 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 actionType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
actionTypeMap actionType = "map"
|
||||||
|
actionTypeDrop actionType = "drop"
|
||||||
|
actionTypeDefault actionType = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *actionType) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var v string
|
||||||
|
|
||||||
|
if err := unmarshal(&v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch actionType(v) {
|
||||||
|
case actionTypeDrop:
|
||||||
|
*t = actionTypeDrop
|
||||||
|
case actionTypeMap, actionTypeDefault:
|
||||||
|
*t = actionTypeMap
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid action type %q", v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -252,6 +252,11 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
if mapping == nil {
|
if mapping == nil {
|
||||||
mapping = &metricMapping{}
|
mapping = &metricMapping{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mapping.Action == actionTypeDrop {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if mapping.HelpText == "" {
|
if mapping.HelpText == "" {
|
||||||
help = defaultHelp
|
help = defaultHelp
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -54,6 +54,7 @@ type metricMapping struct {
|
||||||
Buckets []float64 `yaml:"buckets"`
|
Buckets []float64 `yaml:"buckets"`
|
||||||
MatchType matchType `yaml:"match_type"`
|
MatchType matchType `yaml:"match_type"`
|
||||||
HelpText string `yaml:"help"`
|
HelpText string `yaml:"help"`
|
||||||
|
Action actionType `yaml:"action"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *metricMapper) initFromYAMLString(fileContents string) error {
|
func (m *metricMapper) initFromYAMLString(fileContents string) error {
|
||||||
|
@ -93,6 +94,10 @@ func (m *metricMapper) initFromYAMLString(fileContents string) error {
|
||||||
currentMapping.MatchType = n.Defaults.MatchType
|
currentMapping.MatchType = n.Defaults.MatchType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if currentMapping.Action == "" {
|
||||||
|
currentMapping.Action = actionTypeMap
|
||||||
|
}
|
||||||
|
|
||||||
if currentMapping.MatchType == matchTypeGlob {
|
if currentMapping.MatchType == matchTypeGlob {
|
||||||
if !metricLineRE.MatchString(currentMapping.Match) {
|
if !metricLineRE.MatchString(currentMapping.Match) {
|
||||||
return fmt.Errorf("invalid match: %s", currentMapping.Match)
|
return fmt.Errorf("invalid match: %s", currentMapping.Match)
|
||||||
|
|
105
mapper_test.go
105
mapper_test.go
|
@ -360,6 +360,39 @@ mappings:
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Config that drops all.
|
||||||
|
{
|
||||||
|
config: `mappings:
|
||||||
|
- match: .
|
||||||
|
match_type: regex
|
||||||
|
name: "drop"
|
||||||
|
action: drop`,
|
||||||
|
mappings: mappings{
|
||||||
|
"test.a": {},
|
||||||
|
"abc": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Config that has a catch-all to drop all.
|
||||||
|
{
|
||||||
|
config: `mappings:
|
||||||
|
- match: web.*
|
||||||
|
name: "web"
|
||||||
|
labels:
|
||||||
|
site: "$1"
|
||||||
|
- match: .
|
||||||
|
match_type: regex
|
||||||
|
name: "drop"
|
||||||
|
action: drop`,
|
||||||
|
mappings: mappings{
|
||||||
|
"test.a": {},
|
||||||
|
"web.localhost": {
|
||||||
|
name: "web",
|
||||||
|
labels: map[string]string{
|
||||||
|
"site": "localhost",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper := metricMapper{}
|
mapper := metricMapper{}
|
||||||
|
@ -374,7 +407,7 @@ mappings:
|
||||||
|
|
||||||
for metric, mapping := range scenario.mappings {
|
for metric, mapping := range scenario.mappings {
|
||||||
m, labels, present := mapper.getMapping(metric)
|
m, labels, present := mapper.getMapping(metric)
|
||||||
if present && m.Name != mapping.name {
|
if present && mapping.name != "" && m.Name != mapping.name {
|
||||||
t.Fatalf("%d.%q: Expected name %v, got %v", i, metric, m.Name, mapping.name)
|
t.Fatalf("%d.%q: Expected name %v, got %v", i, metric, m.Name, mapping.name)
|
||||||
}
|
}
|
||||||
if mapping.notPresent && present {
|
if mapping.notPresent && present {
|
||||||
|
@ -392,3 +425,73 @@ mappings:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAction(t *testing.T) {
|
||||||
|
scenarios := []struct {
|
||||||
|
config string
|
||||||
|
configBad bool
|
||||||
|
expectedAction actionType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// no action set
|
||||||
|
config: `---
|
||||||
|
mappings:
|
||||||
|
- match: test.*.*
|
||||||
|
name: "foo"
|
||||||
|
`,
|
||||||
|
configBad: false,
|
||||||
|
expectedAction: actionTypeMap,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// map action set
|
||||||
|
config: `---
|
||||||
|
mappings:
|
||||||
|
- match: test.*.*
|
||||||
|
name: "foo"
|
||||||
|
action: map
|
||||||
|
`,
|
||||||
|
configBad: false,
|
||||||
|
expectedAction: actionTypeMap,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// drop action set
|
||||||
|
config: `---
|
||||||
|
mappings:
|
||||||
|
- match: test.*.*
|
||||||
|
name: "foo"
|
||||||
|
action: drop
|
||||||
|
`,
|
||||||
|
configBad: false,
|
||||||
|
expectedAction: actionTypeDrop,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// invalid action set
|
||||||
|
config: `---
|
||||||
|
mappings:
|
||||||
|
- match: test.*.*
|
||||||
|
name: "foo"
|
||||||
|
action: xyz
|
||||||
|
`,
|
||||||
|
configBad: true,
|
||||||
|
expectedAction: actionTypeDrop,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, scenario := range scenarios {
|
||||||
|
mapper := metricMapper{}
|
||||||
|
err := mapper.initFromYAMLString(scenario.config)
|
||||||
|
if err != nil && !scenario.configBad {
|
||||||
|
t.Fatalf("%d. Config load error: %s %s", i, scenario.config, err)
|
||||||
|
}
|
||||||
|
if err == nil && scenario.configBad {
|
||||||
|
t.Fatalf("%d. Expected bad config, but loaded ok: %s", i, scenario.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !scenario.configBad {
|
||||||
|
a := mapper.Mappings[0].Action
|
||||||
|
if scenario.expectedAction != a {
|
||||||
|
t.Fatalf("%d: Expected action %v, got %v", i, scenario.expectedAction, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue