Skip to content

Commit

Permalink
[pkg/ottl] Convert Statement to an interface (#14869)
Browse files Browse the repository at this point in the history
* Convert Statement to an interface

* update documentation

* add changelog entry

* Add unit tests

* adjust routing processor if statements

* Reorder return values

* Switch from interface to struct
  • Loading branch information
TylerHelmuth authored Oct 12, 2022
1 parent 3da8036 commit 064fd31
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 24 deletions.
16 changes: 16 additions & 0 deletions .chloggen/ottl-eval-interface.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

# 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: Changed Statement to be an interface with an `Execute` function.

# One or more tracking issues related to the change
issues: [14869]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
7 changes: 0 additions & 7 deletions pkg/ottl/grammar.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,6 @@ type Field struct {
MapKey *string `parser:"( '[' @String ']' )?"`
}

// 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[K any] struct {
Function ExprFunc[K]
Condition boolExpressionEvaluator[K]
}

// byteSlice type for capturing byte slices
type byteSlice []byte

Expand Down
23 changes: 21 additions & 2 deletions pkg/ottl/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ type Parser[K any] struct {
telemetrySettings component.TelemetrySettings
}

// Statement holds a top level statement for processing telemetry data.
type Statement[K any] struct {
function ExprFunc[K]
condition boolExpressionEvaluator[K]
}

// Execute is a function that will execute the statement's function if the statement's condition is met.
// Returns true if the function was run, returns false otherwise.
// If the statement contains no condition, the function will run and true will be returned.
// In addition, the functions return value is always returned.
func (s *Statement[K]) Execute(ctx K) (any, bool) {
condition := s.condition(ctx)
var result any
if condition {
result = s.function(ctx)
}
return result, condition
}

func NewParser[K any](functions map[string]interface{}, pathParser PathExpressionParser[K], enumParser EnumParser, telemetrySettings component.TelemetrySettings) Parser[K] {
return Parser[K]{
functions: functions,
Expand Down Expand Up @@ -57,8 +76,8 @@ func (p *Parser[K]) ParseStatements(statements []string) ([]Statement[K], error)
continue
}
parsedStatements = append(parsedStatements, Statement[K]{
Function: function,
Condition: expression,
function: function,
condition: expression,
})
}

Expand Down
51 changes: 51 additions & 0 deletions pkg/ottl/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -841,3 +841,54 @@ func Test_parseStatement(t *testing.T) {
})
}
}

func Test_Execute(t *testing.T) {
tests := []struct {
name string
condition boolExpressionEvaluator[interface{}]
function ExprFunc[interface{}]
expectedCondition bool
expectedResult interface{}
}{
{
name: "Condition matched",
condition: alwaysTrue[interface{}],
function: func(ctx interface{}) interface{} {
return 1
},
expectedCondition: true,
expectedResult: 1,
},
{
name: "Condition not matched",
condition: alwaysFalse[interface{}],
function: func(ctx interface{}) interface{} {
return 1
},
expectedCondition: false,
expectedResult: nil,
},
{
name: "No result",
condition: alwaysTrue[interface{}],
function: func(ctx interface{}) interface{} {
return nil
},
expectedCondition: true,
expectedResult: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
statement := Statement[interface{}]{
condition: tt.condition,
function: tt.function,
}

result, condition := statement.Execute(nil)

assert.Equal(t, tt.expectedCondition, condition)
assert.Equal(t, tt.expectedResult, result)
})
}
}
3 changes: 1 addition & 2 deletions processor/routingprocessor/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ func (p *logProcessor) route(ctx context.Context, l plog.Logs) error {

matchCount := len(p.router.routes)
for key, route := range p.router.routes {
if !route.expression.Condition(ltx) {
if _, isMatch := route.expression.Execute(ltx); !isMatch {
matchCount--
continue
}
route.expression.Function(ltx)
p.group(key, groups, route.exporters, rlogs)
}

Expand Down
3 changes: 1 addition & 2 deletions processor/routingprocessor/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,10 @@ func (p *metricsProcessor) route(ctx context.Context, tm pmetric.Metrics) error

matchCount := len(p.router.routes)
for key, route := range p.router.routes {
if !route.expression.Condition(mtx) {
if _, isMatch := route.expression.Execute(mtx); !isMatch {
matchCount--
continue
}
route.expression.Function(mtx)
p.group(key, groups, route.exporters, rmetrics)
}

Expand Down
3 changes: 1 addition & 2 deletions processor/routingprocessor/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ func (p *tracesProcessor) route(ctx context.Context, t ptrace.Traces) error {

matchCount := len(p.router.routes)
for key, route := range p.router.routes {
if !route.expression.Condition(stx) {
if _, isMatch := route.expression.Execute(stx); !isMatch {
matchCount--
continue
}
route.expression.Function(stx)
p.group(key, groups, route.exporters, rspans)
}

Expand Down
4 changes: 1 addition & 3 deletions processor/transformprocessor/internal/logs/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ func (p *Processor) ProcessLogs(_ context.Context, td plog.Logs) (plog.Logs, err
for k := 0; k < logs.Len(); k++ {
ctx := ottllogs.NewTransformContext(logs.At(k), slogs.Scope(), rlogs.Resource())
for _, statement := range p.statements {
if statement.Condition(ctx) {
statement.Function(ctx)
}
statement.Execute(ctx)
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions processor/transformprocessor/internal/metrics/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ func (p *Processor) handleSummaryDataPoints(dps pmetric.SummaryDataPointSlice, m

func (p *Processor) callFunctions(ctx ottldatapoints.TransformContext) {
for _, statement := range p.statements {
if statement.Condition(ctx) {
statement.Function(ctx)
}
statement.Execute(ctx)
}
}
4 changes: 1 addition & 3 deletions processor/transformprocessor/internal/traces/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ func (p *Processor) ProcessTraces(_ context.Context, td ptrace.Traces) (ptrace.T
for k := 0; k < spans.Len(); k++ {
ctx := ottltraces.NewTransformContext(spans.At(k), sspan.Scope(), rspans.Resource())
for _, statement := range p.statements {
if statement.Condition(ctx) {
statement.Function(ctx)
}
statement.Execute(ctx)
}
}
}
Expand Down

0 comments on commit 064fd31

Please sign in to comment.