Skip to content

Commit 1092522

Browse files
TylerHelmuthevan-bradley
authored andcommitted
Improve OTTL error message (open-telemetry#31233)
**Description:** Improve OTTL context error messages when an unknown path is used. The new error message will look like: ``` Error: invalid configuration: processors::transform: unable to parse OTTL statement "set(attributes[\"test\"], trace_id.hex)": error while parsing arguments for call to "set": invalid argument at position 1: trace_id.hex is not a valid path for the Span context - review https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlspan to see all valid paths ``` **Link to tracking Issue:** <Issue number if applicable> Related to open-telemetry#29871 Closes open-telemetry#29922 **Testing:** <Describe what testing was performed and which tests were added.> Unit tests --------- Co-authored-by: Evan Bradley <[email protected]>
1 parent 5245b05 commit 1092522

File tree

11 files changed

+147
-58
lines changed

11 files changed

+147
-58
lines changed

pkg/ottl/contexts/internal/errors.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal"
5+
6+
import "fmt"
7+
8+
const (
9+
DefaultErrorMessage = "segment %q from path %q is not a valid path nor a valid OTTL keyword for the %v context - review %v to see all valid paths"
10+
11+
ResourceContextRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlresource"
12+
InstrumentationScopeRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlscope"
13+
SpanRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlspan"
14+
SpanEventRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlspanevent"
15+
MetricRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlmetric"
16+
DataPointRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottldatapoint"
17+
LogRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottllog"
18+
)
19+
20+
func FormatDefaultErrorMessage(pathSegment, fullPath, context, ref string) error {
21+
return fmt.Errorf(DefaultErrorMessage, pathSegment, fullPath, context, ref)
22+
}

pkg/ottl/contexts/internal/metric.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-co
55

66
import (
77
"context"
8-
"fmt"
98

109
"go.opentelemetry.io/collector/pdata/pmetric"
1110

@@ -48,7 +47,7 @@ func MetricPathGetSetter[K MetricContext](path ottl.Path[K]) (ottl.GetSetter[K],
4847
case "data_points":
4948
return accessDataPoints[K](), nil
5049
default:
51-
return nil, fmt.Errorf("invalid metric path expression %v", path)
50+
return nil, FormatDefaultErrorMessage(path.Name(), path.String(), "Metric", MetricRef)
5251
}
5352
}
5453

pkg/ottl/contexts/internal/path.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ func (p *TestPath[K]) Keys() []ottl.Key[K] {
3232
return p.KeySlice
3333
}
3434

35+
func (p *TestPath[K]) String() string {
36+
return p.N
37+
}
38+
3539
var _ ottl.Key[any] = &TestKey[any]{}
3640

3741
type TestKey[K any] struct {

pkg/ottl/contexts/internal/resource.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-co
55

66
import (
77
"context"
8-
"fmt"
98

109
"go.opentelemetry.io/collector/pdata/pcommon"
1110

@@ -29,7 +28,7 @@ func ResourcePathGetSetter[K ResourceContext](path ottl.Path[K]) (ottl.GetSetter
2928
case "dropped_attributes_count":
3029
return accessResourceDroppedAttributesCount[K](), nil
3130
default:
32-
return nil, fmt.Errorf("invalid resource path expression %v", path)
31+
return nil, FormatDefaultErrorMessage(path.Name(), path.String(), "Resource", ResourceContextRef)
3332
}
3433
}
3534

pkg/ottl/contexts/internal/scope.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-co
55

66
import (
77
"context"
8-
"fmt"
98

109
"go.opentelemetry.io/collector/pdata/pcommon"
1110

@@ -34,7 +33,7 @@ func ScopePathGetSetter[K InstrumentationScopeContext](path ottl.Path[K]) (ottl.
3433
case "dropped_attributes_count":
3534
return accessInstrumentationScopeDroppedAttributesCount[K](), nil
3635
default:
37-
return nil, fmt.Errorf("invalid scope path expression %v", path)
36+
return nil, FormatDefaultErrorMessage(path.Name(), path.String(), "Instrumentation Scope", InstrumentationScopeRef)
3837
}
3938
}
4039

pkg/ottl/contexts/internal/span.go

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import (
1717
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
1818
)
1919

20+
const (
21+
SpanContextName = "Span"
22+
)
23+
2024
type SpanContext interface {
2125
GetSpan() ptrace.Span
2226
}
@@ -39,35 +43,38 @@ func SpanPathGetSetter[K SpanContext](path ottl.Path[K]) (ottl.GetSetter[K], err
3943
}
4044
switch path.Name() {
4145
case "trace_id":
42-
if path.Next() != nil {
43-
if path.Next().Name() == "string" {
46+
nextPath := path.Next()
47+
if nextPath != nil {
48+
if nextPath.Name() == "string" {
4449
return accessStringTraceID[K](), nil
4550
}
46-
} else {
47-
return accessTraceID[K](), nil
51+
return nil, FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), SpanContextName, SpanRef)
4852
}
53+
return accessTraceID[K](), nil
4954
case "span_id":
50-
if path.Next() != nil {
51-
if path.Next().Name() == "string" {
55+
nextPath := path.Next()
56+
if nextPath != nil {
57+
if nextPath.Name() == "string" {
5258
return accessStringSpanID[K](), nil
5359
}
54-
} else {
55-
return accessSpanID[K](), nil
60+
return nil, FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), SpanContextName, SpanRef)
5661
}
62+
return accessSpanID[K](), nil
5763
case "trace_state":
5864
mapKey := path.Keys()
5965
if mapKey == nil {
6066
return accessTraceState[K](), nil
6167
}
6268
return accessTraceStateKey[K](mapKey)
6369
case "parent_span_id":
64-
if path.Next() != nil {
65-
if path.Next().Name() == "string" {
70+
nextPath := path.Next()
71+
if nextPath != nil {
72+
if nextPath.Name() == "string" {
6673
return accessStringParentSpanID[K](), nil
6774
}
68-
} else {
69-
return accessParentSpanID[K](), nil
75+
return nil, FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), SpanContextName, SpanRef)
7076
}
77+
return accessParentSpanID[K](), nil
7178
case "name":
7279
return accessSpanName[K](), nil
7380
case "kind":
@@ -79,11 +86,10 @@ func SpanPathGetSetter[K SpanContext](path ottl.Path[K]) (ottl.GetSetter[K], err
7986
case "deprecated_string":
8087
return accessDeprecatedStringKind[K](), nil
8188
default:
82-
return nil, fmt.Errorf("invalid span path expression %v", nextPath.Name())
89+
return nil, FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), SpanContextName, SpanRef)
8390
}
84-
} else {
85-
return accessKind[K](), nil
8691
}
92+
return accessKind[K](), nil
8793
case "start_time_unix_nano":
8894
return accessStartTimeUnixNano[K](), nil
8995
case "end_time_unix_nano":
@@ -117,13 +123,13 @@ func SpanPathGetSetter[K SpanContext](path ottl.Path[K]) (ottl.GetSetter[K], err
117123
case "message":
118124
return accessStatusMessage[K](), nil
119125
default:
120-
return nil, fmt.Errorf("invalid span path expression %v", nextPath.Name())
126+
return nil, FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), SpanContextName, SpanRef)
121127
}
122-
} else {
123-
return accessStatus[K](), nil
124128
}
129+
return accessStatus[K](), nil
130+
default:
131+
return nil, FormatDefaultErrorMessage(path.Name(), path.String(), SpanContextName, SpanRef)
125132
}
126-
return nil, fmt.Errorf("invalid span path expression %v", path)
127133
}
128134

