-
Notifications
You must be signed in to change notification settings - Fork 13
/
tag_limit.go
87 lines (76 loc) · 1.92 KB
/
tag_limit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package taglimit
import (
"fmt"
"log"
"github.com/circonus-labs/circonus-unified-agent/cua"
"github.com/circonus-labs/circonus-unified-agent/plugins/processors"
)
const sampleConfig = `
## Maximum number of tags to preserve
limit = 10
## List of tags to preferentially preserve
keep = ["foo", "bar", "baz"]
`
type TagLimit struct {
Limit int `toml:"limit"`
Keep []string `toml:"keep"`
init bool
keepTags map[string]string
}
func (d *TagLimit) SampleConfig() string {
return sampleConfig
}
func (d *TagLimit) Description() string {
return "Restricts the number of tags that can pass through this filter and chooses which tags to preserve when over the limit."
}
func (d *TagLimit) initOnce() error {
if d.init {
return nil
}
if len(d.Keep) > d.Limit {
return fmt.Errorf("%d keep tags is greater than %d total tag limit", len(d.Keep), d.Limit)
}
d.keepTags = make(map[string]string)
// convert list of tags-to-keep to a map so we can do constant-time lookups
for _, tagKey := range d.Keep {
d.keepTags[tagKey] = ""
}
d.init = true
return nil
}
func (d *TagLimit) Apply(in ...cua.Metric) []cua.Metric {
err := d.initOnce()
if err != nil {
log.Printf("E! [processors.tag_limit] could not create tag_limit processor: %v", err)
return in
}
for _, point := range in {
pointOriginalTags := point.TagList()
lenPointTags := len(pointOriginalTags)
if lenPointTags <= d.Limit {
continue
}
tagsToRemove := make([]string, lenPointTags-d.Limit)
removeIdx := 0
// remove extraneous tags, stop once we're at the limit
for _, t := range pointOriginalTags {
if _, ok := d.keepTags[t.Key]; !ok {
tagsToRemove[removeIdx] = t.Key
removeIdx++
lenPointTags--
}
if lenPointTags <= d.Limit {
break
}
}
for _, t := range tagsToRemove {
point.RemoveTag(t)
}
}
return in
}
func init() {
processors.Add("tag_limit", func() cua.Processor {
return &TagLimit{}
})
}