Skip to content

Commit

Permalink
[pkg/telemetryquerylanguage] Add split function to TQL (#13430)
Browse files Browse the repository at this point in the history
* Add split function to TQL

* Change to factory function

* Add test case for empty string and delimiter

* Fix import group
  • Loading branch information
linjunzhe authored Sep 8, 2022
1 parent 8d54b7d commit 566a6dc
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 0 deletions.
16 changes: 16 additions & 0 deletions pkg/telemetryquerylanguage/functions/tqlotel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The following functions are intended to be used in implementations of the Teleme
Factory Functions
- [SpanID](#spanid)
- [TraceID](#traceid)
- [Split](#split)

Functions
- [delete_key](#delete_key)
Expand All @@ -15,6 +16,7 @@ Functions
- [replace_all_matches](#replace_all_matches)
- [replace_all_patterns](#replace_all_patterns)


## SpanID

`SpanID(bytes)`
Expand Down Expand Up @@ -147,3 +149,17 @@ If one or more sections of `target` match `regex` they will get replaced with `r
Examples:

- `replace_all_patterns(attributes, "/account/\\d{4}", "/account/{accountId}")`

## Split

`Split(target, delimiter)`

The `Split` factory function separates a string by the delimiter, and returns an array of substrings.

`target` is a string. `delimiter` is a string.

If the `target` is not a string or does not exist, the `Split` factory function will return `nil`.

Examples:

- ```Split("A|B|C", "|")```
32 changes: 32 additions & 0 deletions pkg/telemetryquerylanguage/functions/tqlotel/func_split.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tqlotel // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/telemetryquerylanguage/functions/tqlotel"

import (
"strings"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/telemetryquerylanguage/tql"
)

func Split(target tql.Getter, delimiter string) (tql.ExprFunc, error) {
return func(ctx tql.TransformContext) interface{} {
if val := target.Get(ctx); val != nil {
if valStr, ok := val.(string); ok {
return strings.Split(valStr, delimiter)
}
}
return nil
}, nil
}
94 changes: 94 additions & 0 deletions pkg/telemetryquerylanguage/functions/tqlotel/func_split_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tqlotel

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/telemetryquerylanguage/tql"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/telemetryquerylanguage/tql/tqltest"
)

func Test_split(t *testing.T) {
tests := []struct {
name string
target tql.Getter
delimiter string
expected interface{}
}{
{
name: "split string",
target: &tql.StandardGetSetter{
Getter: func(ctx tql.TransformContext) interface{} {
return "A|B|C"
},
},
delimiter: "|",
expected: []string{"A", "B", "C"},
},
{
name: "split empty string",
target: &tql.StandardGetSetter{
Getter: func(ctx tql.TransformContext) interface{} {
return ""
},
},
delimiter: "|",
expected: []string{""},
},
{
name: "split empty delimiter",
target: &tql.StandardGetSetter{
Getter: func(ctx tql.TransformContext) interface{} {
return "A|B|C"
},
},
delimiter: "",
expected: []string{"A", "|", "B", "|", "C"},
},
{
name: "split empty string and empty delimiter",
target: &tql.StandardGetSetter{
Getter: func(ctx tql.TransformContext) interface{} {
return ""
},
},
delimiter: "",
expected: []string{},
},
{
name: "split non-string",
target: &tql.StandardGetSetter{
Getter: func(ctx tql.TransformContext) interface{} {
return 123
},
},
delimiter: "|",
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := tqltest.TestTransformContext{}

exprFunc, _ := Split(tt.target, tt.delimiter)
actual := exprFunc(ctx)

assert.Equal(t, tt.expected, actual)
})
}
}
16 changes: 16 additions & 0 deletions unreleased/tql_split_function.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: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: telemetryquerylanguage

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add split factory function to separate a string by the delimiter, and returns an array of substrings.

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

# (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:

0 comments on commit 566a6dc

Please sign in to comment.