diff --git a/pkg/ottl/boolean_value.go b/pkg/ottl/boolean_value.go index 360c7c4774016..ecdd4f22f8257 100644 --- a/pkg/ottl/boolean_value.go +++ b/pkg/ottl/boolean_value.go @@ -19,20 +19,20 @@ import ( ) // boolExpressionEvaluator is a function that returns the result. -type boolExpressionEvaluator = func(ctx TransformContext) bool +type boolExpressionEvaluator[K any] func(ctx K) bool -var alwaysTrue = func(ctx TransformContext) bool { +func alwaysTrue[K any](K) bool { return true } -var alwaysFalse = func(ctx TransformContext) bool { +func alwaysFalse[K any](K) bool { return false } // builds a function that returns a short-circuited result of ANDing // boolExpressionEvaluator funcs -func andFuncs(funcs []boolExpressionEvaluator) boolExpressionEvaluator { - return func(ctx TransformContext) bool { +func andFuncs[K any](funcs []boolExpressionEvaluator[K]) boolExpressionEvaluator[K] { + return func(ctx K) bool { for _, f := range funcs { if !f(ctx) { return false @@ -44,8 +44,8 @@ func andFuncs(funcs []boolExpressionEvaluator) boolExpressionEvaluator { // builds a function that returns a short-circuited result of ORing // boolExpressionEvaluator funcs -func orFuncs(funcs []boolExpressionEvaluator) boolExpressionEvaluator { - return func(ctx TransformContext) bool { +func orFuncs[K any](funcs []boolExpressionEvaluator[K]) boolExpressionEvaluator[K] { + return func(ctx K) bool { for _, f := range funcs { if f(ctx) { return true @@ -55,9 +55,9 @@ func orFuncs(funcs []boolExpressionEvaluator) boolExpressionEvaluator { } } -func (p *Parser) newComparisonEvaluator(comparison *Comparison) (boolExpressionEvaluator, error) { +func (p *Parser[K]) newComparisonEvaluator(comparison *Comparison) (boolExpressionEvaluator[K], error) { if comparison == nil { - return alwaysTrue, nil + return alwaysTrue[K], nil } left, err := p.newGetter(comparison.Left) if err != nil { @@ -69,7 +69,7 @@ func (p *Parser) newComparisonEvaluator(comparison *Comparison) (boolExpressionE } // The parser ensures that we'll never get an invalid comparison.Op, so we don't have to check that case. - return func(ctx TransformContext) bool { + return func(ctx K) bool { a := left.Get(ctx) b := right.Get(ctx) return p.compare(a, b, comparison.Op) @@ -77,15 +77,15 @@ func (p *Parser) newComparisonEvaluator(comparison *Comparison) (boolExpressionE } -func (p *Parser) newBooleanExpressionEvaluator(expr *BooleanExpression) (boolExpressionEvaluator, error) { +func (p *Parser[K]) newBooleanExpressionEvaluator(expr *BooleanExpression) (boolExpressionEvaluator[K], error) { if expr == nil { - return alwaysTrue, nil + return alwaysTrue[K], nil } f, err := p.newBooleanTermEvaluator(expr.Left) if err != nil { return nil, err } - funcs := []boolExpressionEvaluator{f} + funcs := []boolExpressionEvaluator[K]{f} for _, rhs := range expr.Right { f, err := p.newBooleanTermEvaluator(rhs.Term) if err != nil { @@ -97,15 +97,15 @@ func (p *Parser) newBooleanExpressionEvaluator(expr *BooleanExpression) (boolExp return orFuncs(funcs), nil } -func (p *Parser) newBooleanTermEvaluator(term *Term) (boolExpressionEvaluator, error) { +func (p *Parser[K]) newBooleanTermEvaluator(term *Term) (boolExpressionEvaluator[K], error) { if term == nil { - return alwaysTrue, nil + return alwaysTrue[K], nil } f, err := p.newBooleanValueEvaluator(term.Left) if err != nil { return nil, err } - funcs := []boolExpressionEvaluator{f} + funcs := []boolExpressionEvaluator[K]{f} for _, rhs := range term.Right { f, err := p.newBooleanValueEvaluator(rhs.Value) if err != nil { @@ -117,9 +117,9 @@ func (p *Parser) newBooleanTermEvaluator(term *Term) (boolExpressionEvaluator, e return andFuncs(funcs), nil } -func (p *Parser) newBooleanValueEvaluator(value *BooleanValue) (boolExpressionEvaluator, error) { +func (p *Parser[K]) newBooleanValueEvaluator(value *BooleanValue) (boolExpressionEvaluator[K], error) { if value == nil { - return alwaysTrue, nil + return alwaysTrue[K], nil } switch { case value.Comparison != nil: @@ -130,9 +130,9 @@ func (p *Parser) newBooleanValueEvaluator(value *BooleanValue) (boolExpressionEv return comparison, nil case value.ConstExpr != nil: if *value.ConstExpr { - return alwaysTrue, nil + return alwaysTrue[K], nil } - return alwaysFalse, nil + return alwaysFalse[K], nil case value.SubExpr != nil: return p.newBooleanExpressionEvaluator(value.SubExpr) } diff --git a/pkg/ottl/boolean_value_test.go b/pkg/ottl/boolean_value_test.go index 2a18a0cc28550..6c1a6770c3dd1 100644 --- a/pkg/ottl/boolean_value_test.go +++ b/pkg/ottl/boolean_value_test.go @@ -85,45 +85,43 @@ func Test_newComparisonEvaluator(t *testing.T) { componenttest.NewNopTelemetrySettings(), ) - tests := []struct { + var tests = []struct { name string l any r any op string - item interface{} + item string want bool }{ - {"literals match", "hello", "hello", "==", nil, true}, - {"literals don't match", "hello", "goodbye", "!=", nil, true}, - {"path expression matches", "NAME", "bear", "==", "bear", true}, - {"path expression not matches", "NAME", "cat", "!=", "bear", true}, - {"compare Enum to int", "TEST_ENUM", int(0), "==", nil, true}, - {"compare int to Enum", int(2), "TEST_ENUM_TWO", "==", nil, true}, - {"2 > Enum 0", int(2), "TEST_ENUM", ">", nil, true}, - {"not 2 < Enum 0", int(2), "TEST_ENUM", "<", nil, false}, - {"not 6 == 3.14", 6, 3.14, "==", nil, false}, - {"6 != 3.14", 6, 3.14, "!=", nil, true}, - {"6 > 3.14", 6, 3.14, ">", nil, true}, - {"6 >= 3.14", 6, 3.14, ">=", nil, true}, - {"not 6 < 3.14", 6, 3.14, "<", nil, false}, - {"not 6 <= 3.14", 6, 3.14, "<=", nil, false}, - {"'foo' > 'bar'", "foo", "bar", ">", nil, true}, - {"'foo' > bear", "foo", "NAME", ">", "bear", true}, - {"true > false", true, false, ">", nil, true}, - {"not true > 0", true, 0, ">", nil, false}, - {"not 'true' == true", "true", true, "==", nil, false}, - {"[]byte('a') < []byte('b')", []byte("a"), []byte("b"), "<", nil, true}, - {"nil == nil", nil, nil, "==", nil, true}, - {"nil == []byte(nil)", nil, []byte(nil), "==", nil, true}, + {name: "literals match", l: "hello", r: "hello", op: "==", want: true}, + {name: "literals don't match", l: "hello", r: "goodbye", op: "!=", want: true}, + {name: "path expression matches", l: "NAME", r: "bear", op: "==", item: "bear", want: true}, + {name: "path expression not matches", l: "NAME", r: "cat", op: "!=", item: "bear", want: true}, + {name: "compare Enum to int", l: "TEST_ENUM", r: 0, op: "==", want: true}, + {name: "compare int to Enum", l: 2, r: "TEST_ENUM_TWO", op: "==", want: true}, + {name: "2 > Enum 0", l: 2, r: "TEST_ENUM", op: ">", want: true}, + {name: "not 2 < Enum 0", l: 2, r: "TEST_ENUM", op: "<"}, + {name: "not 6 == 3.14", l: 6, r: 3.14, op: "=="}, + {name: "6 != 3.14", l: 6, r: 3.14, op: "!=", want: true}, + {name: "6 > 3.14", l: 6, r: 3.14, op: ">", want: true}, + {name: "6 >= 3.14", l: 6, r: 3.14, op: ">=", want: true}, + {name: "not 6 < 3.14", l: 6, r: 3.14, op: "<"}, + {name: "not 6 <= 3.14", l: 6, r: 3.14, op: "<="}, + {name: "'foo' > 'bar'", l: "foo", r: "bar", op: ">", want: true}, + {name: "'foo' > bear", l: "foo", r: "NAME", op: ">", item: "bear", want: true}, + {name: "true > false", l: true, r: false, op: ">", want: true}, + {name: "not true > 0", l: true, r: 0, op: ">"}, + {name: "not 'true' == true", l: "true", r: true, op: "=="}, + {name: "[]byte('a') < []byte('b')", l: []byte("a"), r: []byte("b"), op: "<", want: true}, + {name: "nil == nil", op: "==", want: true}, + {name: "nil == []byte(nil)", r: []byte(nil), op: "==", want: true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { comp := comparison(tt.l, tt.r, tt.op) evaluate, err := p.newComparisonEvaluator(comp) assert.NoError(t, err) - assert.Equal(t, tt.want, evaluate(ottltest.TestTransformContext{ - Item: tt.item, - })) + assert.Equal(t, tt.want, evaluate(tt.item)) }) } } @@ -353,9 +351,7 @@ func Test_newBooleanExpressionEvaluator(t *testing.T) { t.Run(tt.name, func(t *testing.T) { evaluate, err := p.newBooleanExpressionEvaluator(tt.expr) assert.NoError(t, err) - assert.Equal(t, tt.want, evaluate(ottltest.TestTransformContext{ - Item: nil, - })) + assert.Equal(t, tt.want, evaluate(nil)) }) } } diff --git a/pkg/ottl/compare.go b/pkg/ottl/compare.go index 7ab2ebff9d959..98ebf43f7c6ac 100644 --- a/pkg/ottl/compare.go +++ b/pkg/ottl/compare.go @@ -28,7 +28,7 @@ import ( // invalidComparison returns false for everything except NE (where it returns true to indicate that the // objects were definitely not equivalent). // It also gives us an opportunity to log something. -func (p *Parser) invalidComparison(msg string, op CompareOp) bool { +func (p *Parser[K]) invalidComparison(msg string, op CompareOp) bool { p.telemetrySettings.Logger.Debug(msg, zap.Any("op", op)) return op == NE } @@ -92,7 +92,7 @@ func compareBytes(a []byte, b []byte, op CompareOp) bool { } } -func (p *Parser) compareBool(a bool, b any, op CompareOp) bool { +func (p *Parser[K]) compareBool(a bool, b any, op CompareOp) bool { switch v := b.(type) { case bool: return compareBools(a, v, op) @@ -101,7 +101,7 @@ func (p *Parser) compareBool(a bool, b any, op CompareOp) bool { } } -func (p *Parser) compareString(a string, b any, op CompareOp) bool { +func (p *Parser[K]) compareString(a string, b any, op CompareOp) bool { switch v := b.(type) { case string: return comparePrimitives(a, v, op) @@ -110,7 +110,7 @@ func (p *Parser) compareString(a string, b any, op CompareOp) bool { } } -func (p *Parser) compareByte(a []byte, b any, op CompareOp) bool { +func (p *Parser[K]) compareByte(a []byte, b any, op CompareOp) bool { switch v := b.(type) { case nil: return op == NE @@ -124,7 +124,7 @@ func (p *Parser) compareByte(a []byte, b any, op CompareOp) bool { } } -func (p *Parser) compareInt64(a int64, b any, op CompareOp) bool { +func (p *Parser[K]) compareInt64(a int64, b any, op CompareOp) bool { switch v := b.(type) { case int64: return comparePrimitives(a, v, op) @@ -135,7 +135,7 @@ func (p *Parser) compareInt64(a int64, b any, op CompareOp) bool { } } -func (p *Parser) compareFloat64(a float64, b any, op CompareOp) bool { +func (p *Parser[K]) compareFloat64(a float64, b any, op CompareOp) bool { switch v := b.(type) { case int64: return comparePrimitives(a, float64(v), op) @@ -148,7 +148,7 @@ func (p *Parser) compareFloat64(a float64, b any, op CompareOp) bool { // a and b are the return values from a Getter; we try to compare them // according to the given operator. -func (p *Parser) compare(a any, b any, op CompareOp) bool { +func (p *Parser[K]) compare(a any, b any, op CompareOp) bool { // nils are equal to each other and never equal to anything else, // so if they're both nil, report equality. if a == nil && b == nil { diff --git a/pkg/ottl/compare_test.go b/pkg/ottl/compare_test.go index b6ef74c0459ac..14c4abcffae35 100644 --- a/pkg/ottl/compare_test.go +++ b/pkg/ottl/compare_test.go @@ -116,7 +116,7 @@ func Test_compare(t *testing.T) { for _, tt := range tests { for _, op := range ops { t.Run(fmt.Sprintf("%s %v", tt.name, op), func(t *testing.T) { - p := NewParser(nil, nil, nil, componenttest.NewNopTelemetrySettings()) + p := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) if got := p.compare(tt.a, tt.b, op); got != tt.want[op] { t.Errorf("compare(%v, %v, %v) = %v, want %v", tt.a, tt.b, op, got, tt.want[op]) } @@ -125,70 +125,113 @@ func Test_compare(t *testing.T) { } } -var testParser = NewParser(nil, nil, nil, componenttest.NewNopTelemetrySettings()) - // Benchmarks -- these benchmarks compare the performance of comparisons of a variety of data types. // It's not attempting to be exhaustive, but again, it hits most of the major types and combinations. // The summary is that they're pretty fast; all the calls to compare are 12 ns/op or less on a 2019 intel // mac pro laptop, and none of them have any allocations. func BenchmarkCompareEQInt64(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(i64a, i64b, EQ) } } func BenchmarkCompareEQFloat(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(f64a, f64b, EQ) } } + func BenchmarkCompareEQString(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(sa, sb, EQ) } } + func BenchmarkCompareEQPString(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(&sa, &sb, EQ) } } + func BenchmarkCompareEQBytes(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(ba, bb, EQ) } } + func BenchmarkCompareEQNil(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(nil, nil, EQ) } } + func BenchmarkCompareNEInt(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(i64a, i64b, NE) } } func BenchmarkCompareNEFloat(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(f64a, f64b, NE) } } + func BenchmarkCompareNEString(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(sa, sb, NE) } } + func BenchmarkCompareLTFloat(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(f64a, f64b, LT) } } + func BenchmarkCompareLTString(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(sa, sb, LT) } } + func BenchmarkCompareLTNil(b *testing.B) { + testParser := NewParser[interface{}](nil, nil, nil, componenttest.NewNopTelemetrySettings()) + b.ReportAllocs() + b.ResetTimer() for i := 0; i < b.N; i++ { testParser.compare(nil, nil, LT) } diff --git a/pkg/ottl/contexts/internal/ottlcommon/resource.go b/pkg/ottl/contexts/internal/ottlcommon/resource.go index 22244d360c129..54ea2ade79d3b 100644 --- a/pkg/ottl/contexts/internal/ottlcommon/resource.go +++ b/pkg/ottl/contexts/internal/ottlcommon/resource.go @@ -22,30 +22,34 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ResourcePathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { +type ResourceContext interface { + GetResource() pcommon.Resource +} + +func ResourcePathGetSetter[K ResourceContext](path []ottl.Field) (ottl.GetSetter[K], error) { if len(path) == 0 { - return accessResource(), nil + return accessResource[K](), nil } switch path[0].Name { case "attributes": mapKey := path[0].MapKey if mapKey == nil { - return accessResourceAttributes(), nil + return accessResourceAttributes[K](), nil } - return accessResourceAttributesKey(mapKey), nil + return accessResourceAttributesKey[K](mapKey), nil case "dropped_attributes_count": - return accessDroppedAttributesCount(), nil + return accessDroppedAttributesCount[K](), nil } return nil, fmt.Errorf("invalid resource path expression %v", path) } -func accessResource() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessResource[K ResourceContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetResource() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if newRes, ok := val.(pcommon.Resource); ok { newRes.CopyTo(ctx.GetResource()) } @@ -53,12 +57,12 @@ func accessResource() ottl.StandardGetSetter { } } -func accessResourceAttributes() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessResourceAttributes[K ResourceContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetResource().Attributes() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if attrs, ok := val.(pcommon.Map); ok { attrs.CopyTo(ctx.GetResource().Attributes()) } @@ -66,23 +70,23 @@ func accessResourceAttributes() ottl.StandardGetSetter { } } -func accessResourceAttributesKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessResourceAttributesKey[K ResourceContext](mapKey *string) ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return GetMapValue(ctx.GetResource().Attributes(), *mapKey) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { SetMapValue(ctx.GetResource().Attributes(), *mapKey, val) }, } } -func accessDroppedAttributesCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessDroppedAttributesCount[K ResourceContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return int64(ctx.GetResource().DroppedAttributesCount()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if i, ok := val.(int64); ok { ctx.GetResource().SetDroppedAttributesCount(uint32(i)) } diff --git a/pkg/ottl/contexts/internal/ottlcommon/resource_test.go b/pkg/ottl/contexts/internal/ottlcommon/resource_test.go index ea6e0a829fcf7..39b40e9aecdb5 100644 --- a/pkg/ottl/contexts/internal/ottlcommon/resource_test.go +++ b/pkg/ottl/contexts/internal/ottlcommon/resource_test.go @@ -230,7 +230,7 @@ func TestResourcePathGetSetter(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - accessor, err := ResourcePathGetSetter(tt.path) + accessor, err := ResourcePathGetSetter[*resourceContext](tt.path) assert.NoError(t, err) resource := createResource() @@ -289,18 +289,10 @@ type resourceContext struct { resource pcommon.Resource } -func (r *resourceContext) GetItem() interface{} { - return nil -} - -func (r *resourceContext) GetInstrumentationScope() pcommon.InstrumentationScope { - return pcommon.InstrumentationScope{} -} - func (r *resourceContext) GetResource() pcommon.Resource { return r.resource } -func newResourceContext(resource pcommon.Resource) ottl.TransformContext { +func newResourceContext(resource pcommon.Resource) *resourceContext { return &resourceContext{resource: resource} } diff --git a/pkg/ottl/contexts/internal/ottlcommon/scope.go b/pkg/ottl/contexts/internal/ottlcommon/scope.go index fd82b8b29fb6f..a77fe66d9851e 100644 --- a/pkg/ottl/contexts/internal/ottlcommon/scope.go +++ b/pkg/ottl/contexts/internal/ottlcommon/scope.go @@ -22,33 +22,37 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ScopePathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { +type InstrumentationScopeContext interface { + GetInstrumentationScope() pcommon.InstrumentationScope +} + +func ScopePathGetSetter[K InstrumentationScopeContext](path []ottl.Field) (ottl.GetSetter[K], error) { if len(path) == 0 { - return accessInstrumentationScope(), nil + return accessInstrumentationScope[K](), nil } switch path[0].Name { case "name": - return accessInstrumentationScopeName(), nil + return accessInstrumentationScopeName[K](), nil case "version": - return accessInstrumentationScopeVersion(), nil + return accessInstrumentationScopeVersion[K](), nil case "attributes": mapKey := path[0].MapKey if mapKey == nil { - return accessInstrumentationScopeAttributes(), nil + return accessInstrumentationScopeAttributes[K](), nil } - return accessInstrumentationScopeAttributesKey(mapKey), nil + return accessInstrumentationScopeAttributesKey[K](mapKey), nil } return nil, fmt.Errorf("invalid scope path expression %v", path) } -func accessInstrumentationScope() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessInstrumentationScope[K InstrumentationScopeContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetInstrumentationScope() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if newIl, ok := val.(pcommon.InstrumentationScope); ok { newIl.CopyTo(ctx.GetInstrumentationScope()) } @@ -56,12 +60,12 @@ func accessInstrumentationScope() ottl.StandardGetSetter { } } -func accessInstrumentationScopeAttributes() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessInstrumentationScopeAttributes[K InstrumentationScopeContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetInstrumentationScope().Attributes() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if attrs, ok := val.(pcommon.Map); ok { attrs.CopyTo(ctx.GetInstrumentationScope().Attributes()) } @@ -69,23 +73,23 @@ func accessInstrumentationScopeAttributes() ottl.StandardGetSetter { } } -func accessInstrumentationScopeAttributesKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessInstrumentationScopeAttributesKey[K InstrumentationScopeContext](mapKey *string) ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return GetMapValue(ctx.GetInstrumentationScope().Attributes(), *mapKey) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { SetMapValue(ctx.GetInstrumentationScope().Attributes(), *mapKey, val) }, } } -func accessInstrumentationScopeName() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessInstrumentationScopeName[K InstrumentationScopeContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetInstrumentationScope().Name() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if str, ok := val.(string); ok { ctx.GetInstrumentationScope().SetName(str) } @@ -93,12 +97,12 @@ func accessInstrumentationScopeName() ottl.StandardGetSetter { } } -func accessInstrumentationScopeVersion() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { +func accessInstrumentationScopeVersion[K InstrumentationScopeContext]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx K) interface{} { return ctx.GetInstrumentationScope().Version() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx K, val interface{}) { if str, ok := val.(string); ok { ctx.GetInstrumentationScope().SetVersion(str) } diff --git a/pkg/ottl/contexts/internal/ottlcommon/scope_test.go b/pkg/ottl/contexts/internal/ottlcommon/scope_test.go index 6f6c2a23a1923..7e36cd19b7371 100644 --- a/pkg/ottl/contexts/internal/ottlcommon/scope_test.go +++ b/pkg/ottl/contexts/internal/ottlcommon/scope_test.go @@ -247,7 +247,7 @@ func TestScopePathGetSetter(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - accessor, err := ScopePathGetSetter(tt.path) + accessor, err := ScopePathGetSetter[*instrumentationScopeContext](tt.path) assert.NoError(t, err) is := createInstrumentationScope() @@ -303,18 +303,10 @@ type instrumentationScopeContext struct { is pcommon.InstrumentationScope } -func (r *instrumentationScopeContext) GetItem() interface{} { - return nil -} - func (r *instrumentationScopeContext) GetInstrumentationScope() pcommon.InstrumentationScope { return r.is } -func (r *instrumentationScopeContext) GetResource() pcommon.Resource { - return pcommon.Resource{} -} - -func newInstrumentationScopeContext(is pcommon.InstrumentationScope) ottl.TransformContext { +func newInstrumentationScopeContext(is pcommon.InstrumentationScope) *instrumentationScopeContext { return &instrumentationScopeContext{is: is} } diff --git a/pkg/ottl/contexts/ottldatapoints/datapoints.go b/pkg/ottl/contexts/ottldatapoints/datapoints.go index 3066ab2e102d3..692e20857e1ae 100644 --- a/pkg/ottl/contexts/ottldatapoints/datapoints.go +++ b/pkg/ottl/contexts/ottldatapoints/datapoints.go @@ -26,6 +26,9 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ottlcommon" ) +var _ ottlcommon.ResourceContext = TransformContext{} +var _ ottlcommon.InstrumentationScopeContext = TransformContext{} + type TransformContext struct { dataPoint interface{} metric pmetric.Metric @@ -44,7 +47,7 @@ func NewTransformContext(dataPoint interface{}, metric pmetric.Metric, metrics p } } -func (ctx TransformContext) GetItem() interface{} { +func (ctx TransformContext) GetDataPoint() interface{} { return ctx.dataPoint } @@ -88,19 +91,19 @@ func ParseEnum(val *ottl.EnumSymbol) (*ottl.Enum, error) { return nil, fmt.Errorf("enum symbol not provided") } -func ParsePath(val *ottl.Path) (ottl.GetSetter, error) { +func ParsePath(val *ottl.Path) (ottl.GetSetter[TransformContext], error) { if val != nil && len(val.Fields) > 0 { return newPathGetSetter(val.Fields) } return nil, fmt.Errorf("bad path %v", val) } -func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { +func newPathGetSetter(path []ottl.Field) (ottl.GetSetter[TransformContext], error) { switch path[0].Name { case "resource": - return ottlcommon.ResourcePathGetSetter(path[1:]) + return ottlcommon.ResourcePathGetSetter[TransformContext](path[1:]) case "instrumentation_scope": - return ottlcommon.ScopePathGetSetter(path[1:]) + return ottlcommon.ScopePathGetSetter[TransformContext](path[1:]) case "metric": if len(path) == 1 { return accessMetric(), nil @@ -175,74 +178,74 @@ func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { return nil, fmt.Errorf("invalid path expression %v", path) } -func accessMetric() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.(TransformContext).GetMetric() +func accessMetric() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetMetric() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newMetric, ok := val.(pmetric.Metric); ok { - newMetric.CopyTo(ctx.(TransformContext).GetMetric()) + newMetric.CopyTo(ctx.GetMetric()) } }, } } -func accessMetricName() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.(TransformContext).GetMetric().Name() +func accessMetricName() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetMetric().Name() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.(TransformContext).GetMetric().SetName(str) + ctx.GetMetric().SetName(str) } }, } } -func accessMetricDescription() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.(TransformContext).GetMetric().Description() +func accessMetricDescription() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetMetric().Description() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.(TransformContext).GetMetric().SetDescription(str) + ctx.GetMetric().SetDescription(str) } }, } } -func accessMetricUnit() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.(TransformContext).GetMetric().Unit() +func accessMetricUnit() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetMetric().Unit() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.(TransformContext).GetMetric().SetUnit(str) + ctx.GetMetric().SetUnit(str) } }, } } -func accessMetricType() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.(TransformContext).GetMetric().Type()) +func accessMetricType() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetMetric().Type()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { // TODO Implement methods so correctly convert data types. // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/10130 }, } } -func accessMetricAggTemporality() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - metric := ctx.(TransformContext).GetMetric() +func accessMetricAggTemporality() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + metric := ctx.GetMetric() switch metric.Type() { case pmetric.MetricTypeSum: return int64(metric.Sum().AggregationTemporality()) @@ -253,9 +256,9 @@ func accessMetricAggTemporality() ottl.StandardGetSetter { } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newAggTemporality, ok := val.(int64); ok { - metric := ctx.(TransformContext).GetMetric() + metric := ctx.GetMetric() switch metric.Type() { case pmetric.MetricTypeSum: metric.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporality(newAggTemporality)) @@ -269,19 +272,19 @@ func accessMetricAggTemporality() ottl.StandardGetSetter { } } -func accessMetricIsMonotonic() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - metric := ctx.(TransformContext).GetMetric() +func accessMetricIsMonotonic() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + metric := ctx.GetMetric() switch metric.Type() { case pmetric.MetricTypeSum: return metric.Sum().IsMonotonic() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newIsMonotonic, ok := val.(bool); ok { - metric := ctx.(TransformContext).GetMetric() + metric := ctx.GetMetric() switch metric.Type() { case pmetric.MetricTypeSum: metric.Sum().SetIsMonotonic(newIsMonotonic) @@ -291,508 +294,508 @@ func accessMetricIsMonotonic() ottl.StandardGetSetter { } } -func accessAttributes() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessAttributes() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).Attributes() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).Attributes() case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).Attributes() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).Attributes() case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Attributes() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Attributes() case pmetric.SummaryDataPoint: - return ctx.GetItem().(pmetric.SummaryDataPoint).Attributes() + return ctx.GetDataPoint().(pmetric.SummaryDataPoint).Attributes() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - switch ctx.GetItem().(type) { + Setter: func(ctx TransformContext, val interface{}) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(pmetric.NumberDataPoint).Attributes()) + attrs.CopyTo(ctx.GetDataPoint().(pmetric.NumberDataPoint).Attributes()) } case pmetric.HistogramDataPoint: if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(pmetric.HistogramDataPoint).Attributes()) + attrs.CopyTo(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Attributes()) } case pmetric.ExponentialHistogramDataPoint: if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Attributes()) + attrs.CopyTo(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Attributes()) } case pmetric.SummaryDataPoint: if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(pmetric.SummaryDataPoint).Attributes()) + attrs.CopyTo(ctx.GetDataPoint().(pmetric.SummaryDataPoint).Attributes()) } } }, } } -func accessAttributesKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessAttributesKey(mapKey *string) ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ottlcommon.GetMapValue(ctx.GetItem().(pmetric.NumberDataPoint).Attributes(), *mapKey) + return ottlcommon.GetMapValue(ctx.GetDataPoint().(pmetric.NumberDataPoint).Attributes(), *mapKey) case pmetric.HistogramDataPoint: - return ottlcommon.GetMapValue(ctx.GetItem().(pmetric.HistogramDataPoint).Attributes(), *mapKey) + return ottlcommon.GetMapValue(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Attributes(), *mapKey) case pmetric.ExponentialHistogramDataPoint: - return ottlcommon.GetMapValue(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Attributes(), *mapKey) + return ottlcommon.GetMapValue(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Attributes(), *mapKey) case pmetric.SummaryDataPoint: - return ottlcommon.GetMapValue(ctx.GetItem().(pmetric.SummaryDataPoint).Attributes(), *mapKey) + return ottlcommon.GetMapValue(ctx.GetDataPoint().(pmetric.SummaryDataPoint).Attributes(), *mapKey) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - switch ctx.GetItem().(type) { + Setter: func(ctx TransformContext, val interface{}) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ottlcommon.SetMapValue(ctx.GetItem().(pmetric.NumberDataPoint).Attributes(), *mapKey, val) + ottlcommon.SetMapValue(ctx.GetDataPoint().(pmetric.NumberDataPoint).Attributes(), *mapKey, val) case pmetric.HistogramDataPoint: - ottlcommon.SetMapValue(ctx.GetItem().(pmetric.HistogramDataPoint).Attributes(), *mapKey, val) + ottlcommon.SetMapValue(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Attributes(), *mapKey, val) case pmetric.ExponentialHistogramDataPoint: - ottlcommon.SetMapValue(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Attributes(), *mapKey, val) + ottlcommon.SetMapValue(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Attributes(), *mapKey, val) case pmetric.SummaryDataPoint: - ottlcommon.SetMapValue(ctx.GetItem().(pmetric.SummaryDataPoint).Attributes(), *mapKey, val) + ottlcommon.SetMapValue(ctx.GetDataPoint().(pmetric.SummaryDataPoint).Attributes(), *mapKey, val) } }, } } -func accessStartTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessStartTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).StartTimestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).StartTimestamp().AsTime().UnixNano() case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).StartTimestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).StartTimestamp().AsTime().UnixNano() case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).StartTimestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).StartTimestamp().AsTime().UnixNano() case pmetric.SummaryDataPoint: - return ctx.GetItem().(pmetric.SummaryDataPoint).StartTimestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.SummaryDataPoint).StartTimestamp().AsTime().UnixNano() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newTime, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ctx.GetItem().(pmetric.NumberDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.NumberDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.SummaryDataPoint: - ctx.GetItem().(pmetric.SummaryDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.SummaryDataPoint).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) } } }, } } -func accessTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).Timestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).Timestamp().AsTime().UnixNano() case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).Timestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).Timestamp().AsTime().UnixNano() case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Timestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Timestamp().AsTime().UnixNano() case pmetric.SummaryDataPoint: - return ctx.GetItem().(pmetric.SummaryDataPoint).Timestamp().AsTime().UnixNano() + return ctx.GetDataPoint().(pmetric.SummaryDataPoint).Timestamp().AsTime().UnixNano() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newTime, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ctx.GetItem().(pmetric.NumberDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.NumberDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) case pmetric.SummaryDataPoint: - ctx.GetItem().(pmetric.SummaryDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) + ctx.GetDataPoint().(pmetric.SummaryDataPoint).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, newTime))) } } }, } } -func accessDoubleValue() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessDoubleValue() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).DoubleValue() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).DoubleValue() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newDouble, ok := val.(float64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ctx.GetItem().(pmetric.NumberDataPoint).SetDoubleValue(newDouble) + ctx.GetDataPoint().(pmetric.NumberDataPoint).SetDoubleValue(newDouble) } } }, } } -func accessIntValue() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessIntValue() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).IntValue() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).IntValue() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newInt, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ctx.GetItem().(pmetric.NumberDataPoint).SetIntValue(newInt) + ctx.GetDataPoint().(pmetric.NumberDataPoint).SetIntValue(newInt) } } }, } } -func accessExemplars() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessExemplars() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return ctx.GetItem().(pmetric.NumberDataPoint).Exemplars() + return ctx.GetDataPoint().(pmetric.NumberDataPoint).Exemplars() case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).Exemplars() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).Exemplars() case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Exemplars() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Exemplars() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newExemplars, ok := val.(pmetric.ExemplarSlice); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - newExemplars.CopyTo(ctx.GetItem().(pmetric.NumberDataPoint).Exemplars()) + newExemplars.CopyTo(ctx.GetDataPoint().(pmetric.NumberDataPoint).Exemplars()) case pmetric.HistogramDataPoint: - newExemplars.CopyTo(ctx.GetItem().(pmetric.HistogramDataPoint).Exemplars()) + newExemplars.CopyTo(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Exemplars()) case pmetric.ExponentialHistogramDataPoint: - newExemplars.CopyTo(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Exemplars()) + newExemplars.CopyTo(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Exemplars()) } } }, } } -func accessFlags() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessFlags() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - return int64(ctx.GetItem().(pmetric.NumberDataPoint).Flags()) + return int64(ctx.GetDataPoint().(pmetric.NumberDataPoint).Flags()) case pmetric.HistogramDataPoint: - return int64(ctx.GetItem().(pmetric.HistogramDataPoint).Flags()) + return int64(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Flags()) case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Flags()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Flags()) case pmetric.SummaryDataPoint: - return int64(ctx.GetItem().(pmetric.SummaryDataPoint).Flags()) + return int64(ctx.GetDataPoint().(pmetric.SummaryDataPoint).Flags()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newFlags, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.NumberDataPoint: - ctx.GetItem().(pmetric.NumberDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) + ctx.GetDataPoint().(pmetric.NumberDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) case pmetric.SummaryDataPoint: - ctx.GetItem().(pmetric.SummaryDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) + ctx.GetDataPoint().(pmetric.SummaryDataPoint).SetFlags(pmetric.MetricDataPointFlags(newFlags)) } } }, } } -func accessCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - return int64(ctx.GetItem().(pmetric.HistogramDataPoint).Count()) + return int64(ctx.GetDataPoint().(pmetric.HistogramDataPoint).Count()) case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Count()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Count()) case pmetric.SummaryDataPoint: - return int64(ctx.GetItem().(pmetric.SummaryDataPoint).Count()) + return int64(ctx.GetDataPoint().(pmetric.SummaryDataPoint).Count()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newCount, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).SetCount(uint64(newCount)) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).SetCount(uint64(newCount)) case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetCount(uint64(newCount)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetCount(uint64(newCount)) case pmetric.SummaryDataPoint: - ctx.GetItem().(pmetric.SummaryDataPoint).SetCount(uint64(newCount)) + ctx.GetDataPoint().(pmetric.SummaryDataPoint).SetCount(uint64(newCount)) } } }, } } -func accessSum() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessSum() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).Sum() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).Sum() case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Sum() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Sum() case pmetric.SummaryDataPoint: - return ctx.GetItem().(pmetric.SummaryDataPoint).Sum() + return ctx.GetDataPoint().(pmetric.SummaryDataPoint).Sum() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newSum, ok := val.(float64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).SetSum(newSum) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).SetSum(newSum) case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetSum(newSum) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetSum(newSum) case pmetric.SummaryDataPoint: - ctx.GetItem().(pmetric.SummaryDataPoint).SetSum(newSum) + ctx.GetDataPoint().(pmetric.SummaryDataPoint).SetSum(newSum) } } }, } } -func accessExplicitBounds() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessExplicitBounds() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).ExplicitBounds().AsRaw() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).ExplicitBounds().AsRaw() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newExplicitBounds, ok := val.([]float64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).ExplicitBounds().FromRaw(newExplicitBounds) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).ExplicitBounds().FromRaw(newExplicitBounds) } } }, } } -func accessBucketCounts() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessBucketCounts() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - return ctx.GetItem().(pmetric.HistogramDataPoint).BucketCounts().AsRaw() + return ctx.GetDataPoint().(pmetric.HistogramDataPoint).BucketCounts().AsRaw() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newBucketCount, ok := val.([]uint64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.HistogramDataPoint: - ctx.GetItem().(pmetric.HistogramDataPoint).BucketCounts().FromRaw(newBucketCount) + ctx.GetDataPoint().(pmetric.HistogramDataPoint).BucketCounts().FromRaw(newBucketCount) } } }, } } -func accessScale() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessScale() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Scale()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Scale()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newScale, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetScale(int32(newScale)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetScale(int32(newScale)) } } }, } } -func accessZeroCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessZeroCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).ZeroCount()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).ZeroCount()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newZeroCount, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).SetZeroCount(uint64(newZeroCount)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).SetZeroCount(uint64(newZeroCount)) } } }, } } -func accessPositive() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessPositive() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newPositive, ok := val.(pmetric.Buckets); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - newPositive.CopyTo(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive()) + newPositive.CopyTo(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive()) } } }, } } -func accessPositiveOffset() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessPositiveOffset() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive().Offset()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive().Offset()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newPositiveOffset, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive().SetOffset(int32(newPositiveOffset)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive().SetOffset(int32(newPositiveOffset)) } } }, } } -func accessPositiveBucketCounts() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessPositiveBucketCounts() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive().BucketCounts().AsRaw() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive().BucketCounts().AsRaw() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newPositiveBucketCounts, ok := val.([]uint64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Positive().BucketCounts().FromRaw(newPositiveBucketCounts) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Positive().BucketCounts().FromRaw(newPositiveBucketCounts) } } }, } } -func accessNegative() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessNegative() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newNegative, ok := val.(pmetric.Buckets); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - newNegative.CopyTo(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative()) + newNegative.CopyTo(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative()) } } }, } } -func accessNegativeOffset() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessNegativeOffset() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return int64(ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative().Offset()) + return int64(ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative().Offset()) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newNegativeOffset, ok := val.(int64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative().SetOffset(int32(newNegativeOffset)) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative().SetOffset(int32(newNegativeOffset)) } } }, } } -func accessNegativeBucketCounts() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessNegativeBucketCounts() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - return ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative().BucketCounts().AsRaw() + return ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative().BucketCounts().AsRaw() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newNegativeBucketCounts, ok := val.([]uint64); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.ExponentialHistogramDataPoint: - ctx.GetItem().(pmetric.ExponentialHistogramDataPoint).Negative().BucketCounts().FromRaw(newNegativeBucketCounts) + ctx.GetDataPoint().(pmetric.ExponentialHistogramDataPoint).Negative().BucketCounts().FromRaw(newNegativeBucketCounts) } } }, } } -func accessQuantileValues() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - switch ctx.GetItem().(type) { +func accessQuantileValues() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + switch ctx.GetDataPoint().(type) { case pmetric.SummaryDataPoint: - return ctx.GetItem().(pmetric.SummaryDataPoint).QuantileValues() + return ctx.GetDataPoint().(pmetric.SummaryDataPoint).QuantileValues() } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newQuantileValues, ok := val.(pmetric.ValueAtQuantileSlice); ok { - switch ctx.GetItem().(type) { + switch ctx.GetDataPoint().(type) { case pmetric.SummaryDataPoint: - newQuantileValues.CopyTo(ctx.GetItem().(pmetric.SummaryDataPoint).QuantileValues()) + newQuantileValues.CopyTo(ctx.GetDataPoint().(pmetric.SummaryDataPoint).QuantileValues()) } } }, diff --git a/pkg/ottl/contexts/ottllogs/logs.go b/pkg/ottl/contexts/ottllogs/logs.go index ba2ad7526a657..a7af924093ba1 100644 --- a/pkg/ottl/contexts/ottllogs/logs.go +++ b/pkg/ottl/contexts/ottllogs/logs.go @@ -27,29 +27,32 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ottlcommon" ) -type transformContext struct { +var _ ottlcommon.ResourceContext = TransformContext{} +var _ ottlcommon.InstrumentationScopeContext = TransformContext{} + +type TransformContext struct { logRecord plog.LogRecord instrumentationScope pcommon.InstrumentationScope resource pcommon.Resource } -func NewTransformContext(logRecord plog.LogRecord, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) ottl.TransformContext { - return transformContext{ +func NewTransformContext(logRecord plog.LogRecord, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) TransformContext { + return TransformContext{ logRecord: logRecord, instrumentationScope: instrumentationScope, resource: resource, } } -func (ctx transformContext) GetItem() interface{} { +func (ctx TransformContext) GetLogRecord() plog.LogRecord { return ctx.logRecord } -func (ctx transformContext) GetInstrumentationScope() pcommon.InstrumentationScope { +func (ctx TransformContext) GetInstrumentationScope() pcommon.InstrumentationScope { return ctx.instrumentationScope } -func (ctx transformContext) GetResource() pcommon.Resource { +func (ctx TransformContext) GetResource() pcommon.Resource { return ctx.resource } @@ -91,19 +94,19 @@ func ParseEnum(val *ottl.EnumSymbol) (*ottl.Enum, error) { return nil, fmt.Errorf("enum symbol not provided") } -func ParsePath(val *ottl.Path) (ottl.GetSetter, error) { +func ParsePath(val *ottl.Path) (ottl.GetSetter[TransformContext], error) { if val != nil && len(val.Fields) > 0 { return newPathGetSetter(val.Fields) } return nil, fmt.Errorf("bad path %v", val) } -func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { +func newPathGetSetter(path []ottl.Field) (ottl.GetSetter[TransformContext], error) { switch path[0].Name { case "resource": - return ottlcommon.ResourcePathGetSetter(path[1:]) + return ottlcommon.ResourcePathGetSetter[TransformContext](path[1:]) case "instrumentation_scope": - return ottlcommon.ScopePathGetSetter(path[1:]) + return ottlcommon.ScopePathGetSetter[TransformContext](path[1:]) case "time_unix_nano": return accessTimeUnixNano(), nil case "observed_time_unix_nano": @@ -143,169 +146,169 @@ func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { return nil, fmt.Errorf("invalid path expression %v", path) } -func accessTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).Timestamp().AsTime().UnixNano() +func accessTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().Timestamp().AsTime().UnixNano() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(plog.LogRecord).SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) + ctx.GetLogRecord().SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) } }, } } -func accessObservedTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).ObservedTimestamp().AsTime().UnixNano() +func accessObservedTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().ObservedTimestamp().AsTime().UnixNano() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(plog.LogRecord).SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) + ctx.GetLogRecord().SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) } }, } } -func accessSeverityNumber() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(plog.LogRecord).SeverityNumber()) +func accessSeverityNumber() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetLogRecord().SeverityNumber()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(plog.LogRecord).SetSeverityNumber(plog.SeverityNumber(i)) + ctx.GetLogRecord().SetSeverityNumber(plog.SeverityNumber(i)) } }, } } -func accessSeverityText() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).SeverityText() +func accessSeverityText() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().SeverityText() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if s, ok := val.(string); ok { - ctx.GetItem().(plog.LogRecord).SetSeverityText(s) + ctx.GetLogRecord().SetSeverityText(s) } }, } } -func accessBody() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ottlcommon.GetValue(ctx.GetItem().(plog.LogRecord).Body()) +func accessBody() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ottlcommon.GetValue(ctx.GetLogRecord().Body()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ottlcommon.SetValue(ctx.GetItem().(plog.LogRecord).Body(), val) + Setter: func(ctx TransformContext, val interface{}) { + ottlcommon.SetValue(ctx.GetLogRecord().Body(), val) }, } } -func accessAttributes() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).Attributes() +func accessAttributes() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().Attributes() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(plog.LogRecord).Attributes()) + attrs.CopyTo(ctx.GetLogRecord().Attributes()) } }, } } -func accessAttributesKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ottlcommon.GetMapValue(ctx.GetItem().(plog.LogRecord).Attributes(), *mapKey) +func accessAttributesKey(mapKey *string) ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ottlcommon.GetMapValue(ctx.GetLogRecord().Attributes(), *mapKey) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ottlcommon.SetMapValue(ctx.GetItem().(plog.LogRecord).Attributes(), *mapKey, val) + Setter: func(ctx TransformContext, val interface{}) { + ottlcommon.SetMapValue(ctx.GetLogRecord().Attributes(), *mapKey, val) }, } } -func accessDroppedAttributesCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(plog.LogRecord).DroppedAttributesCount()) +func accessDroppedAttributesCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetLogRecord().DroppedAttributesCount()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(plog.LogRecord).SetDroppedAttributesCount(uint32(i)) + ctx.GetLogRecord().SetDroppedAttributesCount(uint32(i)) } }, } } -func accessFlags() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(plog.LogRecord).Flags()) +func accessFlags() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetLogRecord().Flags()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(plog.LogRecord).SetFlags(plog.LogRecordFlags(i)) + ctx.GetLogRecord().SetFlags(plog.LogRecordFlags(i)) } }, } } -func accessTraceID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).TraceID() +func accessTraceID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().TraceID() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newTraceID, ok := val.(pcommon.TraceID); ok { - ctx.GetItem().(plog.LogRecord).SetTraceID(newTraceID) + ctx.GetLogRecord().SetTraceID(newTraceID) } }, } } -func accessStringTraceID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).TraceID().HexString() +func accessStringTraceID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().TraceID().HexString() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { if traceID, err := parseTraceID(str); err == nil { - ctx.GetItem().(plog.LogRecord).SetTraceID(traceID) + ctx.GetLogRecord().SetTraceID(traceID) } } }, } } -func accessSpanID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).SpanID() +func accessSpanID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().SpanID() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newSpanID, ok := val.(pcommon.SpanID); ok { - ctx.GetItem().(plog.LogRecord).SetSpanID(newSpanID) + ctx.GetLogRecord().SetSpanID(newSpanID) } }, } } -func accessStringSpanID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(plog.LogRecord).SpanID().HexString() +func accessStringSpanID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetLogRecord().SpanID().HexString() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { if spanID, err := parseSpanID(str); err == nil { - ctx.GetItem().(plog.LogRecord).SetSpanID(spanID) + ctx.GetLogRecord().SetSpanID(spanID) } } }, diff --git a/pkg/ottl/contexts/ottltraces/traces.go b/pkg/ottl/contexts/ottltraces/traces.go index 5e80f35ce850e..67dff7b824fce 100644 --- a/pkg/ottl/contexts/ottltraces/traces.go +++ b/pkg/ottl/contexts/ottltraces/traces.go @@ -28,29 +28,32 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ottlcommon" ) -type transformContext struct { +var _ ottlcommon.ResourceContext = TransformContext{} +var _ ottlcommon.InstrumentationScopeContext = TransformContext{} + +type TransformContext struct { span ptrace.Span instrumentationScope pcommon.InstrumentationScope resource pcommon.Resource } -func NewTransformContext(span ptrace.Span, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) ottl.TransformContext { - return transformContext{ +func NewTransformContext(span ptrace.Span, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) TransformContext { + return TransformContext{ span: span, instrumentationScope: instrumentationScope, resource: resource, } } -func (ctx transformContext) GetItem() interface{} { +func (ctx TransformContext) GetSpan() ptrace.Span { return ctx.span } -func (ctx transformContext) GetInstrumentationScope() pcommon.InstrumentationScope { +func (ctx TransformContext) GetInstrumentationScope() pcommon.InstrumentationScope { return ctx.instrumentationScope } -func (ctx transformContext) GetResource() pcommon.Resource { +func (ctx TransformContext) GetResource() pcommon.Resource { return ctx.resource } @@ -76,19 +79,19 @@ func ParseEnum(val *ottl.EnumSymbol) (*ottl.Enum, error) { return nil, fmt.Errorf("enum symbol not provided") } -func ParsePath(val *ottl.Path) (ottl.GetSetter, error) { +func ParsePath(val *ottl.Path) (ottl.GetSetter[TransformContext], error) { if val != nil && len(val.Fields) > 0 { return newPathGetSetter(val.Fields) } return nil, fmt.Errorf("bad path %v", val) } -func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { +func newPathGetSetter(path []ottl.Field) (ottl.GetSetter[TransformContext], error) { switch path[0].Name { case "resource": - return ottlcommon.ResourcePathGetSetter(path[1:]) + return ottlcommon.ResourcePathGetSetter[TransformContext](path[1:]) case "instrumentation_library": - return ottlcommon.ScopePathGetSetter(path[1:]) + return ottlcommon.ScopePathGetSetter[TransformContext](path[1:]) case "trace_id": if len(path) == 1 { return accessTraceID(), nil @@ -152,88 +155,88 @@ func newPathGetSetter(path []ottl.Field) (ottl.GetSetter, error) { return nil, fmt.Errorf("invalid path expression %v", path) } -func accessTraceID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).TraceID() +func accessTraceID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().TraceID() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newTraceID, ok := val.(pcommon.TraceID); ok { - ctx.GetItem().(ptrace.Span).SetTraceID(newTraceID) + ctx.GetSpan().SetTraceID(newTraceID) } }, } } -func accessStringTraceID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).TraceID().HexString() +func accessStringTraceID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().TraceID().HexString() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { if traceID, err := parseTraceID(str); err == nil { - ctx.GetItem().(ptrace.Span).SetTraceID(traceID) + ctx.GetSpan().SetTraceID(traceID) } } }, } } -func accessSpanID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).SpanID() +func accessSpanID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().SpanID() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newSpanID, ok := val.(pcommon.SpanID); ok { - ctx.GetItem().(ptrace.Span).SetSpanID(newSpanID) + ctx.GetSpan().SetSpanID(newSpanID) } }, } } -func accessStringSpanID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).SpanID().HexString() +func accessStringSpanID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().SpanID().HexString() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { if spanID, err := parseSpanID(str); err == nil { - ctx.GetItem().(ptrace.Span).SetSpanID(spanID) + ctx.GetSpan().SetSpanID(spanID) } } }, } } -func accessTraceState() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).TraceState().AsRaw() +func accessTraceState() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().TraceState().AsRaw() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.GetItem().(ptrace.Span).TraceState().FromRaw(str) + ctx.GetSpan().TraceState().FromRaw(str) } }, } } -func accessTraceStateKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - if ts, err := trace.ParseTraceState(ctx.GetItem().(ptrace.Span).TraceState().AsRaw()); err == nil { +func accessTraceStateKey(mapKey *string) ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + if ts, err := trace.ParseTraceState(ctx.GetSpan().TraceState().AsRaw()); err == nil { return ts.Get(*mapKey) } return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - if ts, err := trace.ParseTraceState(ctx.GetItem().(ptrace.Span).TraceState().AsRaw()); err == nil { + if ts, err := trace.ParseTraceState(ctx.GetSpan().TraceState().AsRaw()); err == nil { if updated, err := ts.Insert(*mapKey, str); err == nil { - ctx.GetItem().(ptrace.Span).TraceState().FromRaw(updated.String()) + ctx.GetSpan().TraceState().FromRaw(updated.String()) } } } @@ -241,200 +244,200 @@ func accessTraceStateKey(mapKey *string) ottl.StandardGetSetter { } } -func accessParentSpanID() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).ParentSpanID() +func accessParentSpanID() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().ParentSpanID() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if newParentSpanID, ok := val.(pcommon.SpanID); ok { - ctx.GetItem().(ptrace.Span).SetParentSpanID(newParentSpanID) + ctx.GetSpan().SetParentSpanID(newParentSpanID) } }, } } -func accessName() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Name() +func accessName() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Name() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.GetItem().(ptrace.Span).SetName(str) + ctx.GetSpan().SetName(str) } }, } } -func accessKind() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(ptrace.Span).Kind()) +func accessKind() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetSpan().Kind()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetKind(ptrace.SpanKind(i)) + ctx.GetSpan().SetKind(ptrace.SpanKind(i)) } }, } } -func accessStartTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).StartTimestamp().AsTime().UnixNano() +func accessStartTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().StartTimestamp().AsTime().UnixNano() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) + ctx.GetSpan().SetStartTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) } }, } } -func accessEndTimeUnixNano() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).EndTimestamp().AsTime().UnixNano() +func accessEndTimeUnixNano() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().EndTimestamp().AsTime().UnixNano() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetEndTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) + ctx.GetSpan().SetEndTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i))) } }, } } -func accessAttributes() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Attributes() +func accessAttributes() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Attributes() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if attrs, ok := val.(pcommon.Map); ok { - attrs.CopyTo(ctx.GetItem().(ptrace.Span).Attributes()) + attrs.CopyTo(ctx.GetSpan().Attributes()) } }, } } -func accessAttributesKey(mapKey *string) ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ottlcommon.GetMapValue(ctx.GetItem().(ptrace.Span).Attributes(), *mapKey) +func accessAttributesKey(mapKey *string) ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ottlcommon.GetMapValue(ctx.GetSpan().Attributes(), *mapKey) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ottlcommon.SetMapValue(ctx.GetItem().(ptrace.Span).Attributes(), *mapKey, val) + Setter: func(ctx TransformContext, val interface{}) { + ottlcommon.SetMapValue(ctx.GetSpan().Attributes(), *mapKey, val) }, } } -func accessDroppedAttributesCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(ptrace.Span).DroppedAttributesCount()) +func accessDroppedAttributesCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetSpan().DroppedAttributesCount()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetDroppedAttributesCount(uint32(i)) + ctx.GetSpan().SetDroppedAttributesCount(uint32(i)) } }, } } -func accessEvents() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Events() +func accessEvents() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Events() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if slc, ok := val.(ptrace.SpanEventSlice); ok { - ctx.GetItem().(ptrace.Span).Events().RemoveIf(func(event ptrace.SpanEvent) bool { + ctx.GetSpan().Events().RemoveIf(func(event ptrace.SpanEvent) bool { return true }) - slc.CopyTo(ctx.GetItem().(ptrace.Span).Events()) + slc.CopyTo(ctx.GetSpan().Events()) } }, } } -func accessDroppedEventsCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(ptrace.Span).DroppedEventsCount()) +func accessDroppedEventsCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetSpan().DroppedEventsCount()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetDroppedEventsCount(uint32(i)) + ctx.GetSpan().SetDroppedEventsCount(uint32(i)) } }, } } -func accessLinks() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Links() +func accessLinks() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Links() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if slc, ok := val.(ptrace.SpanLinkSlice); ok { - ctx.GetItem().(ptrace.Span).Links().RemoveIf(func(event ptrace.SpanLink) bool { + ctx.GetSpan().Links().RemoveIf(func(event ptrace.SpanLink) bool { return true }) - slc.CopyTo(ctx.GetItem().(ptrace.Span).Links()) + slc.CopyTo(ctx.GetSpan().Links()) } }, } } -func accessDroppedLinksCount() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(ptrace.Span).DroppedLinksCount()) +func accessDroppedLinksCount() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetSpan().DroppedLinksCount()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).SetDroppedLinksCount(uint32(i)) + ctx.GetSpan().SetDroppedLinksCount(uint32(i)) } }, } } -func accessStatus() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Status() +func accessStatus() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Status() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if status, ok := val.(ptrace.SpanStatus); ok { - status.CopyTo(ctx.GetItem().(ptrace.Span).Status()) + status.CopyTo(ctx.GetSpan().Status()) } }, } } -func accessStatusCode() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return int64(ctx.GetItem().(ptrace.Span).Status().Code()) +func accessStatusCode() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return int64(ctx.GetSpan().Status().Code()) }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if i, ok := val.(int64); ok { - ctx.GetItem().(ptrace.Span).Status().SetCode(ptrace.StatusCode(i)) + ctx.GetSpan().Status().SetCode(ptrace.StatusCode(i)) } }, } } -func accessStatusMessage() ottl.StandardGetSetter { - return ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(ptrace.Span).Status().Message() +func accessStatusMessage() ottl.StandardGetSetter[TransformContext] { + return ottl.StandardGetSetter[TransformContext]{ + Getter: func(ctx TransformContext) interface{} { + return ctx.GetSpan().Status().Message() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx TransformContext, val interface{}) { if str, ok := val.(string); ok { - ctx.GetItem().(ptrace.Span).Status().SetMessage(str) + ctx.GetSpan().Status().SetMessage(str) } }, } diff --git a/pkg/ottl/expression.go b/pkg/ottl/expression.go index d142fd8777370..e2a0cec08de15 100644 --- a/pkg/ottl/expression.go +++ b/pkg/ottl/expression.go @@ -16,79 +16,71 @@ package ottl // import "github.com/open-telemetry/opentelemetry-collector-contri import ( "fmt" - - "go.opentelemetry.io/collector/pdata/pcommon" ) -type TransformContext interface { - GetItem() interface{} - GetInstrumentationScope() pcommon.InstrumentationScope - GetResource() pcommon.Resource -} - -type ExprFunc func(ctx TransformContext) interface{} +type ExprFunc[K any] func(ctx K) interface{} -type Getter interface { - Get(ctx TransformContext) interface{} +type Getter[K any] interface { + Get(ctx K) interface{} } -type Setter interface { - Set(ctx TransformContext, val interface{}) +type Setter[K any] interface { + Set(ctx K, val interface{}) } -type GetSetter interface { - Getter - Setter +type GetSetter[K any] interface { + Getter[K] + Setter[K] } -type StandardGetSetter struct { - Getter func(ctx TransformContext) interface{} - Setter func(ctx TransformContext, val interface{}) +type StandardGetSetter[K any] struct { + Getter func(ctx K) interface{} + Setter func(ctx K, val interface{}) } -func (path StandardGetSetter) Get(ctx TransformContext) interface{} { +func (path StandardGetSetter[K]) Get(ctx K) interface{} { return path.Getter(ctx) } -func (path StandardGetSetter) Set(ctx TransformContext, val interface{}) { +func (path StandardGetSetter[K]) Set(ctx K, val interface{}) { path.Setter(ctx, val) } -type literal struct { +type literal[K any] struct { value interface{} } -func (l literal) Get(ctx TransformContext) interface{} { +func (l literal[K]) Get(K) interface{} { return l.value } -type exprGetter struct { - expr ExprFunc +type exprGetter[K any] struct { + expr ExprFunc[K] } -func (g exprGetter) Get(ctx TransformContext) interface{} { +func (g exprGetter[K]) Get(ctx K) interface{} { return g.expr(ctx) } -func (p *Parser) newGetter(val Value) (Getter, error) { +func (p *Parser[K]) newGetter(val Value) (Getter[K], error) { if val.IsNil != nil && *val.IsNil { - return &literal{value: nil}, nil + return &literal[K]{value: nil}, nil } if s := val.String; s != nil { - return &literal{value: *s}, nil + return &literal[K]{value: *s}, nil } if f := val.Float; f != nil { - return &literal{value: *f}, nil + return &literal[K]{value: *f}, nil } if i := val.Int; i != nil { - return &literal{value: *i}, nil + return &literal[K]{value: *i}, nil } if b := val.Bool; b != nil { - return &literal{value: bool(*b)}, nil + return &literal[K]{value: bool(*b)}, nil } if b := val.Bytes; b != nil { - return &literal{value: ([]byte)(*b)}, nil + return &literal[K]{value: ([]byte)(*b)}, nil } if val.Enum != nil { @@ -96,7 +88,7 @@ func (p *Parser) newGetter(val Value) (Getter, error) { if err != nil { return nil, err } - return &literal{value: int64(*enum)}, nil + return &literal[K]{value: int64(*enum)}, nil } if val.Path != nil { @@ -111,7 +103,7 @@ func (p *Parser) newGetter(val Value) (Getter, error) { if err != nil { return nil, err } - return &exprGetter{ + return &exprGetter[K]{ expr: call, }, nil } diff --git a/pkg/ottl/expression_test.go b/pkg/ottl/expression_test.go index b972e471da69e..ac7404db0757f 100644 --- a/pkg/ottl/expression_test.go +++ b/pkg/ottl/expression_test.go @@ -23,8 +23,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) -func hello() (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func hello[K any]() (ExprFunc[K], error) { + return func(ctx K) interface{} { return "world" }, nil } @@ -108,7 +108,7 @@ func Test_newGetter(t *testing.T) { }, } - functions := map[string]interface{}{"hello": hello} + functions := map[string]interface{}{"hello": hello[interface{}]} p := NewParser( functions, @@ -121,9 +121,7 @@ func Test_newGetter(t *testing.T) { t.Run(tt.name, func(t *testing.T) { reader, err := p.newGetter(tt.val) assert.NoError(t, err) - val := reader.Get(ottltest.TestTransformContext{ - Item: tt.want, - }) + val := reader.Get(tt.want) assert.Equal(t, tt.want, val) }) } @@ -133,17 +131,3 @@ func Test_newGetter(t *testing.T) { assert.Error(t, err) }) } - -// pathGetSetter is a getSetter which has been resolved using a path expression provided by a user. -type testGetSetter struct { - getter ExprFunc - setter func(ctx TransformContext, val interface{}) -} - -func (path testGetSetter) Get(ctx TransformContext) interface{} { - return path.getter(ctx) -} - -func (path testGetSetter) Set(ctx TransformContext, val interface{}) { - path.setter(ctx, val) -} diff --git a/pkg/ottl/functions.go b/pkg/ottl/functions.go index ef1d2388bf2a7..b59148a0bc5fa 100644 --- a/pkg/ottl/functions.go +++ b/pkg/ottl/functions.go @@ -15,17 +15,19 @@ package ottl // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" import ( + "errors" "fmt" "reflect" + "strings" ) -type PathExpressionParser func(*Path) (GetSetter, error) +type PathExpressionParser[K any] func(*Path) (GetSetter[K], error) type EnumParser func(*EnumSymbol) (*Enum, error) type Enum int64 -func (p *Parser) newFunctionCall(inv Invocation) (ExprFunc, error) { +func (p *Parser[K]) newFunctionCall(inv Invocation) (ExprFunc[K], error) { if f, ok := p.functions[inv.Function]; ok { args, err := p.buildArgs(inv, reflect.TypeOf(f)) if err != nil { @@ -40,12 +42,12 @@ func (p *Parser) newFunctionCall(inv Invocation) (ExprFunc, error) { err = returnVals[1].Interface().(error) } - return returnVals[0].Interface().(ExprFunc), err + return returnVals[0].Interface().(ExprFunc[K]), err } return nil, fmt.Errorf("undefined function %v", inv.Function) } -func (p *Parser) buildArgs(inv Invocation, fType reflect.Type) ([]reflect.Value, error) { +func (p *Parser[K]) buildArgs(inv Invocation, fType reflect.Type) ([]reflect.Value, error) { var args []reflect.Value // Some function arguments may be intended to take values from the calling processor // instead of being passed by the caller of the OTTL function, so we have to keep @@ -90,9 +92,10 @@ func (p *Parser) buildArgs(inv Invocation, fType reflect.Type) ([]reflect.Value, return args, nil } -func (p *Parser) buildSliceArg(inv Invocation, argType reflect.Type, startingIndex int, args *[]reflect.Value) error { - switch argType.Elem().Name() { - case reflect.String.String(): +func (p *Parser[K]) buildSliceArg(inv Invocation, argType reflect.Type, startingIndex int, args *[]reflect.Value) error { + name := argType.Elem().Name() + switch { + case name == reflect.String.String(): var arg []string for j := startingIndex; j < len(inv.Arguments); j++ { if inv.Arguments[j].String == nil { @@ -101,7 +104,7 @@ func (p *Parser) buildSliceArg(inv Invocation, argType reflect.Type, startingInd arg = append(arg, *inv.Arguments[j].String) } *args = append(*args, reflect.ValueOf(arg)) - case reflect.Float64.String(): + case name == reflect.Float64.String(): var arg []float64 for j := startingIndex; j < len(inv.Arguments); j++ { if inv.Arguments[j].Float == nil { @@ -110,7 +113,7 @@ func (p *Parser) buildSliceArg(inv Invocation, argType reflect.Type, startingInd arg = append(arg, *inv.Arguments[j].Float) } *args = append(*args, reflect.ValueOf(arg)) - case reflect.Int64.String(): + case name == reflect.Int64.String(): var arg []int64 for j := startingIndex; j < len(inv.Arguments); j++ { if inv.Arguments[j].Int == nil { @@ -119,13 +122,13 @@ func (p *Parser) buildSliceArg(inv Invocation, argType reflect.Type, startingInd arg = append(arg, *inv.Arguments[j].Int) } *args = append(*args, reflect.ValueOf(arg)) - case reflect.Uint8.String(): + case name == reflect.Uint8.String(): if inv.Arguments[startingIndex].Bytes == nil { return fmt.Errorf("invalid argument for slice parameter at position %v, must be a byte slice literal", startingIndex) } *args = append(*args, reflect.ValueOf(([]byte)(*inv.Arguments[startingIndex].Bytes))) - case "Getter": - var arg []Getter + case strings.HasPrefix(name, "Getter"): + var arg []Getter[K] for j := startingIndex; j < len(inv.Arguments); j++ { val, err := p.newGetter(inv.Arguments[j]) if err != nil { @@ -141,55 +144,58 @@ func (p *Parser) buildSliceArg(inv Invocation, argType reflect.Type, startingInd } // Handle interfaces that can be passed as arguments to OTTL function invocations. -func (p *Parser) buildArg(argDef Value, argType reflect.Type, index int, args *[]reflect.Value) error { - switch argType.Name() { - case "Setter": +func (p *Parser[K]) buildArg(argDef Value, argType reflect.Type, index int, args *[]reflect.Value) error { + name := argType.Name() + switch { + case strings.HasPrefix(name, "Setter"): fallthrough - case "GetSetter": + case strings.HasPrefix(name, "GetSetter"): arg, err := p.pathParser(argDef.Path) if err != nil { return fmt.Errorf("invalid argument at position %v %w", index, err) } *args = append(*args, reflect.ValueOf(arg)) - case "Getter": + case strings.HasPrefix(name, "Getter"): arg, err := p.newGetter(argDef) if err != nil { return fmt.Errorf("invalid argument at position %v %w", index, err) } *args = append(*args, reflect.ValueOf(arg)) - case "Enum": + case name == "Enum": arg, err := p.enumParser(argDef.Enum) if err != nil { return fmt.Errorf("invalid argument at position %v must be an Enum", index) } *args = append(*args, reflect.ValueOf(*arg)) - case "string": + case name == "string": if argDef.String == nil { return fmt.Errorf("invalid argument at position %v, must be an string", index) } *args = append(*args, reflect.ValueOf(*argDef.String)) - case "float64": + case name == "float64": if argDef.Float == nil { return fmt.Errorf("invalid argument at position %v, must be an float", index) } *args = append(*args, reflect.ValueOf(*argDef.Float)) - case "int64": + case name == "int64": if argDef.Int == nil { return fmt.Errorf("invalid argument at position %v, must be an int", index) } *args = append(*args, reflect.ValueOf(*argDef.Int)) - case "bool": + case name == "bool": if argDef.Bool == nil { return fmt.Errorf("invalid argument at position %v, must be a bool", index) } *args = append(*args, reflect.ValueOf(bool(*argDef.Bool))) + default: + return errors.New("unsupported argument type") } return nil } // Handle interfaces that can be declared as parameters to a OTTL function, but will // never be called in an invocation. Returns whether the arg is an internal arg. -func (p *Parser) buildInternalArg(argType reflect.Type, args *[]reflect.Value) bool { +func (p *Parser[K]) buildInternalArg(argType reflect.Type, args *[]reflect.Value) bool { switch argType.Name() { case "TelemetrySettings": *args = append(*args, reflect.ValueOf(p.telemetrySettings)) diff --git a/pkg/ottl/functions_test.go b/pkg/ottl/functions_test.go index 7c35423d82357..536c622390674 100644 --- a/pkg/ottl/functions_test.go +++ b/pkg/ottl/functions_test.go @@ -540,111 +540,111 @@ func Test_NewFunctionCall(t *testing.T) { } } -func functionWithStringSlice(_ []string) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithStringSlice(_ []string) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithFloatSlice(_ []float64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithFloatSlice(_ []float64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithIntSlice(_ []int64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithIntSlice(_ []int64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithByteSlice(_ []byte) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithByteSlice([]byte) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithGetterSlice(_ []Getter) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithGetterSlice([]Getter[interface{}]) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithSetter(_ Setter) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithSetter(Setter[interface{}]) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithGetSetter(_ GetSetter) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithGetSetter(GetSetter[interface{}]) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithGetter(_ Getter) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithGetter(Getter[interface{}]) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithString(_ string) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithString(string) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithFloat(_ float64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithFloat(float64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithInt(_ int64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithInt(int64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithBool(_ bool) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithBool(bool) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithMultipleArgs(_ GetSetter, _ string, _ float64, _ int64, _ []string) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithMultipleArgs(GetSetter[interface{}], string, float64, int64, []string) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionThatHasAnError() (ExprFunc, error) { +func functionThatHasAnError() (ExprFunc[interface{}], error) { err := errors.New("testing") - return func(ctx TransformContext) interface{} { + return func(interface{}) interface{} { return "anything" }, err } -func functionWithEnum(_ Enum) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithEnum(_ Enum) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithTelemetrySettingsFirst(_ component.TelemetrySettings, _ string, _ string, _ int64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithTelemetrySettingsFirst(_ component.TelemetrySettings, _ string, _ string, _ int64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithTelemetrySettingsMiddle(_ string, _ string, _ component.TelemetrySettings, _ int64) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithTelemetrySettingsMiddle(_ string, _ string, _ component.TelemetrySettings, _ int64) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } -func functionWithTelemetrySettingsLast(_ string, _ string, _ int64, _ component.TelemetrySettings) (ExprFunc, error) { - return func(ctx TransformContext) interface{} { +func functionWithTelemetrySettingsLast(_ string, _ string, _ int64, _ component.TelemetrySettings) (ExprFunc[interface{}], error) { + return func(interface{}) interface{} { return "anything" }, nil } diff --git a/pkg/ottl/ottlfuncs/func_concat.go b/pkg/ottl/ottlfuncs/func_concat.go index fa50a46bf73f0..d193b080d238e 100644 --- a/pkg/ottl/ottlfuncs/func_concat.go +++ b/pkg/ottl/ottlfuncs/func_concat.go @@ -21,8 +21,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func Concat(delimiter string, vals []ottl.Getter) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { +func Concat[K any](delimiter string, vals []ottl.Getter[K]) (ottl.ExprFunc[K], error) { + return func(ctx K) interface{} { builder := strings.Builder{} for i, rv := range vals { switch val := rv.Get(ctx).(type) { diff --git a/pkg/ottl/ottlfuncs/func_concat_test.go b/pkg/ottl/ottlfuncs/func_concat_test.go index 2402f376d71e2..a78db44ee1cc4 100644 --- a/pkg/ottl/ottlfuncs/func_concat_test.go +++ b/pkg/ottl/ottlfuncs/func_concat_test.go @@ -18,29 +18,29 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_concat(t *testing.T) { tests := []struct { name string delimiter string - vals []ottl.StandardGetSetter + vals []ottl.StandardGetSetter[interface{}] expected string }{ { name: "concat strings", delimiter: " ", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "world" }, }, @@ -50,19 +50,19 @@ func Test_concat(t *testing.T) { { name: "nil", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return nil }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "world" }, }, @@ -72,14 +72,14 @@ func Test_concat(t *testing.T) { { name: "integers", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return int64(1) }, }, @@ -89,14 +89,14 @@ func Test_concat(t *testing.T) { { name: "floats", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return 3.14159 }, }, @@ -106,14 +106,14 @@ func Test_concat(t *testing.T) { { name: "booleans", delimiter: " ", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return true }, }, @@ -123,9 +123,9 @@ func Test_concat(t *testing.T) { { name: "byte slices", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xd2, 0xe6, 0x3c, 0xbe, 0x71, 0xf5, 0xa8} }, }, @@ -135,9 +135,9 @@ func Test_concat(t *testing.T) { { name: "non-byte slices", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} }, }, @@ -147,9 +147,9 @@ func Test_concat(t *testing.T) { { name: "maps", delimiter: "", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return map[string]string{"key": "value"} }, }, @@ -159,19 +159,19 @@ func Test_concat(t *testing.T) { { name: "unprintable value in the middle", delimiter: "-", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return map[string]string{"key": "value"} }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "world" }, }, @@ -181,19 +181,19 @@ func Test_concat(t *testing.T) { { name: "empty string values", delimiter: "__", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "" }, }, { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "" }, }, @@ -203,9 +203,9 @@ func Test_concat(t *testing.T) { { name: "single argument", delimiter: "-", - vals: []ottl.StandardGetSetter{ + vals: []ottl.StandardGetSetter[interface{}]{ { - Getter: func(ctx ottl.TransformContext) interface{} { + Getter: func(ctx interface{}) interface{} { return "hello" }, }, @@ -215,30 +215,27 @@ func Test_concat(t *testing.T) { { name: "no arguments", delimiter: "-", - vals: []ottl.StandardGetSetter{}, + vals: []ottl.StandardGetSetter[interface{}]{}, expected: "", }, { name: "no arguments with an empty delimiter", delimiter: "", - vals: []ottl.StandardGetSetter{}, + vals: []ottl.StandardGetSetter[interface{}]{}, expected: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := ottltest.TestTransformContext{} - - getters := make([]ottl.Getter, len(tt.vals)) + getters := make([]ottl.Getter[interface{}], len(tt.vals)) for i, val := range tt.vals { getters[i] = val } - exprFunc, _ := Concat(tt.delimiter, getters) - actual := exprFunc(ctx) - - assert.Equal(t, tt.expected, actual) + exprFunc, err := Concat(tt.delimiter, getters) + require.NoError(t, err) + assert.Equal(t, tt.expected, exprFunc(nil)) }) } } diff --git a/pkg/ottl/ottlfuncs/func_delete_key.go b/pkg/ottl/ottlfuncs/func_delete_key.go index 8a5a4f0e853e8..9b98aca12cf06 100644 --- a/pkg/ottl/ottlfuncs/func_delete_key.go +++ b/pkg/ottl/ottlfuncs/func_delete_key.go @@ -20,8 +20,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func DeleteKey(target ottl.Getter, key string) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { +func DeleteKey[K any](target ottl.Getter[K], key string) (ottl.ExprFunc[K], error) { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil diff --git a/pkg/ottl/ottlfuncs/func_delete_key_test.go b/pkg/ottl/ottlfuncs/func_delete_key_test.go index 1e4b138a1835e..ee1ea1f0e7c3a 100644 --- a/pkg/ottl/ottlfuncs/func_delete_key_test.go +++ b/pkg/ottl/ottlfuncs/func_delete_key_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_deleteKey(t *testing.T) { @@ -30,15 +30,15 @@ func Test_deleteKey(t *testing.T) { input.PutInt("test2", 3) input.PutBool("test3", true) - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, } tests := []struct { name string - target ottl.Getter + target ottl.Getter[pcommon.Map] key string want func(pcommon.Map) }{ @@ -79,12 +79,9 @@ func Test_deleteKey(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := DeleteKey(tt.target, tt.key) - exprFunc(ctx) + exprFunc, err := DeleteKey(tt.target, tt.key) + require.NoError(t, err) + exprFunc(scenarioMap) expected := pcommon.NewMap() tt.want(expected) @@ -96,43 +93,36 @@ func Test_deleteKey(t *testing.T) { func Test_deleteKey_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } key := "anything" - exprFunc, _ := DeleteKey(target, key) - exprFunc(ctx) - + exprFunc, err := DeleteKey[interface{}](target, key) + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_deleteKey_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } key := "anything" - exprFunc, _ := DeleteKey(target, key) - exprFunc(ctx) + exprFunc, err := DeleteKey[interface{}](target, key) + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_delete_matching_keys.go b/pkg/ottl/ottlfuncs/func_delete_matching_keys.go index 9243ea2100807..7251703027246 100644 --- a/pkg/ottl/ottlfuncs/func_delete_matching_keys.go +++ b/pkg/ottl/ottlfuncs/func_delete_matching_keys.go @@ -23,12 +23,12 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func DeleteMatchingKeys(target ottl.Getter, pattern string) (ottl.ExprFunc, error) { +func DeleteMatchingKeys[K any](target ottl.Getter[K], pattern string) (ottl.ExprFunc[K], error) { compiledPattern, err := regexp.Compile(pattern) if err != nil { return nil, fmt.Errorf("the regex pattern supplied to delete_matching_keys is not a valid pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil diff --git a/pkg/ottl/ottlfuncs/func_delete_matching_keys_test.go b/pkg/ottl/ottlfuncs/func_delete_matching_keys_test.go index 742859512dd47..27cf2b2c26645 100644 --- a/pkg/ottl/ottlfuncs/func_delete_matching_keys_test.go +++ b/pkg/ottl/ottlfuncs/func_delete_matching_keys_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_deleteMatchingKeys(t *testing.T) { @@ -30,15 +30,15 @@ func Test_deleteMatchingKeys(t *testing.T) { input.PutInt("test2", 3) input.PutBool("test3", true) - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, } tests := []struct { name string - target ottl.Getter + target ottl.Getter[pcommon.Map] pattern string want func(pcommon.Map) }{ @@ -77,12 +77,9 @@ func Test_deleteMatchingKeys(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := DeleteMatchingKeys(tt.target, tt.pattern) - exprFunc(ctx) + exprFunc, err := DeleteMatchingKeys(tt.target, tt.pattern) + require.NoError(t, err) + exprFunc(scenarioMap) expected := pcommon.NewMap() tt.want(expected) @@ -94,48 +91,41 @@ func Test_deleteMatchingKeys(t *testing.T) { func Test_deleteMatchingKeys_bad_input(t *testing.T) { input := pcommon.NewValueInt(1) - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, } - exprFunc, err := DeleteMatchingKeys(target, "anything") - assert.Nil(t, err) - exprFunc(ctx) + exprFunc, err := DeleteMatchingKeys[interface{}](target, "anything") + require.NoError(t, err) + exprFunc(input) assert.Equal(t, pcommon.NewValueInt(1), input) } func Test_deleteMatchingKeys_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, } - exprFunc, _ := DeleteMatchingKeys(target, "anything") - exprFunc(ctx) + exprFunc, err := DeleteMatchingKeys[interface{}](target, "anything") + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } func Test_deleteMatchingKeys_invalid_pattern(t *testing.T) { - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { t.Errorf("nothing should be received in this scenario") return nil }, } invalidRegexPattern := "*" - exprFunc, err := DeleteMatchingKeys(target, invalidRegexPattern) - assert.Nil(t, exprFunc) - assert.Contains(t, err.Error(), "error parsing regexp:") + _, err := DeleteMatchingKeys[interface{}](target, invalidRegexPattern) + require.Error(t, err) + assert.ErrorContains(t, err, "error parsing regexp:") } diff --git a/pkg/ottl/ottlfuncs/func_int.go b/pkg/ottl/ottlfuncs/func_int.go index 223eb64c4f426..a099ac4e81cd0 100644 --- a/pkg/ottl/ottlfuncs/func_int.go +++ b/pkg/ottl/ottlfuncs/func_int.go @@ -20,8 +20,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func Int(target ottl.Getter) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { +func Int[K any](target ottl.Getter[K]) (ottl.ExprFunc[K], error) { + return func(ctx K) interface{} { value := target.Get(ctx) switch value := value.(type) { case int64: diff --git a/pkg/ottl/ottlfuncs/func_int_test.go b/pkg/ottl/ottlfuncs/func_int_test.go index 0c72b0d5fe8b3..5226942d47353 100644 --- a/pkg/ottl/ottlfuncs/func_int_test.go +++ b/pkg/ottl/ottlfuncs/func_int_test.go @@ -18,9 +18,9 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_Int(t *testing.T) { @@ -82,16 +82,13 @@ func Test_Int(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := ottltest.TestTransformContext{} - - exprFunc, _ := Int(&ottl.StandardGetSetter{ - Getter: func(_ ottl.TransformContext) interface{} { + exprFunc, err := Int[interface{}](&ottl.StandardGetSetter[interface{}]{ + Getter: func(interface{}) interface{} { return tt.value }, }) - actual := exprFunc(ctx) - - assert.Equal(t, tt.expected, actual) + require.NoError(t, err) + assert.Equal(t, tt.expected, exprFunc(nil)) }) } } diff --git a/pkg/ottl/ottlfuncs/func_is_match.go b/pkg/ottl/ottlfuncs/func_is_match.go index 05956499b2690..6fe5d64c058d2 100644 --- a/pkg/ottl/ottlfuncs/func_is_match.go +++ b/pkg/ottl/ottlfuncs/func_is_match.go @@ -21,15 +21,15 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func IsMatch(target ottl.Getter, pattern string) (ottl.ExprFunc, error) { - regexp, err := regexp.Compile(pattern) +func IsMatch[K any](target ottl.Getter[K], pattern string) (ottl.ExprFunc[K], error) { + compiledPattern, err := regexp.Compile(pattern) if err != nil { return nil, fmt.Errorf("the pattern supplied to IsMatch is not a valid regexp pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { if val := target.Get(ctx); val != nil { if valStr, ok := val.(string); ok { - return regexp.MatchString(valStr) + return compiledPattern.MatchString(valStr) } } return false diff --git a/pkg/ottl/ottlfuncs/func_is_match_test.go b/pkg/ottl/ottlfuncs/func_is_match_test.go index 5743ac9944f04..803be3d18daa5 100644 --- a/pkg/ottl/ottlfuncs/func_is_match_test.go +++ b/pkg/ottl/ottlfuncs/func_is_match_test.go @@ -18,22 +18,22 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_isMatch(t *testing.T) { tests := []struct { name string - target ottl.Getter + target ottl.Getter[interface{}] pattern string expected bool }{ { name: "replace match true", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "hello world" }, }, @@ -42,8 +42,8 @@ func Test_isMatch(t *testing.T) { }, { name: "replace match false", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "goodbye world" }, }, @@ -52,8 +52,8 @@ func Test_isMatch(t *testing.T) { }, { name: "replace match complex", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "-12.001" }, }, @@ -62,8 +62,8 @@ func Test_isMatch(t *testing.T) { }, { name: "target not a string", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return 1 }, }, @@ -72,8 +72,8 @@ func Test_isMatch(t *testing.T) { }, { name: "target nil", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return nil }, }, @@ -83,22 +83,19 @@ func Test_isMatch(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := ottltest.TestTransformContext{} - - exprFunc, _ := IsMatch(tt.target, tt.pattern) - actual := exprFunc(ctx) - - assert.Equal(t, tt.expected, actual) + exprFunc, err := IsMatch(tt.target, tt.pattern) + require.NoError(t, err) + assert.Equal(t, tt.expected, exprFunc(nil)) }) } } func Test_isMatch_validation(t *testing.T) { - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "anything" }, } - _, err := IsMatch(target, "\\K") - assert.Error(t, err) + _, err := IsMatch[interface{}](target, "\\K") + require.Error(t, err) } diff --git a/pkg/ottl/ottlfuncs/func_keep_keys.go b/pkg/ottl/ottlfuncs/func_keep_keys.go index 5c3149ed6f406..4bbb747cd9e6f 100644 --- a/pkg/ottl/ottlfuncs/func_keep_keys.go +++ b/pkg/ottl/ottlfuncs/func_keep_keys.go @@ -20,13 +20,13 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func KeepKeys(target ottl.GetSetter, keys []string) (ottl.ExprFunc, error) { +func KeepKeys[K any](target ottl.GetSetter[K], keys []string) (ottl.ExprFunc[K], error) { keySet := make(map[string]struct{}, len(keys)) for _, key := range keys { keySet[key] = struct{}{} } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil diff --git a/pkg/ottl/ottlfuncs/func_keep_keys_test.go b/pkg/ottl/ottlfuncs/func_keep_keys_test.go index c4b1bc89810ee..c4641f75a736e 100644 --- a/pkg/ottl/ottlfuncs/func_keep_keys_test.go +++ b/pkg/ottl/ottlfuncs/func_keep_keys_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_keepKeys(t *testing.T) { @@ -30,19 +30,19 @@ func Test_keepKeys(t *testing.T) { input.PutInt("test2", 3) input.PutBool("test3", true) - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Map).Clear() - val.(pcommon.Map).CopyTo(ctx.GetItem().(pcommon.Map)) + Setter: func(ctx pcommon.Map, val interface{}) { + ctx.Clear() + val.(pcommon.Map).CopyTo(ctx) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Map] keys []string want func(pcommon.Map) }{ @@ -95,12 +95,9 @@ func Test_keepKeys(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := KeepKeys(tt.target, tt.keys) - exprFunc(ctx) + exprFunc, err := KeepKeys(tt.target, tt.keys) + require.NoError(t, err) + exprFunc(scenarioMap) expected := pcommon.NewMap() tt.want(expected) @@ -112,43 +109,37 @@ func Test_keepKeys(t *testing.T) { func Test_keepKeys_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } keys := []string{"anything"} - exprFunc, _ := KeepKeys(target, keys) - exprFunc(ctx) + exprFunc, err := KeepKeys[interface{}](target, keys) + require.NoError(t, err) + exprFunc(input) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_keepKeys_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } keys := []string{"anything"} - exprFunc, _ := KeepKeys(target, keys) - exprFunc(ctx) + exprFunc, err := KeepKeys[interface{}](target, keys) + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_limit.go b/pkg/ottl/ottlfuncs/func_limit.go index 68178f5e981a8..be46e60d3ff6f 100644 --- a/pkg/ottl/ottlfuncs/func_limit.go +++ b/pkg/ottl/ottlfuncs/func_limit.go @@ -22,7 +22,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func Limit(target ottl.GetSetter, limit int64, priorityKeys []string) (ottl.ExprFunc, error) { +func Limit[K any](target ottl.GetSetter[K], limit int64, priorityKeys []string) (ottl.ExprFunc[K], error) { if limit < 0 { return nil, fmt.Errorf("invalid limit for limit function, %d cannot be negative", limit) } @@ -37,37 +37,40 @@ func Limit(target ottl.GetSetter, limit int64, priorityKeys []string) (ottl.Expr keep[key] = struct{}{} } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil } - if attrs, ok := val.(pcommon.Map); ok { - if int64(attrs.Len()) <= limit { - return nil - } + attrs, ok := val.(pcommon.Map) + if !ok { + return nil + } - count := int64(0) - for _, key := range priorityKeys { - if _, ok := attrs.Get(key); ok { - count++ - } - } + if int64(attrs.Len()) <= limit { + return nil + } - attrs.RemoveIf(func(key string, value pcommon.Value) bool { - if _, ok := keep[key]; ok { - return false - } - if count < limit { - count++ - return false - } - return true - }) - // TODO: Write log when limiting is performed - // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/9730 + count := int64(0) + for _, key := range priorityKeys { + if _, ok := attrs.Get(key); ok { + count++ + } } + + attrs.RemoveIf(func(key string, value pcommon.Value) bool { + if _, ok := keep[key]; ok { + return false + } + if count < limit { + count++ + return false + } + return true + }) + // TODO: Write log when limiting is performed + // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/9730 return nil }, nil } diff --git a/pkg/ottl/ottlfuncs/func_limit_test.go b/pkg/ottl/ottlfuncs/func_limit_test.go index e49576d35ca20..87fe546b92a2f 100644 --- a/pkg/ottl/ottlfuncs/func_limit_test.go +++ b/pkg/ottl/ottlfuncs/func_limit_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_limit(t *testing.T) { @@ -30,19 +30,19 @@ func Test_limit(t *testing.T) { input.PutInt("test2", 3) input.PutBool("test3", true) - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Map).Clear() - val.(pcommon.Map).CopyTo(ctx.GetItem().(pcommon.Map)) + Setter: func(ctx pcommon.Map, val interface{}) { + ctx.Clear() + val.(pcommon.Map).CopyTo(ctx) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Map] limit int64 keep []string want func(pcommon.Map) @@ -135,18 +135,14 @@ func Test_limit(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := Limit(tt.target, tt.limit, tt.keep) - exprFunc(ctx) - actual := ctx.GetItem() + exprFunc, err := Limit(tt.target, tt.limit, tt.keep) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioMap)) expected := pcommon.NewMap() tt.want(expected) - assert.Equal(t, expected, actual) + assert.Equal(t, expected, scenarioMap) }) } } @@ -154,18 +150,18 @@ func Test_limit(t *testing.T) { func Test_limit_validation(t *testing.T) { tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[interface{}] keep []string limit int64 }{ { name: "limit less than zero", - target: &ottl.StandardGetSetter{}, + target: &ottl.StandardGetSetter[interface{}]{}, limit: int64(-1), }, { name: "limit less than # of keep attrs", - target: &ottl.StandardGetSetter{}, + target: &ottl.StandardGetSetter[interface{}]{}, keep: []string{"test", "test"}, limit: int64(1), }, @@ -173,46 +169,39 @@ func Test_limit_validation(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := Limit(tt.target, tt.limit, tt.keep) - assert.NotNil(t, err) + assert.Error(t, err) }) } } func Test_limit_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := Limit(target, 1, []string{}) - exprFunc(ctx) - + exprFunc, err := Limit[interface{}](target, 1, []string{}) + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_limit_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := Limit(target, 1, []string{}) - exprFunc(ctx) + exprFunc, err := Limit[interface{}](target, 1, []string{}) + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_matches.go b/pkg/ottl/ottlfuncs/func_replace_all_matches.go index cae8eff46ce53..e86522e4fc69d 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_matches.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_matches.go @@ -23,27 +23,29 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ReplaceAllMatches(target ottl.GetSetter, pattern string, replacement string) (ottl.ExprFunc, error) { +func ReplaceAllMatches[K any](target ottl.GetSetter[K], pattern string, replacement string) (ottl.ExprFunc[K], error) { glob, err := glob.Compile(pattern) if err != nil { return nil, fmt.Errorf("the pattern supplied to replace_match is not a valid pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil } - if attrs, ok := val.(pcommon.Map); ok { - updated := pcommon.NewMap() - attrs.CopyTo(updated) - updated.Range(func(key string, value pcommon.Value) bool { - if glob.Match(value.Str()) { - value.SetStr(replacement) - } - return true - }) - target.Set(ctx, updated) + attrs, ok := val.(pcommon.Map) + if !ok { + return nil } + updated := pcommon.NewMap() + attrs.CopyTo(updated) + updated.Range(func(key string, value pcommon.Value) bool { + if glob.Match(value.Str()) { + value.SetStr(replacement) + } + return true + }) + target.Set(ctx, updated) return nil }, nil } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go b/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go index c742ab7a46818..967030bf6eed9 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_matches_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_replaceAllMatches(t *testing.T) { @@ -30,19 +30,19 @@ func Test_replaceAllMatches(t *testing.T) { input.PutString("test2", "hello") input.PutString("test3", "goodbye") - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Map).Clear() - val.(pcommon.Map).CopyTo(ctx.GetItem().(pcommon.Map)) + Setter: func(ctx pcommon.Map, val interface{}) { + ctx.Clear() + val.(pcommon.Map).CopyTo(ctx) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Map] pattern string replacement string want func(pcommon.Map) @@ -77,12 +77,9 @@ func Test_replaceAllMatches(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := ReplaceAllMatches(tt.target, tt.pattern, tt.replacement) - exprFunc(ctx) + exprFunc, err := ReplaceAllMatches(tt.target, tt.pattern, tt.replacement) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioMap)) expected := pcommon.NewMap() tt.want(expected) @@ -94,39 +91,32 @@ func Test_replaceAllMatches(t *testing.T) { func Test_replaceAllMatches_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := ReplaceAllMatches(target, "*", "{replacement}") - exprFunc(ctx) - + exprFunc, err := ReplaceAllMatches[interface{}](target, "*", "{replacement}") + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_replaceAllMatches_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := ReplaceAllMatches(target, "*", "{anything}") - exprFunc(ctx) + exprFunc, err := ReplaceAllMatches[interface{}](target, "*", "{anything}") + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_patterns.go b/pkg/ottl/ottlfuncs/func_replace_all_patterns.go index 9e9394ac3ae2d..f78682417503d 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_patterns.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_patterns.go @@ -23,28 +23,31 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ReplaceAllPatterns(target ottl.GetSetter, regexPattern string, replacement string) (ottl.ExprFunc, error) { +func ReplaceAllPatterns[K any](target ottl.GetSetter[K], regexPattern string, replacement string) (ottl.ExprFunc[K], error) { compiledPattern, err := regexp.Compile(regexPattern) if err != nil { return nil, fmt.Errorf("the regex pattern supplied to replace_all_patterns is not a valid pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil } - if attrs, ok := val.(pcommon.Map); ok { - updated := pcommon.NewMap() - attrs.CopyTo(updated) - updated.Range(func(key string, value pcommon.Value) bool { - stringVal := value.Str() - if compiledPattern.MatchString(stringVal) { - value.SetStr(compiledPattern.ReplaceAllLiteralString(stringVal, replacement)) - } - return true - }) - target.Set(ctx, updated) + attrs, ok := val.(pcommon.Map) + if !ok { + return nil } + + updated := pcommon.NewMap() + attrs.CopyTo(updated) + updated.Range(func(key string, value pcommon.Value) bool { + stringVal := value.Str() + if compiledPattern.MatchString(stringVal) { + value.SetStr(compiledPattern.ReplaceAllLiteralString(stringVal, replacement)) + } + return true + }) + target.Set(ctx, updated) return nil }, nil } diff --git a/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go b/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go index d01d4a6e2f1d1..e6b9ebad41939 100644 --- a/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_all_patterns_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_replaceAllPatterns(t *testing.T) { @@ -30,19 +30,19 @@ func Test_replaceAllPatterns(t *testing.T) { input.PutString("test2", "hello") input.PutString("test3", "goodbye world1 and world2") - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Map).Clear() - val.(pcommon.Map).CopyTo(ctx.GetItem().(pcommon.Map)) + Setter: func(ctx pcommon.Map, val interface{}) { + ctx.Clear() + val.(pcommon.Map).CopyTo(ctx) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Map] pattern string replacement string want func(pcommon.Map) @@ -89,12 +89,9 @@ func Test_replaceAllPatterns(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := ReplaceAllPatterns(tt.target, tt.pattern, tt.replacement) - exprFunc(ctx) + exprFunc, err := ReplaceAllPatterns[pcommon.Map](tt.target, tt.pattern, tt.replacement) + require.NoError(t, err) + exprFunc(scenarioMap) expected := pcommon.NewMap() tt.want(expected) @@ -106,59 +103,53 @@ func Test_replaceAllPatterns(t *testing.T) { func Test_replaceAllPatterns_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, err := ReplaceAllPatterns(target, "regexpattern", "{replacement}") + exprFunc, err := ReplaceAllPatterns[interface{}](target, "regexpattern", "{replacement}") assert.Nil(t, err) - exprFunc(ctx) + exprFunc(input) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_replaceAllPatterns_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, err := ReplaceAllPatterns(target, "regexp", "{anything}") - assert.Nil(t, err) - exprFunc(ctx) + exprFunc, err := ReplaceAllPatterns[interface{}](target, "regexp", "{anything}") + require.NoError(t, err) + exprFunc(nil) } func Test_replaceAllPatterns_invalid_pattern(t *testing.T) { - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { t.Errorf("nothing should be received in this scenario") return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } invalidRegexPattern := "*" - exprFunc, err := ReplaceAllPatterns(target, invalidRegexPattern, "{anything}") + exprFunc, err := ReplaceAllPatterns[interface{}](target, invalidRegexPattern, "{anything}") + require.Error(t, err) + assert.ErrorContains(t, err, "error parsing regexp:") assert.Nil(t, exprFunc) - assert.Contains(t, err.Error(), "error parsing regexp:") } diff --git a/pkg/ottl/ottlfuncs/func_replace_match.go b/pkg/ottl/ottlfuncs/func_replace_match.go index 914cce9b80dfb..0ca9aaeae0146 100644 --- a/pkg/ottl/ottlfuncs/func_replace_match.go +++ b/pkg/ottl/ottlfuncs/func_replace_match.go @@ -22,12 +22,12 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ReplaceMatch(target ottl.GetSetter, pattern string, replacement string) (ottl.ExprFunc, error) { +func ReplaceMatch[K any](target ottl.GetSetter[K], pattern string, replacement string) (ottl.ExprFunc[K], error) { glob, err := glob.Compile(pattern) if err != nil { return nil, fmt.Errorf("the pattern supplied to replace_match is not a valid pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { val := target.Get(ctx) if val == nil { return nil diff --git a/pkg/ottl/ottlfuncs/func_replace_match_test.go b/pkg/ottl/ottlfuncs/func_replace_match_test.go index 0460ff3ed8808..c2ffa3253e2b6 100644 --- a/pkg/ottl/ottlfuncs/func_replace_match_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_match_test.go @@ -18,27 +18,27 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_replaceMatch(t *testing.T) { input := pcommon.NewValueString("hello world") - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(pcommon.Value).Str() + target := &ottl.StandardGetSetter[pcommon.Value]{ + Getter: func(ctx pcommon.Value) interface{} { + return ctx.Str() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Value).SetStr(val.(string)) + Setter: func(ctx pcommon.Value, val interface{}) { + ctx.SetStr(val.(string)) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Value] pattern string replacement string want func(pcommon.Value) @@ -66,12 +66,9 @@ func Test_replaceMatch(t *testing.T) { t.Run(tt.name, func(t *testing.T) { scenarioValue := pcommon.NewValueString(input.Str()) - ctx := ottltest.TestTransformContext{ - Item: scenarioValue, - } - - exprFunc, _ := ReplaceMatch(tt.target, tt.pattern, tt.replacement) - exprFunc(ctx) + exprFunc, err := ReplaceMatch(tt.target, tt.pattern, tt.replacement) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioValue)) expected := pcommon.NewValueString("") tt.want(expected) @@ -83,39 +80,33 @@ func Test_replaceMatch(t *testing.T) { func Test_replaceMatch_bad_input(t *testing.T) { input := pcommon.NewValueInt(1) - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := ReplaceMatch(target, "*", "{replacement}") - exprFunc(ctx) + exprFunc, err := ReplaceMatch[interface{}](target, "*", "{replacement}") + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueInt(1), input) } func Test_replaceMatch_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := ReplaceMatch(target, "*", "{anything}") - exprFunc(ctx) + exprFunc, err := ReplaceMatch[interface{}](target, "*", "{anything}") + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_replace_pattern.go b/pkg/ottl/ottlfuncs/func_replace_pattern.go index d085ce43dfad8..3b4a960e64be8 100644 --- a/pkg/ottl/ottlfuncs/func_replace_pattern.go +++ b/pkg/ottl/ottlfuncs/func_replace_pattern.go @@ -21,12 +21,12 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func ReplacePattern(target ottl.GetSetter, regexPattern string, replacement string) (ottl.ExprFunc, error) { +func ReplacePattern[K any](target ottl.GetSetter[K], regexPattern string, replacement string) (ottl.ExprFunc[K], error) { compiledPattern, err := regexp.Compile(regexPattern) if err != nil { return nil, fmt.Errorf("the regex pattern supplied to replace_pattern is not a valid pattern: %w", err) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { originalVal := target.Get(ctx) if originalVal == nil { return nil diff --git a/pkg/ottl/ottlfuncs/func_replace_pattern_test.go b/pkg/ottl/ottlfuncs/func_replace_pattern_test.go index 45ec2fd52a03d..8bbafead160b3 100644 --- a/pkg/ottl/ottlfuncs/func_replace_pattern_test.go +++ b/pkg/ottl/ottlfuncs/func_replace_pattern_test.go @@ -18,27 +18,27 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_replacePattern(t *testing.T) { input := pcommon.NewValueString("application passwd=sensitivedtata otherarg=notsensitive key1 key2") - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem().(pcommon.Value).Str() + target := &ottl.StandardGetSetter[pcommon.Value]{ + Getter: func(ctx pcommon.Value) interface{} { + return ctx.Str() }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Value).SetStr(val.(string)) + Setter: func(ctx pcommon.Value, val interface{}) { + ctx.SetStr(val.(string)) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Value] pattern string replacement string want func(pcommon.Value) @@ -75,12 +75,9 @@ func Test_replacePattern(t *testing.T) { t.Run(tt.name, func(t *testing.T) { scenarioValue := pcommon.NewValueString(input.Str()) - ctx := ottltest.TestTransformContext{ - Item: scenarioValue, - } - - exprFunc, _ := ReplacePattern(tt.target, tt.pattern, tt.replacement) - exprFunc(ctx) + exprFunc, err := ReplacePattern(tt.target, tt.pattern, tt.replacement) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioValue)) expected := pcommon.NewValueString("") tt.want(expected) @@ -92,57 +89,49 @@ func Test_replacePattern(t *testing.T) { func Test_replacePattern_bad_input(t *testing.T) { input := pcommon.NewValueInt(1) - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, err := ReplacePattern(target, "regexp", "{replacement}") - assert.Nil(t, err) - exprFunc(ctx) - + exprFunc, err := ReplacePattern[interface{}](target, "regexp", "{replacement}") + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueInt(1), input) } func Test_replacePattern_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := ReplacePattern(target, `nomatch\=[^\s]*(\s?)`, "{anything}") - exprFunc(ctx) + exprFunc, err := ReplacePattern[interface{}](target, `nomatch\=[^\s]*(\s?)`, "{anything}") + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } func Test_replacePatterns_invalid_pattern(t *testing.T) { - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { t.Errorf("nothing should be received in this scenario") return nil }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } invalidRegexPattern := "*" - exprFunc, err := ReplacePattern(target, invalidRegexPattern, "{anything}") - assert.Nil(t, exprFunc) - assert.Contains(t, err.Error(), "error parsing regexp:") + _, err := ReplacePattern[interface{}](target, invalidRegexPattern, "{anything}") + require.Error(t, err) + assert.ErrorContains(t, err, "error parsing regexp:") } diff --git a/pkg/ottl/ottlfuncs/func_set.go b/pkg/ottl/ottlfuncs/func_set.go index 95c7505428a6f..c447ebb9cd7e8 100644 --- a/pkg/ottl/ottlfuncs/func_set.go +++ b/pkg/ottl/ottlfuncs/func_set.go @@ -16,8 +16,8 @@ package ottlfuncs // import "github.com/open-telemetry/opentelemetry-collector-c import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" -func Set(target ottl.Setter, value ottl.Getter) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { +func Set[K any](target ottl.Setter[K], value ottl.Getter[K]) (ottl.ExprFunc[K], error) { + return func(ctx K) interface{} { val := value.Get(ctx) // No fields currently support `null` as a valid type. diff --git a/pkg/ottl/ottlfuncs/func_set_test.go b/pkg/ottl/ottlfuncs/func_set_test.go index 4881d71857d75..43949490c0309 100644 --- a/pkg/ottl/ottlfuncs/func_set_test.go +++ b/pkg/ottl/ottlfuncs/func_set_test.go @@ -18,32 +18,32 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_set(t *testing.T) { input := pcommon.NewValueString("original name") - target := &ottl.StandardGetSetter{ - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Value).SetStr(val.(string)) + target := &ottl.StandardGetSetter[pcommon.Value]{ + Setter: func(ctx pcommon.Value, val interface{}) { + ctx.SetStr(val.(string)) }, } tests := []struct { name string - setter ottl.Setter - getter ottl.Getter + setter ottl.Setter[pcommon.Value] + getter ottl.Getter[pcommon.Value] want func(pcommon.Value) }{ { name: "set name", setter: target, - getter: ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + getter: ottl.StandardGetSetter[pcommon.Value]{ + Getter: func(ctx pcommon.Value) interface{} { return "new name" }, }, @@ -54,8 +54,8 @@ func Test_set(t *testing.T) { { name: "set nil value", setter: target, - getter: ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + getter: ottl.StandardGetSetter[pcommon.Value]{ + Getter: func(ctx pcommon.Value) interface{} { return nil }, }, @@ -68,12 +68,9 @@ func Test_set(t *testing.T) { t.Run(tt.name, func(t *testing.T) { scenarioValue := pcommon.NewValueString(input.Str()) - ctx := ottltest.TestTransformContext{ - Item: scenarioValue, - } - - exprFunc, _ := Set(tt.setter, tt.getter) - exprFunc(ctx) + exprFunc, err := Set(tt.setter, tt.getter) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioValue)) expected := pcommon.NewValueString("") tt.want(expected) @@ -84,22 +81,19 @@ func Test_set(t *testing.T) { } func Test_set_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - setter := &ottl.StandardGetSetter{ - Setter: func(ctx ottl.TransformContext, val interface{}) { + setter := &ottl.StandardGetSetter[interface{}]{ + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - getter := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + getter := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, } - exprFunc, _ := Set(setter, getter) - exprFunc(ctx) + exprFunc, err := Set[interface{}](setter, getter) + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottlfuncs/func_span_id.go b/pkg/ottl/ottlfuncs/func_span_id.go index a0ea9e00aadcb..af42e7659bb2f 100644 --- a/pkg/ottl/ottlfuncs/func_span_id.go +++ b/pkg/ottl/ottlfuncs/func_span_id.go @@ -22,14 +22,14 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func SpanID(bytes []byte) (ottl.ExprFunc, error) { +func SpanID[K any](bytes []byte) (ottl.ExprFunc[K], error) { if len(bytes) != 8 { return nil, errors.New("span ids must be 8 bytes") } var idArr [8]byte copy(idArr[:8], bytes) id := pcommon.SpanID(idArr) - return func(ctx ottl.TransformContext) interface{} { + return func(K) interface{} { return id }, nil } diff --git a/pkg/ottl/ottlfuncs/func_span_id_test.go b/pkg/ottl/ottlfuncs/func_span_id_test.go index 299ed486e30ba..14a61c0840314 100644 --- a/pkg/ottl/ottlfuncs/func_span_id_test.go +++ b/pkg/ottl/ottlfuncs/func_span_id_test.go @@ -18,9 +18,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_spanID(t *testing.T) { @@ -37,13 +36,9 @@ func Test_spanID(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - - ctx := ottltest.TestTransformContext{} - - exprFunc, _ := SpanID(tt.bytes) - actual := exprFunc(ctx) - - assert.Equal(t, tt.want, actual) + exprFunc, err := SpanID[interface{}](tt.bytes) + require.NoError(t, err) + assert.Equal(t, tt.want, exprFunc(nil)) }) } } @@ -64,8 +59,9 @@ func Test_spanID_validation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := TraceID(tt.bytes) - assert.Error(t, err, "span ids must be 8 bytes") + _, err := SpanID[interface{}](tt.bytes) + require.Error(t, err) + assert.ErrorContains(t, err, "span ids must be 8 bytes") }) } } diff --git a/pkg/ottl/ottlfuncs/func_split.go b/pkg/ottl/ottlfuncs/func_split.go index 3ec3a036d90d2..736b6c88f5fc7 100644 --- a/pkg/ottl/ottlfuncs/func_split.go +++ b/pkg/ottl/ottlfuncs/func_split.go @@ -20,8 +20,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func Split(target ottl.Getter, delimiter string) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { +func Split[K any](target ottl.Getter[K], delimiter string) (ottl.ExprFunc[K], error) { + return func(ctx K) interface{} { if val := target.Get(ctx); val != nil { if valStr, ok := val.(string); ok { return strings.Split(valStr, delimiter) diff --git a/pkg/ottl/ottlfuncs/func_split_test.go b/pkg/ottl/ottlfuncs/func_split_test.go index 630120c098302..02aa2e7f64120 100644 --- a/pkg/ottl/ottlfuncs/func_split_test.go +++ b/pkg/ottl/ottlfuncs/func_split_test.go @@ -18,22 +18,22 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_split(t *testing.T) { tests := []struct { name string - target ottl.Getter + target ottl.Getter[interface{}] delimiter string expected interface{} }{ { name: "split string", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "A|B|C" }, }, @@ -42,8 +42,8 @@ func Test_split(t *testing.T) { }, { name: "split empty string", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "" }, }, @@ -52,8 +52,8 @@ func Test_split(t *testing.T) { }, { name: "split empty delimiter", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "A|B|C" }, }, @@ -62,8 +62,8 @@ func Test_split(t *testing.T) { }, { name: "split empty string and empty delimiter", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return "" }, }, @@ -72,8 +72,8 @@ func Test_split(t *testing.T) { }, { name: "split non-string", - target: &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { + target: &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { return 123 }, }, @@ -83,12 +83,9 @@ func Test_split(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := ottltest.TestTransformContext{} - - exprFunc, _ := Split(tt.target, tt.delimiter) - actual := exprFunc(ctx) - - assert.Equal(t, tt.expected, actual) + exprFunc, err := Split(tt.target, tt.delimiter) + require.NoError(t, err) + assert.Equal(t, tt.expected, exprFunc(nil)) }) } } diff --git a/pkg/ottl/ottlfuncs/func_trace_id.go b/pkg/ottl/ottlfuncs/func_trace_id.go index b4b2aa6736518..9db3fd5a0ae31 100644 --- a/pkg/ottl/ottlfuncs/func_trace_id.go +++ b/pkg/ottl/ottlfuncs/func_trace_id.go @@ -22,14 +22,14 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func TraceID(bytes []byte) (ottl.ExprFunc, error) { +func TraceID[K any](bytes []byte) (ottl.ExprFunc[K], error) { if len(bytes) != 16 { return nil, errors.New("traces ids must be 16 bytes") } var idArr [16]byte copy(idArr[:16], bytes) id := pcommon.TraceID(idArr) - return func(ctx ottl.TransformContext) interface{} { + return func(K) interface{} { return id }, nil } diff --git a/pkg/ottl/ottlfuncs/func_trace_id_test.go b/pkg/ottl/ottlfuncs/func_trace_id_test.go index f19c04199c9e3..ac5c48d037bc1 100644 --- a/pkg/ottl/ottlfuncs/func_trace_id_test.go +++ b/pkg/ottl/ottlfuncs/func_trace_id_test.go @@ -18,9 +18,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_traceID(t *testing.T) { @@ -37,13 +36,9 @@ func Test_traceID(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - - ctx := ottltest.TestTransformContext{} - - exprFunc, _ := TraceID(tt.bytes) - actual := exprFunc(ctx) - - assert.Equal(t, tt.want, actual) + exprFunc, err := TraceID[interface{}](tt.bytes) + require.NoError(t, err) + assert.Equal(t, tt.want, exprFunc(nil)) }) } } @@ -64,8 +59,9 @@ func Test_traceID_validation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := TraceID(tt.bytes) - assert.Error(t, err, "traces ids must be 16 bytes") + _, err := TraceID[interface{}](tt.bytes) + require.Error(t, err) + assert.ErrorContains(t, err, "traces ids must be 16 bytes") }) } } diff --git a/pkg/ottl/ottlfuncs/func_truncate_all.go b/pkg/ottl/ottlfuncs/func_truncate_all.go index ae5f722ca7fa1..70d49785315a5 100644 --- a/pkg/ottl/ottlfuncs/func_truncate_all.go +++ b/pkg/ottl/ottlfuncs/func_truncate_all.go @@ -22,11 +22,11 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" ) -func TruncateAll(target ottl.GetSetter, limit int64) (ottl.ExprFunc, error) { +func TruncateAll[K any](target ottl.GetSetter[K], limit int64) (ottl.ExprFunc[K], error) { if limit < 0 { return nil, fmt.Errorf("invalid limit for truncate_all function, %d cannot be negative", limit) } - return func(ctx ottl.TransformContext) interface{} { + return func(ctx K) interface{} { if limit < 0 { return nil } @@ -36,20 +36,23 @@ func TruncateAll(target ottl.GetSetter, limit int64) (ottl.ExprFunc, error) { return nil } - if attrs, ok := val.(pcommon.Map); ok { - updated := pcommon.NewMap() - attrs.CopyTo(updated) - updated.Range(func(key string, value pcommon.Value) bool { - stringVal := value.Str() - if int64(len(stringVal)) > limit { - value.SetStr(stringVal[:limit]) - } - return true - }) - target.Set(ctx, updated) - // TODO: Write log when truncation is performed - // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/9730 + attrs, ok := val.(pcommon.Map) + if !ok { + return nil } + + updated := pcommon.NewMap() + attrs.CopyTo(updated) + updated.Range(func(key string, value pcommon.Value) bool { + stringVal := value.Str() + if int64(len(stringVal)) > limit { + value.SetStr(stringVal[:limit]) + } + return true + }) + target.Set(ctx, updated) + // TODO: Write log when truncation is performed + // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/9730 return nil }, nil } diff --git a/pkg/ottl/ottlfuncs/func_truncate_all_test.go b/pkg/ottl/ottlfuncs/func_truncate_all_test.go index 629f65de5bab5..f413fca29d1e8 100644 --- a/pkg/ottl/ottlfuncs/func_truncate_all_test.go +++ b/pkg/ottl/ottlfuncs/func_truncate_all_test.go @@ -18,10 +18,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" ) func Test_truncateAll(t *testing.T) { @@ -30,19 +30,19 @@ func Test_truncateAll(t *testing.T) { input.PutInt("test2", 3) input.PutBool("test3", true) - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[pcommon.Map]{ + Getter: func(ctx pcommon.Map) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { - ctx.GetItem().(pcommon.Map).Clear() - val.(pcommon.Map).CopyTo(ctx.GetItem().(pcommon.Map)) + Setter: func(ctx pcommon.Map, val interface{}) { + ctx.Clear() + val.(pcommon.Map).CopyTo(ctx) }, } tests := []struct { name string - target ottl.GetSetter + target ottl.GetSetter[pcommon.Map] limit int64 want func(pcommon.Map) }{ @@ -96,12 +96,9 @@ func Test_truncateAll(t *testing.T) { scenarioMap := pcommon.NewMap() input.CopyTo(scenarioMap) - ctx := ottltest.TestTransformContext{ - Item: scenarioMap, - } - - exprFunc, _ := TruncateAll(tt.target, tt.limit) - exprFunc(ctx) + exprFunc, err := TruncateAll(tt.target, tt.limit) + require.NoError(t, err) + assert.Nil(t, exprFunc(scenarioMap)) expected := pcommon.NewMap() tt.want(expected) @@ -112,60 +109,39 @@ func Test_truncateAll(t *testing.T) { } func Test_truncateAll_validation(t *testing.T) { - tests := []struct { - name string - target ottl.GetSetter - limit int64 - }{ - { - name: "limit less than zero", - target: &ottl.StandardGetSetter{}, - limit: int64(-1), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - _, err := TruncateAll(tt.target, tt.limit) - assert.Error(t, err, "invalid limit for truncate_all function, -1 cannot be negative") - }) - } + _, err := TruncateAll[interface{}](&ottl.StandardGetSetter[interface{}]{}, -1) + require.Error(t, err) + assert.ErrorContains(t, err, "invalid limit for truncate_all function, -1 cannot be negative") } func Test_truncateAll_bad_input(t *testing.T) { input := pcommon.NewValueString("not a map") - ctx := ottltest.TestTransformContext{ - Item: input, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := TruncateAll(target, 1) - exprFunc(ctx) - + exprFunc, err := TruncateAll[interface{}](target, 1) + require.NoError(t, err) + assert.Nil(t, exprFunc(input)) assert.Equal(t, pcommon.NewValueString("not a map"), input) } func Test_truncateAll_get_nil(t *testing.T) { - ctx := ottltest.TestTransformContext{ - Item: nil, - } - - target := &ottl.StandardGetSetter{ - Getter: func(ctx ottl.TransformContext) interface{} { - return ctx.GetItem() + target := &ottl.StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - Setter: func(ctx ottl.TransformContext, val interface{}) { + Setter: func(ctx interface{}, val interface{}) { t.Errorf("nothing should be set in this scenario") }, } - exprFunc, _ := TruncateAll(target, 1) - exprFunc(ctx) + exprFunc, err := TruncateAll[interface{}](target, 1) + require.NoError(t, err) + assert.Nil(t, exprFunc(nil)) } diff --git a/pkg/ottl/ottltest/ottltest.go b/pkg/ottl/ottltest/ottltest.go index d465afc0fd277..53155eb1e1abb 100644 --- a/pkg/ottl/ottltest/ottltest.go +++ b/pkg/ottl/ottltest/ottltest.go @@ -14,10 +14,6 @@ package ottltest // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" -import ( - "go.opentelemetry.io/collector/pdata/pcommon" -) - func Strp(s string) *string { return &s } @@ -33,19 +29,3 @@ func Intp(i int64) *int64 { func Boolp(b bool) *bool { return &b } - -type TestTransformContext struct { - Item interface{} -} - -func (ctx TestTransformContext) GetItem() interface{} { - return ctx.Item -} - -func (ctx TestTransformContext) GetInstrumentationScope() pcommon.InstrumentationScope { - return pcommon.InstrumentationScope{} -} - -func (ctx TestTransformContext) GetResource() pcommon.Resource { - return pcommon.Resource{} -} diff --git a/pkg/ottl/parser.go b/pkg/ottl/parser.go index 8b06e188fdd7a..18fcbc29235c5 100644 --- a/pkg/ottl/parser.go +++ b/pkg/ottl/parser.go @@ -157,9 +157,9 @@ type Field struct { // Statement holds a top level Statement for processing telemetry data. A Statement is a combination of a function // invocation and the expression to match telemetry for invoking the function. -type Statement struct { - Function ExprFunc - Condition boolExpressionEvaluator +type Statement[K any] struct { + Function ExprFunc[K] + Condition boolExpressionEvaluator[K] } // Bytes type for capturing byte arrays @@ -193,15 +193,15 @@ func (n *IsNil) Capture(_ []string) error { type EnumSymbol string -type Parser struct { +type Parser[K any] struct { functions map[string]interface{} - pathParser PathExpressionParser + pathParser PathExpressionParser[K] enumParser EnumParser telemetrySettings component.TelemetrySettings } -func NewParser(functions map[string]interface{}, pathParser PathExpressionParser, enumParser EnumParser, telemetrySettings component.TelemetrySettings) Parser { - return Parser{ +func NewParser[K any](functions map[string]interface{}, pathParser PathExpressionParser[K], enumParser EnumParser, telemetrySettings component.TelemetrySettings) Parser[K] { + return Parser[K]{ functions: functions, pathParser: pathParser, enumParser: enumParser, @@ -209,8 +209,8 @@ func NewParser(functions map[string]interface{}, pathParser PathExpressionParser } } -func (p *Parser) ParseStatements(statements []string) ([]Statement, error) { - var queries []Statement +func (p *Parser[K]) ParseStatements(statements []string) ([]Statement[K], error) { + var queries []Statement[K] var errors error for _, statement := range statements { @@ -229,7 +229,7 @@ func (p *Parser) ParseStatements(statements []string) ([]Statement, error) { errors = multierr.Append(errors, err) continue } - queries = append(queries, Statement{ + queries = append(queries, Statement[K]{ Function: function, Condition: expression, }) diff --git a/pkg/ottl/parser_test.go b/pkg/ottl/parser_test.go index d4e261b4019fa..d9d28030626d3 100644 --- a/pkg/ottl/parser_test.go +++ b/pkg/ottl/parser_test.go @@ -16,6 +16,7 @@ package ottl import ( "fmt" + "reflect" "regexp" "testing" @@ -466,14 +467,14 @@ func Test_parse_failure(t *testing.T) { } } -func testParsePath(val *Path) (GetSetter, error) { +func testParsePath(val *Path) (GetSetter[interface{}], error) { if val != nil && len(val.Fields) > 0 && val.Fields[0].Name == "name" { - return &testGetSetter{ - getter: func(ctx TransformContext) interface{} { - return ctx.GetItem() + return &StandardGetSetter[interface{}]{ + Getter: func(ctx interface{}) interface{} { + return ctx }, - setter: func(ctx TransformContext, val interface{}) { - ctx.GetItem() + Setter: func(ctx interface{}, val interface{}) { + reflect.DeepEqual(ctx, val) }, }, nil } diff --git a/processor/routingprocessor/internal/common/functions.go b/processor/routingprocessor/internal/common/functions.go index 05d4567c719e7..87aec1f0daff8 100644 --- a/processor/routingprocessor/internal/common/functions.go +++ b/processor/routingprocessor/internal/common/functions.go @@ -19,19 +19,17 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs" ) -var registry = map[string]interface{}{ - "IsMatch": ottlfuncs.IsMatch, - "delete_key": ottlfuncs.DeleteKey, - "delete_matching_keys": ottlfuncs.DeleteMatchingKeys, - // noop function, it is required since the parsing of conditions is not implemented yet, - // see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/13545 - "route": func(_ []string) (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { - return true - }, nil - }, -} - -func Functions() map[string]interface{} { - return registry +func Functions[K any]() map[string]interface{} { + return map[string]interface{}{ + "IsMatch": ottlfuncs.IsMatch[K], + "delete_key": ottlfuncs.DeleteKey[K], + "delete_matching_keys": ottlfuncs.DeleteMatchingKeys[K], + // noop function, it is required since the parsing of conditions is not implemented yet, + // see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/13545 + "route": func(_ []string) (ottl.ExprFunc[K], error) { + return func(K) interface{} { + return true + }, nil + }, + } } diff --git a/processor/routingprocessor/logs.go b/processor/routingprocessor/logs.go index fa2e5ac698d1b..c047af7117aab 100644 --- a/processor/routingprocessor/logs.go +++ b/processor/routingprocessor/logs.go @@ -25,7 +25,9 @@ import ( "go.uber.org/multierr" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllogs" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor/internal/common" ) var _ component.LogsProcessor = (*logProcessor)(nil) @@ -35,7 +37,7 @@ type logProcessor struct { config *Config extractor extractor - router router[component.LogsExporter] + router router[component.LogsExporter, ottllogs.TransformContext] } func newLogProcessor(settings component.TelemetrySettings, config config.Processor) *logProcessor { @@ -44,10 +46,16 @@ func newLogProcessor(settings component.TelemetrySettings, config config.Process return &logProcessor{ logger: settings.Logger, config: cfg, - router: newRouter[component.LogsExporter]( + router: newRouter[component.LogsExporter, ottllogs.TransformContext]( cfg.Table, cfg.DefaultExporters, settings, + ottl.NewParser[ottllogs.TransformContext]( + common.Functions[ottllogs.TransformContext](), + ottllogs.ParsePath, + ottllogs.ParseEnum, + settings, + ), ), extractor: newExtractor(cfg.FromAttribute, settings.Logger), } diff --git a/processor/routingprocessor/metrics.go b/processor/routingprocessor/metrics.go index c3fa1f738a336..9e5c62b327904 100644 --- a/processor/routingprocessor/metrics.go +++ b/processor/routingprocessor/metrics.go @@ -25,7 +25,9 @@ import ( "go.uber.org/multierr" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor/internal/common" ) var _ component.MetricsProcessor = (*metricsProcessor)(nil) @@ -35,7 +37,7 @@ type metricsProcessor struct { config *Config extractor extractor - router router[component.MetricsExporter] + router router[component.MetricsExporter, ottldatapoints.TransformContext] } func newMetricProcessor(settings component.TelemetrySettings, config config.Processor) *metricsProcessor { @@ -48,6 +50,12 @@ func newMetricProcessor(settings component.TelemetrySettings, config config.Proc cfg.Table, cfg.DefaultExporters, settings, + ottl.NewParser[ottldatapoints.TransformContext]( + common.Functions[ottldatapoints.TransformContext](), + ottldatapoints.ParsePath, + ottldatapoints.ParseEnum, + settings, + ), ), extractor: newExtractor(cfg.FromAttribute, settings.Logger), } diff --git a/processor/routingprocessor/router.go b/processor/routingprocessor/router.go index ccf3173cfa799..f217040bf37ba 100644 --- a/processor/routingprocessor/router.go +++ b/processor/routingprocessor/router.go @@ -23,8 +23,6 @@ import ( "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllogs" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor/internal/common" ) var errExporterNotFound = errors.New("exporter not found") @@ -32,46 +30,42 @@ var errExporterNotFound = errors.New("exporter not found") // router registers exporters and default exporters for an exporter. router can // be instantiated with component.TracesExporter, component.MetricsExporter, and // component.LogsExporter type arguments. -type router[E component.Exporter] struct { +type router[E component.Exporter, K any] struct { logger *zap.Logger - parser ottl.Parser + parser ottl.Parser[K] defaultExporterIDs []string table []RoutingTableItem defaultExporters []E - routes map[string]routingItem[E] + routes map[string]routingItem[E, K] } // newRouter creates a new router instance with its type parameter constrained // to component.Exporter. -func newRouter[E component.Exporter]( +func newRouter[E component.Exporter, K any]( table []RoutingTableItem, defaultExporterIDs []string, settings component.TelemetrySettings, -) router[E] { - return router[E]{ + parser ottl.Parser[K], +) router[E, K] { + return router[E, K]{ logger: settings.Logger, - parser: ottl.NewParser( - common.Functions(), - ottllogs.ParsePath, - ottllogs.ParseEnum, - settings, - ), + parser: parser, table: table, defaultExporterIDs: defaultExporterIDs, - routes: make(map[string]routingItem[E]), + routes: make(map[string]routingItem[E, K]), } } -type routingItem[E component.Exporter] struct { +type routingItem[E component.Exporter, K any] struct { exporters []E - expression ottl.Statement + expression ottl.Statement[K] } -func (r *router[E]) registerExporters(available map[config.ComponentID]component.Exporter) error { +func (r *router[E, K]) registerExporters(available map[config.ComponentID]component.Exporter) error { // register default exporters err := r.registerDefaultExporters(available) if err != nil { @@ -89,7 +83,7 @@ func (r *router[E]) registerExporters(available map[config.ComponentID]component // registerDefaultExporters registers the configured default exporters // using the provided available exporters map. -func (r *router[E]) registerDefaultExporters(available map[config.ComponentID]component.Exporter) error { +func (r *router[E, K]) registerDefaultExporters(available map[config.ComponentID]component.Exporter) error { for _, name := range r.defaultExporterIDs { e, err := r.extractExporter(name, available) if errors.Is(err, errExporterNotFound) { @@ -106,7 +100,7 @@ func (r *router[E]) registerDefaultExporters(available map[config.ComponentID]co // registerRouteExporters registers route exporters using the provided // available exporters map to check if they were available. -func (r *router[E]) registerRouteExporters(available map[config.ComponentID]component.Exporter) error { +func (r *router[E, K]) registerRouteExporters(available map[config.ComponentID]component.Exporter) error { for _, item := range r.table { e, err := r.routingExpression(item) if err != nil { @@ -136,8 +130,8 @@ func (r *router[E]) registerRouteExporters(available map[config.ComponentID]comp // routingExpression builds a routing OTTL expressions from provided // routing table entry configuration. If routing table entry configuration // does not contain a OTTL expressions then nil is returned. -func (r *router[E]) routingExpression(item RoutingTableItem) (ottl.Statement, error) { - var e ottl.Statement +func (r *router[E, K]) routingExpression(item RoutingTableItem) (ottl.Statement[K], error) { + var e ottl.Statement[K] if item.Expression != "" { queries, err := r.parser.ParseStatements([]string{item.Expression}) if err != nil { @@ -160,7 +154,7 @@ func key(entry RoutingTableItem) string { // extractExporter returns an exporter for the given name (type/name) and type // argument if it exists in the list of available exporters. -func (r *router[E]) extractExporter(name string, available map[config.ComponentID]component.Exporter) (E, error) { +func (r *router[E, K]) extractExporter(name string, available map[config.ComponentID]component.Exporter) (E, error) { var exporter E id, err := config.NewComponentIDFromString(name) @@ -190,7 +184,7 @@ func (r *router[E]) extractExporter(name string, available map[config.ComponentI return exporter, nil } -func (r *router[E]) getExporters(key string) []E { +func (r *router[E, K]) getExporters(key string) []E { e, ok := r.routes[key] if !ok { return r.defaultExporters diff --git a/processor/routingprocessor/traces.go b/processor/routingprocessor/traces.go index 83771034c4323..3ea1a152e8165 100644 --- a/processor/routingprocessor/traces.go +++ b/processor/routingprocessor/traces.go @@ -25,7 +25,9 @@ import ( "go.uber.org/multierr" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottltraces" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor/internal/common" ) var _ component.TracesProcessor = (*tracesProcessor)(nil) @@ -35,7 +37,7 @@ type tracesProcessor struct { config *Config extractor extractor - router router[component.TracesExporter] + router router[component.TracesExporter, ottltraces.TransformContext] } func newTracesProcessor(settings component.TelemetrySettings, config config.Processor) *tracesProcessor { @@ -44,10 +46,16 @@ func newTracesProcessor(settings component.TelemetrySettings, config config.Proc return &tracesProcessor{ logger: settings.Logger, config: cfg, - router: newRouter[component.TracesExporter]( + router: newRouter[component.TracesExporter, ottltraces.TransformContext]( cfg.Table, cfg.DefaultExporters, settings, + ottl.NewParser[ottltraces.TransformContext]( + common.Functions[ottltraces.TransformContext](), + ottltraces.ParsePath, + ottltraces.ParseEnum, + settings, + ), ), extractor: newExtractor(cfg.FromAttribute, settings.Logger), } diff --git a/processor/transformprocessor/config.go b/processor/transformprocessor/config.go index 89e03db06e172..6b9cc1db7fbc5 100644 --- a/processor/transformprocessor/config.go +++ b/processor/transformprocessor/config.go @@ -41,35 +41,35 @@ var _ config.Processor = (*Config)(nil) func (c *Config) Validate() error { var errors error - ottlp := ottl.NewParser( + ottltracesp := ottl.NewParser[ottltraces.TransformContext]( traces.Functions(), ottltraces.ParsePath, ottltraces.ParseEnum, component.TelemetrySettings{Logger: zap.NewNop()}, ) - _, err := ottlp.ParseStatements(c.Traces.Queries) + _, err := ottltracesp.ParseStatements(c.Traces.Queries) if err != nil { errors = multierr.Append(errors, err) } - ottlp = ottl.NewParser( + ottlmetricsp := ottl.NewParser[ottldatapoints.TransformContext]( metrics.Functions(), ottldatapoints.ParsePath, ottldatapoints.ParseEnum, component.TelemetrySettings{Logger: zap.NewNop()}, ) - _, err = ottlp.ParseStatements(c.Metrics.Queries) + _, err = ottlmetricsp.ParseStatements(c.Metrics.Queries) if err != nil { errors = multierr.Append(errors, err) } - ottlp = ottl.NewParser( + ottllogsp := ottl.NewParser[ottllogs.TransformContext]( logs.Functions(), ottllogs.ParsePath, ottllogs.ParseEnum, component.TelemetrySettings{Logger: zap.NewNop()}, ) - _, err = ottlp.ParseStatements(c.Logs.Queries) + _, err = ottllogsp.ParseStatements(c.Logs.Queries) if err != nil { errors = multierr.Append(errors, err) } diff --git a/processor/transformprocessor/internal/common/functions.go b/processor/transformprocessor/internal/common/functions.go index 37b12c1c881f8..7b1e370d71d64 100644 --- a/processor/transformprocessor/internal/common/functions.go +++ b/processor/transformprocessor/internal/common/functions.go @@ -18,25 +18,23 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs" ) -var registry = map[string]interface{}{ - "TraceID": ottlfuncs.TraceID, - "SpanID": ottlfuncs.SpanID, - "IsMatch": ottlfuncs.IsMatch, - "Concat": ottlfuncs.Concat, - "Split": ottlfuncs.Split, - "Int": ottlfuncs.Int, - "keep_keys": ottlfuncs.KeepKeys, - "set": ottlfuncs.Set, - "truncate_all": ottlfuncs.TruncateAll, - "limit": ottlfuncs.Limit, - "replace_match": ottlfuncs.ReplaceMatch, - "replace_all_matches": ottlfuncs.ReplaceAllMatches, - "replace_pattern": ottlfuncs.ReplacePattern, - "replace_all_patterns": ottlfuncs.ReplaceAllPatterns, - "delete_key": ottlfuncs.DeleteKey, - "delete_matching_keys": ottlfuncs.DeleteMatchingKeys, -} - -func Functions() map[string]interface{} { - return registry +func Functions[K any]() map[string]interface{} { + return map[string]interface{}{ + "TraceID": ottlfuncs.TraceID[K], + "SpanID": ottlfuncs.SpanID[K], + "IsMatch": ottlfuncs.IsMatch[K], + "Concat": ottlfuncs.Concat[K], + "Split": ottlfuncs.Split[K], + "Int": ottlfuncs.Int[K], + "keep_keys": ottlfuncs.KeepKeys[K], + "set": ottlfuncs.Set[K], + "truncate_all": ottlfuncs.TruncateAll[K], + "limit": ottlfuncs.Limit[K], + "replace_match": ottlfuncs.ReplaceMatch[K], + "replace_all_matches": ottlfuncs.ReplaceAllMatches[K], + "replace_pattern": ottlfuncs.ReplacePattern[K], + "replace_all_patterns": ottlfuncs.ReplaceAllPatterns[K], + "delete_key": ottlfuncs.DeleteKey[K], + "delete_matching_keys": ottlfuncs.DeleteMatchingKeys[K], + } } diff --git a/processor/transformprocessor/internal/logs/functions.go b/processor/transformprocessor/internal/logs/functions.go index 3a5550619e00d..c49645b03aacc 100644 --- a/processor/transformprocessor/internal/logs/functions.go +++ b/processor/transformprocessor/internal/logs/functions.go @@ -15,10 +15,11 @@ package logs // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/logs" import ( + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllogs" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) func Functions() map[string]interface{} { // No logs-only functions yet. - return common.Functions() + return common.Functions[ottllogs.TransformContext]() } diff --git a/processor/transformprocessor/internal/logs/functions_test.go b/processor/transformprocessor/internal/logs/functions_test.go index bad4fddf79b6d..1407f5c7f481c 100644 --- a/processor/transformprocessor/internal/logs/functions_test.go +++ b/processor/transformprocessor/internal/logs/functions_test.go @@ -18,10 +18,17 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllogs" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) func Test_DefaultFunctions(t *testing.T) { - assert.Equal(t, common.Functions(), Functions()) + expected := common.Functions[ottllogs.TransformContext]() + actual := Functions() + require.Equal(t, len(expected), len(actual)) + for k := range actual { + assert.Contains(t, expected, k) + } } diff --git a/processor/transformprocessor/internal/logs/processor.go b/processor/transformprocessor/internal/logs/processor.go index 089b34123f930..2e203fb4f0b31 100644 --- a/processor/transformprocessor/internal/logs/processor.go +++ b/processor/transformprocessor/internal/logs/processor.go @@ -26,7 +26,7 @@ import ( ) type Processor struct { - queries []ottl.Statement + queries []ottl.Statement[ottllogs.TransformContext] logger *zap.Logger } diff --git a/processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum.go b/processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum.go index 7aa6b3c29d777..5285c19880e7a 100644 --- a/processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum.go +++ b/processor/transformprocessor/internal/metrics/func_convert_gauge_to_sum.go @@ -23,7 +23,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" ) -func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc, error) { +func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoints.TransformContext], error) { var aggTemp pmetric.MetricAggregationTemporality switch stringAggTemp { case "delta": @@ -34,13 +34,8 @@ func convertGaugeToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc, err return nil, fmt.Errorf("unknown aggregation temporality: %s", stringAggTemp) } - return func(ctx ottl.TransformContext) interface{} { - mtc, ok := ctx.(ottldatapoints.TransformContext) - if !ok { - return nil - } - - metric := mtc.GetMetric() + return func(ctx ottldatapoints.TransformContext) interface{} { + metric := ctx.GetMetric() if metric.Type() != pmetric.MetricTypeGauge { return nil } diff --git a/processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go b/processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go index 90302b625efdb..37be8f958a3c5 100644 --- a/processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go +++ b/processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go @@ -21,14 +21,9 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" ) -func convertSumToGauge() (ottl.ExprFunc, error) { - return func(ctx ottl.TransformContext) interface{} { - mtc, ok := ctx.(ottldatapoints.TransformContext) - if !ok { - return nil - } - - metric := mtc.GetMetric() +func convertSumToGauge() (ottl.ExprFunc[ottldatapoints.TransformContext], error) { + return func(ctx ottldatapoints.TransformContext) interface{} { + metric := ctx.GetMetric() if metric.Type() != pmetric.MetricTypeSum { return nil } diff --git a/processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum.go b/processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum.go index 864274b922adc..d63c1a58992e0 100644 --- a/processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum.go +++ b/processor/transformprocessor/internal/metrics/func_convert_summary_count_val_to_sum.go @@ -23,7 +23,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" ) -func convertSummaryCountValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc, error) { +func convertSummaryCountValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoints.TransformContext], error) { var aggTemp pmetric.MetricAggregationTemporality switch stringAggTemp { case "delta": @@ -33,18 +33,13 @@ func convertSummaryCountValToSum(stringAggTemp string, monotonic bool) (ottl.Exp default: return nil, fmt.Errorf("unknown aggregation temporality: %s", stringAggTemp) } - return func(ctx ottl.TransformContext) interface{} { - mtc, ok := ctx.(ottldatapoints.TransformContext) - if !ok { - return nil - } - - metric := mtc.GetMetric() + return func(ctx ottldatapoints.TransformContext) interface{} { + metric := ctx.GetMetric() if metric.Type() != pmetric.MetricTypeSummary { return nil } - sumMetric := mtc.GetMetrics().AppendEmpty() + sumMetric := ctx.GetMetrics().AppendEmpty() sumMetric.SetDescription(metric.Description()) sumMetric.SetName(metric.Name() + "_count") sumMetric.SetUnit(metric.Unit()) diff --git a/processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum.go b/processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum.go index 27a868c89c3d8..f9383d6d06b68 100644 --- a/processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum.go +++ b/processor/transformprocessor/internal/metrics/func_convert_summary_sum_val_to_sum.go @@ -23,7 +23,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" ) -func convertSummarySumValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc, error) { +func convertSummarySumValToSum(stringAggTemp string, monotonic bool) (ottl.ExprFunc[ottldatapoints.TransformContext], error) { var aggTemp pmetric.MetricAggregationTemporality switch stringAggTemp { case "delta": @@ -33,18 +33,13 @@ func convertSummarySumValToSum(stringAggTemp string, monotonic bool) (ottl.ExprF default: return nil, fmt.Errorf("unknown aggregation temporality: %s", stringAggTemp) } - return func(ctx ottl.TransformContext) interface{} { - mtc, ok := ctx.(ottldatapoints.TransformContext) - if !ok { - return nil - } - - metric := mtc.GetMetric() + return func(ctx ottldatapoints.TransformContext) interface{} { + metric := ctx.GetMetric() if metric.Type() != pmetric.MetricTypeSummary { return nil } - sumMetric := mtc.GetMetrics().AppendEmpty() + sumMetric := ctx.GetMetrics().AppendEmpty() sumMetric.SetDescription(metric.Description()) sumMetric.SetName(metric.Name() + "_sum") sumMetric.SetUnit(metric.Unit()) diff --git a/processor/transformprocessor/internal/metrics/functions.go b/processor/transformprocessor/internal/metrics/functions.go index 84b9b71e19e4c..06818758680b9 100644 --- a/processor/transformprocessor/internal/metrics/functions.go +++ b/processor/transformprocessor/internal/metrics/functions.go @@ -15,6 +15,7 @@ package metrics // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/metrics" import ( + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) @@ -28,7 +29,7 @@ var registry = map[string]interface{}{ func init() { // Init metrics registry with default functions common to all signals - for k, v := range common.Functions() { + for k, v := range common.Functions[ottldatapoints.TransformContext]() { registry[k] = v } } diff --git a/processor/transformprocessor/internal/metrics/functions_test.go b/processor/transformprocessor/internal/metrics/functions_test.go index cf84a686deeb3..f3da54de8cb12 100644 --- a/processor/transformprocessor/internal/metrics/functions_test.go +++ b/processor/transformprocessor/internal/metrics/functions_test.go @@ -18,25 +18,23 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottldatapoints" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) func Test_DefaultFunctions(t *testing.T) { - expectedFunctions := common.Functions() - expectedFunctions["convert_sum_to_gauge"] = convertSumToGauge - expectedFunctions["convert_gauge_to_sum"] = convertGaugeToSum - expectedFunctions["convert_summary_sum_val_to_sum"] = convertSummarySumValToSum - expectedFunctions["convert_summary_count_val_to_sum"] = convertSummaryCountValToSum + expected := common.Functions[ottldatapoints.TransformContext]() + expected["convert_sum_to_gauge"] = convertSumToGauge + expected["convert_gauge_to_sum"] = convertGaugeToSum + expected["convert_summary_sum_val_to_sum"] = convertSummarySumValToSum + expected["convert_summary_count_val_to_sum"] = convertSummaryCountValToSum actual := Functions() - assert.NotNil(t, actual) - assert.Equal(t, len(expectedFunctions), len(actual)) - + require.Equal(t, len(expected), len(actual)) for k := range actual { - if _, ok := expectedFunctions[k]; !ok { - assert.FailNowf(t, "%v is not an expected function", k) - } + assert.Contains(t, expected, k) } } diff --git a/processor/transformprocessor/internal/metrics/processor.go b/processor/transformprocessor/internal/metrics/processor.go index 31c004dafd634..21e5aefb99af1 100644 --- a/processor/transformprocessor/internal/metrics/processor.go +++ b/processor/transformprocessor/internal/metrics/processor.go @@ -27,7 +27,7 @@ import ( ) type Processor struct { - queries []ottl.Statement + queries []ottl.Statement[ottldatapoints.TransformContext] logger *zap.Logger } @@ -102,7 +102,7 @@ func (p *Processor) handleSummaryDataPoints(dps pmetric.SummaryDataPointSlice, m } } -func (p *Processor) callFunctions(ctx ottl.TransformContext) { +func (p *Processor) callFunctions(ctx ottldatapoints.TransformContext) { for _, statement := range p.queries { if statement.Condition(ctx) { statement.Function(ctx) diff --git a/processor/transformprocessor/internal/traces/functions.go b/processor/transformprocessor/internal/traces/functions.go index 3f0c2f8b0d88c..2c714d0ef2b06 100644 --- a/processor/transformprocessor/internal/traces/functions.go +++ b/processor/transformprocessor/internal/traces/functions.go @@ -15,10 +15,11 @@ package traces // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/traces" import ( + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottltraces" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) func Functions() map[string]interface{} { // No trace-only functions yet. - return common.Functions() + return common.Functions[ottltraces.TransformContext]() } diff --git a/processor/transformprocessor/internal/traces/functions_test.go b/processor/transformprocessor/internal/traces/functions_test.go index 3514845399c9c..1b4e6c748e97a 100644 --- a/processor/transformprocessor/internal/traces/functions_test.go +++ b/processor/transformprocessor/internal/traces/functions_test.go @@ -18,10 +18,17 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottltraces" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/common" ) func Test_DefaultFunctions(t *testing.T) { - assert.Equal(t, common.Functions(), Functions()) + expected := common.Functions[ottltraces.TransformContext]() + actual := Functions() + require.Equal(t, len(expected), len(actual)) + for k := range actual { + assert.Contains(t, expected, k) + } } diff --git a/processor/transformprocessor/internal/traces/processor.go b/processor/transformprocessor/internal/traces/processor.go index f5662913f46a9..1c826df939674 100644 --- a/processor/transformprocessor/internal/traces/processor.go +++ b/processor/transformprocessor/internal/traces/processor.go @@ -26,7 +26,7 @@ import ( ) type Processor struct { - queries []ottl.Statement + queries []ottl.Statement[ottltraces.TransformContext] logger *zap.Logger } diff --git a/unreleased/ottl-generics.yaml b/unreleased/ottl-generics.yaml new file mode 100644 index 0000000000000..eacb914b46608 --- /dev/null +++ b/unreleased/ottl-generics.yaml @@ -0,0 +1,11 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/ottl + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Use generics to avoid context cast in getters and funcs. + +# One or more tracking issues related to the change +issues: [14482]