129135
func accessSpan[K SpanContext]() ottl.StandardGetSetter[K] {

pkg/ottl/contexts/ottldatapoint/datapoint.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal"
1717
)
1818

19+
const (
20+
contextName = "DataPoint"
21+
)
22+
1923
var _ internal.ResourceContext = TransformContext{}
2024
var _ internal.InstrumentationScopeContext = TransformContext{}
2125

@@ -197,11 +201,10 @@ func (pep *pathExpressionParser) parsePath(path ottl.Path[TransformContext]) (ot
197201
case "bucket_counts":
198202
return accessPositiveBucketCounts(), nil
199203
default:
200-
return nil, fmt.Errorf("invalid span path expression %v", nextPath.Name())
204+
return nil, internal.FormatDefaultErrorMessage(nextPath.Name(), path.String(), contextName, internal.DataPointRef)
201205
}
202-
} else {
203-
return accessPositive(), nil
204206
}
207+
return accessPositive(), nil
205208
case "negative":
206209
nextPath := path.Next()
207210
if nextPath != nil {
@@ -211,15 +214,15 @@ func (pep *pathExpressionParser) parsePath(path ottl.Path[TransformContext]) (ot
211214
case "bucket_counts":
212215
return accessNegativeBucketCounts(), nil
213216
default:
214-
return nil, fmt.Errorf("invalid span path expression %v", nextPath.Name())
217+
return nil, internal.FormatDefaultErrorMessage(nextPath.Name(), path.String(), contextName, internal.DataPointRef)
215218
}
216-
} else {
217-
return accessNegative(), nil
218219
}
220+
return accessNegative(), nil
219221
case "quantile_values":
220222
return accessQuantileValues(), nil
223+
default:
224+
return nil, internal.FormatDefaultErrorMessage(path.Name(), path.String(), contextName, internal.DataPointRef)
221225
}
222-
return nil, fmt.Errorf("invalid path expression %v", path)
223226
}
224227

