Skip to content

Commit

Permalink
Add banfield transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Oracz committed Oct 9, 2024
1 parent f76c5fa commit 90a28aa
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
7 changes: 7 additions & 0 deletions transformer/auto.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,11 @@ func init() {
Help: "Ban values from nested structure using a path e.g. Path looking like this foo.bar.1 has a structure looking like this { foo: { bar: { 1: hello } } }. The last element in the path will get removed from the tree in this case 1: hello, you will end up having a tree looking like this { foo: { bar: {} } }.",
AutoMake: false,
})
Auto.Add(skogul.Module{
Name: "banfield",
Aliases: []string{},
Alloc: func() interface{} { return &BanField{} },
Help: "Remove single fields in a metric based on a regular expression criteria",
AutoMake: false,
})
}
75 changes: 75 additions & 0 deletions transformer/ban_field.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package transformer

import (
"fmt"
"github.com/telenornms/skogul"
"regexp"
"sync"
)

type BanField struct {
SourceData string `doc:"Data field to ban"`
RegexpData string `doc:"Regex to match value of source-data field"`
regexpData *regexp.Regexp
SourceMetadata string `doc:"Metadata field to ban"`
RegexpMetadata string `doc:"Regex to match value of source-metadata field"`
regexpMetadata *regexp.Regexp
errData error
errMetadata error
init sync.Once
}

func (b *BanField) Transform(c *skogul.Container) error {
b.init.Do(func() {
b.regexpData, b.errData = regexp.Compile(b.RegexpData)
b.regexpMetadata, b.errMetadata = regexp.Compile(b.RegexpMetadata)
})

if b.errData != nil {
return fmt.Errorf("unable to compile regexp `%s': %w", b.RegexpData, b.errData)
}
if b.errMetadata != nil {
return fmt.Errorf("unable to compile regexp `%s': %w", b.RegexpMetadata, b.errMetadata)
}

for _, metric := range c.Metrics {
if b.SourceData != "" {
if str, ok := metric.Data[b.SourceData]; ok {
if b.regexpData.Match([]byte(str.(string))) {
delete(metric.Data, b.SourceData)
}
}
}
if b.SourceMetadata != "" {
if str, ok := metric.Metadata[b.SourceMetadata]; ok {
if b.regexpMetadata.Match([]byte(str.(string))) {
delete(metric.Metadata, b.SourceMetadata)
}
}
}
}

return nil
}

func (b *BanField) Verify() error {
if b.SourceData != "" && b.RegexpData == "" {
return fmt.Errorf("regexpdata field has to have a value when sourcedata is provided")
}
if b.SourceMetadata != "" && b.RegexpMetadata == "" {
return fmt.Errorf("regexpmetadata field has to have a value when sourcemetadata is provided")
}

var err error

_, err = regexp.Compile(b.RegexpData)
if err != nil {
return fmt.Errorf("failed to compile regexp for regexpdata field %v %v", b.RegexpData, err)
}

_, err = regexp.Compile(b.RegexpMetadata)
if err != nil {
return fmt.Errorf("failed to compile regexp for regexpmetadata field %v %v", b.RegexpMetadata, err)
}
return nil
}
41 changes: 41 additions & 0 deletions transformer/ban_field_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package transformer_test

import (
"testing"

"github.com/telenornms/skogul"
"github.com/telenornms/skogul/transformer"
)

func TestBanField(t *testing.T) {
metric := skogul.Metric{}
metric.Metadata = make(map[string]interface{})
metric.Metadata["foofoo"] = "barBAR"
metric.Data = make(map[string]interface{})
metric.Data["foo"] = "BAR"
metric.Data["baz"] = "foobar"
c := skogul.Container{}
c.Metrics = []*skogul.Metric{&metric}

ban := transformer.BanField{
SourceData: "foo",
RegexpData: "BAR",
SourceMetadata: "foofoo",
RegexpMetadata: "barBAR",
}

t.Logf("Container before transform:\n%v", c)
err := ban.Transform(&c)
if err != nil {
t.Errorf("ban_field returned non-nil err: %v", err)
}

t.Logf("Container after transform:\n%v", c)

if _, ok := c.Metrics[0].Metadata["foofoo"]; ok {
t.Fatal("ban_field transformer failed to ban key-value pair")
}
if _, ok := c.Metrics[0].Data["foo"]; ok {
t.Fatal("ban_field transformer failed to ban key-value pair")
}
}

0 comments on commit 90a28aa

Please sign in to comment.