-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: signoztransformprocessor: add custom ottl function for converti…
…ng hex strings to int (#292) * feat: signoztransformprocessor: add custom ottl function for converting hex strings to int * chore: add one more test case for HexToInt function * chore: signoztransformprocessor: HexToInt: allow odd length hex values * chore: signoztransformprocessor: hextoint: compile hex value regex only when constructing statement * chore: signoztransformprocessor: hextoint: let strconv.ParseInt do relevant validation
- Loading branch information
1 parent
098c8bc
commit 1795156
Showing
3 changed files
with
106 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
processor/signoztransformprocessor/ottlfunctions/func_hex_to_int.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package ottlfunctions | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" | ||
) | ||
|
||
type HexToIntArguments[K any] struct { | ||
Target ottl.StandardStringGetter[K] | ||
} | ||
|
||
func NewHexToIntFactory[K any]() ottl.Factory[K] { | ||
return ottl.NewFactory("HexToInt", &HexToIntArguments[K]{}, createHexToIntFunction[K]) | ||
} | ||
|
||
func createHexToIntFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[K], error) { | ||
args, ok := oArgs.(*HexToIntArguments[K]) | ||
|
||
if !ok { | ||
return nil, fmt.Errorf("HexToIntFactory args must be of type *HexToIntArguments[K]") | ||
} | ||
|
||
return hexToInt(args.Target) | ||
} | ||
|
||
func hexToInt[K any](target ottl.StandardStringGetter[K]) (ottl.ExprFunc[K], error) { | ||
|
||
return func(ctx context.Context, tCtx K) (interface{}, error) { | ||
val, err := target.Get(ctx, tCtx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
normalized := strings.TrimPrefix(strings.ToLower(val), "0x") | ||
result, err := strconv.ParseInt(normalized, 16, 64) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not parse hex value %s: %w", val, err) | ||
} | ||
return result, nil | ||
}, nil | ||
} |
60 changes: 60 additions & 0 deletions
60
processor/signoztransformprocessor/ottlfunctions/func_hex_to_int_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package ottlfunctions | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestHexToInt(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
target string | ||
expected int64 | ||
shouldError bool | ||
}{ | ||
{ | ||
name: "value with prefix", | ||
target: "0xaB", | ||
expected: int64(171), | ||
shouldError: false, | ||
}, { | ||
name: "value without prefix", | ||
target: "ab", | ||
expected: int64(171), | ||
shouldError: false, | ||
}, { | ||
name: "odd length value", | ||
target: "aAa", | ||
expected: int64(2730), | ||
shouldError: false, | ||
}, { | ||
name: "non-hex value", | ||
target: "zz", | ||
shouldError: true, | ||
expected: 0, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
target := ottl.StandardStringGetter[any]{ | ||
Getter: func(ctx context.Context, tCtx any) (interface{}, error) { | ||
return tt.target, nil | ||
}, | ||
} | ||
|
||
fn, err := hexToInt(target) | ||
assert.NoError(t, err) | ||
|
||
result, err := fn(context.Background(), nil) | ||
if tt.shouldError { | ||
assert.Error(t, err) | ||
} else { | ||
assert.NoError(t, err) | ||
assert.Equal(t, result, tt.expected) | ||
} | ||
}) | ||
} | ||
} |