225228
func accessCache() ottl.StandardGetSetter[TransformContext] {

pkg/ottl/contexts/ottllog/log.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import (
1818
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/internal/ottlcommon"
1919
)
2020

21+
const (
22+
contextName = "Log"
23+
)
24+
2125
var _ internal.ResourceContext = TransformContext{}
2226
var _ internal.InstrumentationScopeContext = TransformContext{}
2327

@@ -173,16 +177,17 @@ func (pep *pathExpressionParser) parsePath(path ottl.Path[TransformContext]) (ot
173177
case "severity_text":
174178
return accessSeverityText(), nil
175179
case "body":
176-
if path.Next() != nil {
177-
if path.Next().Name() == "string" {
180+
nextPath := path.Next()
181+
if nextPath != nil {
182+
if nextPath.Name() == "string" {
178183
return accessStringBody(), nil
179184
}
180-
} else {
181-
if path.Keys() == nil {
182-
return accessBody(), nil
183-
}
184-
return accessBodyKey(path.Keys()), nil
185+
return nil, internal.FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), contextName, internal.LogRef)
186+
}
187+
if path.Keys() == nil {
188+
return accessBody(), nil
185189
}
190+
return accessBodyKey(path.Keys()), nil
186191
case "attributes":
187192
if path.Keys() == nil {
188193
return accessAttributes(), nil
@@ -193,23 +198,26 @@ func (pep *pathExpressionParser) parsePath(path ottl.Path[TransformContext]) (ot
193198
case "flags":
194199
return accessFlags(), nil
195200
case "trace_id":
196-
if path.Next() != nil {
197-
if path.Next().Name() == "string" {
201+
nextPath := path.Next()
202+
if nextPath != nil {
203+
if nextPath.Name() == "string" {
198204
return accessStringTraceID(), nil
199205
}
200-
} else {
201-
return accessTraceID(), nil
206+
return nil, internal.FormatDefaultErrorMessage(nextPath.Name(), nextPath.String(), contextName, internal.LogRef)
202207
}
208+
return accessTraceID(), nil
203209
case "span_id":
204-
if path.Next() != nil {
205-
if path.Next().Name() == "string" {
210+
nextPath := path.Next()
211+
if nextPath != nil {
212+
if nextPath.Name() == "string" {
206213
return accessStringSpanID(), nil
207214
}
208-
} else {
209-
return accessSpanID(), nil
215+
return nil, internal.FormatDefaultErrorMessage(nextPath.Name(), path.String(), contextName, internal.LogRef)
210216
}
217+
return accessSpanID(), nil
218+
default:
219+
return nil, internal.FormatDefaultErrorMessage(path.Name(), path.String(), contextName, internal.LogRef)
211220
}
212-
return nil, fmt.Errorf("invalid path expression %v", path)
213221
}
214222

215223
func accessCache() ottl.StandardGetSetter[TransformContext] {

pkg/ottl/contexts/ottlspanevent/span_events.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,10 @@ func (pep *pathExpressionParser) parsePath(path ottl.Path[TransformContext]) (ot
152152
return accessSpanEventAttributesKey(path.Keys()), nil
153153
case "dropped_attributes_count":
154154
return accessSpanEventDroppedAttributeCount(), nil
155+
default:
156+
return nil, internal.FormatDefaultErrorMessage(path.Name(), path.String(), "Span Event", internal.SpanEventRef)
155157
}
156158

157-
return nil, fmt.Errorf("invalid scope path expression %v", path)
158159
}
159160
func accessCache() ottl.StandardGetSetter[TransformContext] {
160161
return ottl.StandardGetSetter[TransformContext]{

0 commit comments

Comments
 (0)