2016-07-28 19:31:11 +08:00
|
|
|
package models
|
2016-01-23 02:54:12 +08:00
|
|
|
|
|
|
|
|
import (
|
2016-04-13 07:06:27 +08:00
|
|
|
"fmt"
|
2016-01-23 02:54:12 +08:00
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
"github.com/influxdata/telegraf"
|
2016-06-03 01:47:15 +08:00
|
|
|
"github.com/influxdata/telegraf/filter"
|
2016-01-23 02:54:12 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// TagFilter is the name of a tag, and the values on which to filter
|
|
|
|
|
type TagFilter struct {
|
|
|
|
|
Name string
|
2022-10-13 03:19:47 +08:00
|
|
|
Values []string
|
2016-06-03 01:47:15 +08:00
|
|
|
filter filter.Filter
|
2016-01-23 02:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 16:26:38 +08:00
|
|
|
func (tf *TagFilter) Compile() error {
|
|
|
|
|
f, err := filter.Compile(tf.Values)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
tf.filter = f
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-23 02:54:12 +08:00
|
|
|
// Filter containing drop/pass and tagdrop/tagpass rules
|
|
|
|
|
type Filter struct {
|
2022-10-13 03:19:47 +08:00
|
|
|
NameDrop []string
|
|
|
|
|
nameDropFilter filter.Filter
|
|
|
|
|
NamePass []string
|
|
|
|
|
namePassFilter filter.Filter
|
2016-02-20 13:35:12 +08:00
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
FieldDrop []string
|
|
|
|
|
fieldDropFilter filter.Filter
|
|
|
|
|
FieldPass []string
|
|
|
|
|
fieldPassFilter filter.Filter
|
2016-01-23 02:54:12 +08:00
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
TagDropFilters []TagFilter
|
|
|
|
|
TagPassFilters []TagFilter
|
2016-01-23 02:54:12 +08:00
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
TagExclude []string
|
|
|
|
|
tagExcludeFilter filter.Filter
|
|
|
|
|
TagInclude []string
|
|
|
|
|
tagIncludeFilter filter.Filter
|
2016-04-13 07:06:27 +08:00
|
|
|
|
2016-09-05 23:16:37 +08:00
|
|
|
isActive bool
|
2016-01-23 02:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
2016-06-03 01:47:15 +08:00
|
|
|
// Compile all Filter lists into filter.Filter objects.
|
2016-09-05 23:16:37 +08:00
|
|
|
func (f *Filter) Compile() error {
|
|
|
|
|
if len(f.NameDrop) == 0 &&
|
|
|
|
|
len(f.NamePass) == 0 &&
|
|
|
|
|
len(f.FieldDrop) == 0 &&
|
|
|
|
|
len(f.FieldPass) == 0 &&
|
|
|
|
|
len(f.TagInclude) == 0 &&
|
|
|
|
|
len(f.TagExclude) == 0 &&
|
2022-10-13 03:19:47 +08:00
|
|
|
len(f.TagPassFilters) == 0 &&
|
|
|
|
|
len(f.TagDropFilters) == 0 {
|
2016-09-05 23:16:37 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f.isActive = true
|
2016-04-13 07:06:27 +08:00
|
|
|
var err error
|
2022-10-13 03:19:47 +08:00
|
|
|
f.nameDropFilter, err = filter.Compile(f.NameDrop)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'namedrop', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
2022-10-13 03:19:47 +08:00
|
|
|
f.namePassFilter, err = filter.Compile(f.NamePass)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'namepass', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
f.fieldDropFilter, err = filter.Compile(f.FieldDrop)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'fielddrop', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
2022-10-13 03:19:47 +08:00
|
|
|
f.fieldPassFilter, err = filter.Compile(f.FieldPass)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'fieldpass', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
f.tagExcludeFilter, err = filter.Compile(f.TagExclude)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'tagexclude', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
2022-10-13 03:19:47 +08:00
|
|
|
f.tagIncludeFilter, err = filter.Compile(f.TagInclude)
|
2016-04-13 07:06:27 +08:00
|
|
|
if err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'taginclude', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 16:26:38 +08:00
|
|
|
for i := 0; i < len(f.TagDropFilters); i++ {
|
|
|
|
|
if err := f.TagDropFilters[i].Compile(); err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'tagdrop', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-07 16:26:38 +08:00
|
|
|
|
|
|
|
|
for i := 0; i < len(f.TagPassFilters); i++ {
|
|
|
|
|
if err := f.TagPassFilters[i].Compile(); err != nil {
|
2023-02-22 19:57:53 +08:00
|
|
|
return fmt.Errorf("error compiling 'tagpass', %w", err)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
// Select returns true if the metric matches according to the
|
|
|
|
|
// namepass/namedrop and tagpass/tagdrop filters. The metric is not modified.
|
|
|
|
|
func (f *Filter) Select(metric telegraf.Metric) bool {
|
2016-09-05 23:16:37 +08:00
|
|
|
if !f.isActive {
|
2016-01-23 02:54:12 +08:00
|
|
|
return true
|
|
|
|
|
}
|
2016-09-05 23:16:37 +08:00
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
if !f.shouldNamePass(metric.Name()) {
|
2016-09-05 23:16:37 +08:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
if !f.shouldTagsPass(metric.TagList()) {
|
2016-09-05 23:16:37 +08:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
return true
|
|
|
|
|
}
|
2016-09-05 23:16:37 +08:00
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
// Modify removes any tags and fields from the metric according to the
|
|
|
|
|
// fieldpass/fielddrop and taginclude/tagexclude filters.
|
|
|
|
|
func (f *Filter) Modify(metric telegraf.Metric) {
|
|
|
|
|
if !f.isActive {
|
|
|
|
|
return
|
|
|
|
|
}
|
2016-09-05 23:16:37 +08:00
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
f.filterFields(metric)
|
|
|
|
|
f.filterTags(metric)
|
2016-09-05 23:16:37 +08:00
|
|
|
}
|
|
|
|
|
|
2017-07-22 01:53:57 +08:00
|
|
|
// IsActive checking if filter is active
|
2016-09-05 23:16:37 +08:00
|
|
|
func (f *Filter) IsActive() bool {
|
|
|
|
|
return f.isActive
|
2016-01-23 02:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
// shouldNamePass returns true if the metric should pass, false if it should drop
|
2016-02-20 13:35:12 +08:00
|
|
|
// based on the drop/pass filter parameters
|
2016-09-05 23:16:37 +08:00
|
|
|
func (f *Filter) shouldNamePass(key string) bool {
|
2017-07-22 01:53:57 +08:00
|
|
|
pass := func(f *Filter) bool {
|
2022-10-13 03:19:47 +08:00
|
|
|
return f.namePassFilter.Match(key)
|
2016-02-20 13:35:12 +08:00
|
|
|
}
|
|
|
|
|
|
2017-07-22 01:53:57 +08:00
|
|
|
drop := func(f *Filter) bool {
|
2022-10-13 03:19:47 +08:00
|
|
|
return !f.nameDropFilter.Match(key)
|
2016-02-20 13:35:12 +08:00
|
|
|
}
|
2017-07-22 01:53:57 +08:00
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
if f.namePassFilter != nil && f.nameDropFilter != nil {
|
2017-07-22 01:53:57 +08:00
|
|
|
return pass(f) && drop(f)
|
2022-10-13 03:19:47 +08:00
|
|
|
} else if f.namePassFilter != nil {
|
2017-07-22 01:53:57 +08:00
|
|
|
return pass(f)
|
2022-10-13 03:19:47 +08:00
|
|
|
} else if f.nameDropFilter != nil {
|
2017-07-22 01:53:57 +08:00
|
|
|
return drop(f)
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-20 13:35:12 +08:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
// shouldFieldPass returns true if the metric should pass, false if it should drop
|
2016-01-23 02:54:12 +08:00
|
|
|
// based on the drop/pass filter parameters
|
2016-09-05 23:16:37 +08:00
|
|
|
func (f *Filter) shouldFieldPass(key string) bool {
|
2022-10-13 03:19:47 +08:00
|
|
|
if f.fieldPassFilter != nil && f.fieldDropFilter != nil {
|
|
|
|
|
return f.fieldPassFilter.Match(key) && !f.fieldDropFilter.Match(key)
|
|
|
|
|
} else if f.fieldPassFilter != nil {
|
|
|
|
|
return f.fieldPassFilter.Match(key)
|
|
|
|
|
} else if f.fieldDropFilter != nil {
|
|
|
|
|
return !f.fieldDropFilter.Match(key)
|
2017-07-22 01:53:57 +08:00
|
|
|
}
|
2016-01-23 02:54:12 +08:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
// shouldTagsPass returns true if the metric should pass, false if it should drop
|
2016-01-23 02:54:12 +08:00
|
|
|
// based on the tagdrop/tagpass filter parameters
|
2018-09-29 05:48:20 +08:00
|
|
|
func (f *Filter) shouldTagsPass(tags []*telegraf.Tag) bool {
|
2023-03-07 16:26:38 +08:00
|
|
|
return ShouldTagsPass(f.TagPassFilters, f.TagDropFilters, tags)
|
2016-01-23 02:54:12 +08:00
|
|
|
}
|
2016-04-13 07:06:27 +08:00
|
|
|
|
2018-09-29 05:48:20 +08:00
|
|
|
// filterFields removes fields according to fieldpass/fielddrop.
|
|
|
|
|
func (f *Filter) filterFields(metric telegraf.Metric) {
|
|
|
|
|
filterKeys := []string{}
|
|
|
|
|
for _, field := range metric.FieldList() {
|
|
|
|
|
if !f.shouldFieldPass(field.Key) {
|
|
|
|
|
filterKeys = append(filterKeys, field.Key)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, key := range filterKeys {
|
|
|
|
|
metric.RemoveField(key)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// filterTags removes tags according to taginclude/tagexclude.
|
|
|
|
|
func (f *Filter) filterTags(metric telegraf.Metric) {
|
|
|
|
|
filterKeys := []string{}
|
2022-10-13 03:19:47 +08:00
|
|
|
if f.tagIncludeFilter != nil {
|
2018-09-29 05:48:20 +08:00
|
|
|
for _, tag := range metric.TagList() {
|
2022-10-13 03:19:47 +08:00
|
|
|
if !f.tagIncludeFilter.Match(tag.Key) {
|
2018-09-29 05:48:20 +08:00
|
|
|
filterKeys = append(filterKeys, tag.Key)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-29 05:48:20 +08:00
|
|
|
for _, key := range filterKeys {
|
|
|
|
|
metric.RemoveTag(key)
|
|
|
|
|
}
|
2016-04-13 07:06:27 +08:00
|
|
|
|
2022-10-13 03:19:47 +08:00
|
|
|
if f.tagExcludeFilter != nil {
|
2018-09-29 05:48:20 +08:00
|
|
|
for _, tag := range metric.TagList() {
|
2022-10-13 03:19:47 +08:00
|
|
|
if f.tagExcludeFilter.Match(tag.Key) {
|
2018-09-29 05:48:20 +08:00
|
|
|
filterKeys = append(filterKeys, tag.Key)
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-29 05:48:20 +08:00
|
|
|
for _, key := range filterKeys {
|
|
|
|
|
metric.RemoveTag(key)
|
|
|
|
|
}
|
2016-04-13 07:06:27 +08:00
|
|
|
}
|
2023-03-07 16:26:38 +08:00
|
|
|
|
|
|
|
|
func ShouldTagsPass(passFilters []TagFilter, dropFilters []TagFilter, tags []*telegraf.Tag) bool {
|
|
|
|
|
pass := func(tpf []TagFilter) bool {
|
|
|
|
|
for _, pat := range tpf {
|
|
|
|
|
if pat.filter == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
for _, tag := range tags {
|
|
|
|
|
if tag.Key == pat.Name {
|
|
|
|
|
if pat.filter.Match(tag.Value) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drop := func(tdf []TagFilter) bool {
|
|
|
|
|
for _, pat := range tdf {
|
|
|
|
|
if pat.filter == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
for _, tag := range tags {
|
|
|
|
|
if tag.Key == pat.Name {
|
|
|
|
|
if pat.filter.Match(tag.Value) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add additional logic in case where both parameters are set.
|
|
|
|
|
// see: https://github.com/influxdata/telegraf/issues/2860
|
|
|
|
|
if passFilters != nil && dropFilters != nil {
|
|
|
|
|
// return true only in case when tag pass and won't be dropped (true, true).
|
|
|
|
|
// in case when the same tag should be passed and dropped it will be dropped (true, false).
|
|
|
|
|
return pass(passFilters) && drop(dropFilters)
|
|
|
|
|
} else if passFilters != nil {
|
|
|
|
|
return pass(passFilters)
|
|
|
|
|
} else if dropFilters != nil {
|
|
|
|
|
return drop(dropFilters)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|