Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pkg/ottl] Update grammar to enforce paths terminate with brackets if included. #20528

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .chloggen/ottl-adjust-fields.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: Remove ability to specify identifiers after brackets in a path.

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

# (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: The change has no impact on any of the standard OTTL contexts, transformprocessor, filterprocessor, or routingprocessor. It is only a breaking change if you have implemented your own context and were taking advantage of dots after bracket indexing.
6 changes: 3 additions & 3 deletions pkg/ottl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ Values are passed as input to an Invocation or are used in a Boolean Expression.
- [Literals](#literals)
- [Enums](#enums)
- [Converters](#converters)
- [Math Expressions](#math_expressions)
- [Math Expressions](#math-expressions)

#### Paths

A Path Value is a reference to a telemetry field. Paths are made up of lowercase identifiers, dots (`.`), and square brackets combined with a string key (`["key"]`). **The interpretation of a Path is NOT implemented by the OTTL.** Instead, the user must provide a `PathExpressionParser` that the OTTL can use to interpret paths. As a result, how the Path parts are used is up to the user. However, it is recommended, that the parts be used like so:
A Path Value is a reference to a telemetry field. Paths are made up of lowercase identifiers separated by dots (`.`), optionally terminating with square brackets combined with a string key (`["key"]`). Dots (`.`) and lowercase identifiers cannot be used after brackets/keys (`["key"]`). **The interpretation of a Path is NOT implemented by the OTTL.** Instead, the user must provide a `PathExpressionParser` that the OTTL can use to interpret paths. As a result, how the Path parts are used is up to the user. However, it is recommended, that the parts be used like so:

- Identifiers are used to map to a telemetry field.
- Dots (`.`) are used to separate nested fields.
- Square brackets and keys (`["key"]`) are used to access values within maps.

When accessing a map's value, if the given key does not exist, `nil` will be returned.
This can be used to check for the presence of a key within a map within a [Boolean Expression](#boolean_expressions).
This can be used to check for the presence of a key within a map within a [Boolean Expression](#boolean-expressions).

Example Paths
- `name`
Expand Down
6 changes: 2 additions & 4 deletions pkg/ottl/boolean_value_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,8 @@ func valueFor(x any) value {
// if the string is NAME construct a path of "name".
val.Literal = &mathExprLiteral{
Path: &Path{
Fields: []Field{
{
Name: "name",
},
Fields: []string{
"name",
},
},
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/ottl/contexts/internal/ottlcommon/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ var MetricSymbolTable = map[ottl.EnumSymbol]ottl.Enum{
"METRIC_DATA_TYPE_SUMMARY": ottl.Enum(pmetric.MetricTypeSummary),
}

func MetricPathGetSetter[K MetricContext](path []ottl.Field) (ottl.GetSetter[K], error) {
if len(path) == 0 {
func MetricPathGetSetter[K MetricContext](path ottl.Path) (ottl.GetSetter[K], error) {
if len(path.Fields) == 0 {
return accessMetric[K](), nil
}
switch path[0].Name {
switch path.Fields[0] {
case "name":
return accessName[K](), nil
case "description":
Expand Down
46 changes: 16 additions & 30 deletions pkg/ottl/contexts/internal/ottlcommon/metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ func Test_MetricPathGetSetter(t *testing.T) {

tests := []struct {
name string
path []ottl.Field
fields []string
orig interface{}
newVal interface{}
modified func(metric pmetric.Metric)
}{
{
name: "metric name",
path: []ottl.Field{
{
Name: "name",
},
fields: []string{
"name",
},
orig: "name",
newVal: "new name",
Expand All @@ -57,10 +55,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric description",
path: []ottl.Field{
{
Name: "description",
},
fields: []string{
"description",
},
orig: "description",
newVal: "new description",
Expand All @@ -70,10 +66,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric unit",
path: []ottl.Field{
{
Name: "unit",
},
fields: []string{
"unit",
},
orig: "unit",
newVal: "new unit",
Expand All @@ -83,10 +77,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric type",
path: []ottl.Field{
{
Name: "type",
},
fields: []string{
"type",
},
orig: int64(pmetric.MetricTypeSum),
newVal: int64(pmetric.MetricTypeSum),
Expand All @@ -95,10 +87,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric aggregation_temporality",
path: []ottl.Field{
{
Name: "aggregation_temporality",
},
fields: []string{
"aggregation_temporality",
},
orig: int64(2),
newVal: int64(1),
Expand All @@ -108,10 +98,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric is_monotonic",
path: []ottl.Field{
{
Name: "is_monotonic",
},
fields: []string{
"is_monotonic",
},
orig: true,
newVal: false,
Expand All @@ -121,10 +109,8 @@ func Test_MetricPathGetSetter(t *testing.T) {
},
{
name: "metric data points",
path: []ottl.Field{
{
Name: "data_points",
},
fields: []string{
"data_points",
},
orig: refMetric.Sum().DataPoints(),
newVal: newDataPoints,
Expand All @@ -135,7 +121,7 @@ func Test_MetricPathGetSetter(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
accessor, err := MetricPathGetSetter[*metricContext](tt.path)
accessor, err := MetricPathGetSetter[*metricContext](ottl.Path{Fields: tt.fields})
assert.NoError(t, err)

metric := createMetricTelemetry()
Expand Down
11 changes: 5 additions & 6 deletions pkg/ottl/contexts/internal/ottlcommon/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ type ResourceContext interface {
GetResource() pcommon.Resource
}

func ResourcePathGetSetter[K ResourceContext](path []ottl.Field) (ottl.GetSetter[K], error) {
if len(path) == 0 {
func ResourcePathGetSetter[K ResourceContext](path ottl.Path) (ottl.GetSetter[K], error) {
if len(path.Fields) == 0 {
return accessResource[K](), nil
}
switch path[0].Name {
switch path.Fields[0] {
case "attributes":
mapKey := path[0].MapKey
if mapKey == nil {
if path.MapKey == nil {
return accessResourceAttributes[K](), nil
}
return accessResourceAttributesKey[K](mapKey), nil
return accessResourceAttributesKey[K](path.MapKey), nil
case "dropped_attributes_count":
return accessResourceDroppedAttributesCount[K](), nil
}
Expand Down
Loading