Skip to content

Commit a0478c9

Browse files
authored
fix(ottl): enforce valid types for setters in contexts (#43505)
#### Description Introduce a common utility to check for the expected type and returns a consistent error message. Also applies the use of this utility to ctxscope, ctxlog and ctxmetric. #### Link to tracking issue Fixes #40198 #### Testing Adds testing for the new utility, will address any tests whose behavior is changed by this propagation of error that didn't exist before. #### TODO As it is now, the PR changes some but not all setters, I can either apply them all here or create a followup PR with more refactorings. #### Alternate designs Introducing a new helper in ctxerror was considered but it can be done at a later stage, as it requires consensus on the set of metadata that such helper would require or optional (e.g. context name, path segment).
1 parent 7a7db5b commit a0478c9

File tree

6 files changed

+198
-75
lines changed

6 files changed

+198
-75
lines changed

.chloggen/fix_40198_simple.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
7+
component: pkg/ottl
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Return errors when OTTL context setters receive values of the wrong type
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [40198]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
Introduces `ctxutil.ExpectType` and updates log, metric, and scope setters to surface type assertion failures.
20+
21+
# If your change doesn't affect end users or the exported elements of any package,
22+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
23+
# Optional: The change log or logs in which this entry should be included.
24+
# e.g. '[user]' or '[user, api]'
25+
# Include 'user' if the change is relevant to end users.
26+
# Include 'api' if there is a change to a library API.
27+
# Default: '[user]'
28+
change_logs: [api, user]

pkg/ottl/contexts/internal/ctxlog/log.go

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ func accessTimeUnixNano[K Context]() ottl.StandardGetSetter[K] {
8888
return tCtx.GetLogRecord().Timestamp().AsTime().UnixNano(), nil
8989
},
9090
Setter: func(_ context.Context, tCtx K, val any) error {
91-
if i, ok := val.(int64); ok {
92-
tCtx.GetLogRecord().SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i)))
91+
i, err := ctxutil.ExpectType[int64](val)
92+
if err != nil {
93+
return err
9394
}
95+
tCtx.GetLogRecord().SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i)))
9496
return nil
9597
},
9698
}
@@ -102,9 +104,11 @@ func accessObservedTimeUnixNano[K Context]() ottl.StandardGetSetter[K] {
102104
return tCtx.GetLogRecord().ObservedTimestamp().AsTime().UnixNano(), nil
103105
},
104106
Setter: func(_ context.Context, tCtx K, val any) error {
105-
if i, ok := val.(int64); ok {
106-
tCtx.GetLogRecord().SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i)))
107+
i, err := ctxutil.ExpectType[int64](val)
108+
if err != nil {
109+
return err
107110
}
111+
tCtx.GetLogRecord().SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, i)))
108112
return nil
109113
},
110114
}
@@ -116,9 +120,11 @@ func accessTime[K Context]() ottl.StandardGetSetter[K] {
116120
return tCtx.GetLogRecord().Timestamp().AsTime(), nil
117121
},
118122
Setter: func(_ context.Context, tCtx K, val any) error {
119-
if i, ok := val.(time.Time); ok {
120-
tCtx.GetLogRecord().SetTimestamp(pcommon.NewTimestampFromTime(i))
123+
i, err := ctxutil.ExpectType[time.Time](val)
124+
if err != nil {
125+
return err
121126
}
127+
tCtx.GetLogRecord().SetTimestamp(pcommon.NewTimestampFromTime(i))
122128
return nil
123129
},
124130
}
@@ -130,9 +136,11 @@ func accessObservedTime[K Context]() ottl.StandardGetSetter[K] {
130136
return tCtx.GetLogRecord().ObservedTimestamp().AsTime(), nil
131137
},
132138
Setter: func(_ context.Context, tCtx K, val any) error {
133-
if i, ok := val.(time.Time); ok {
134-
tCtx.GetLogRecord().SetObservedTimestamp(pcommon.NewTimestampFromTime(i))
139+
i, err := ctxutil.ExpectType[time.Time](val)
140+
if err != nil {
141+
return err
135142
}
143+
tCtx.GetLogRecord().SetObservedTimestamp(pcommon.NewTimestampFromTime(i))
136144
return nil
137145
},
138146
}
@@ -144,9 +152,11 @@ func accessSeverityNumber[K Context]() ottl.StandardGetSetter[K] {
144152
return int64(tCtx.GetLogRecord().SeverityNumber()), nil
145153
},
146154
Setter: func(_ context.Context, tCtx K, val any) error {
147-
if i, ok := val.(int64); ok {
148-
tCtx.GetLogRecord().SetSeverityNumber(plog.SeverityNumber(i))
155+
i, err := ctxutil.ExpectType[int64](val)
156+
if err != nil {
157+
return err
149158
}
159+
tCtx.GetLogRecord().SetSeverityNumber(plog.SeverityNumber(i))
150160
return nil
151161
},
152162
}
@@ -158,9 +168,11 @@ func accessSeverityText[K Context]() ottl.StandardGetSetter[K] {
158168
return tCtx.GetLogRecord().SeverityText(), nil
159169
},
160170
Setter: func(_ context.Context, tCtx K, val any) error {
161-
if s, ok := val.(string); ok {
162-
tCtx.GetLogRecord().SetSeverityText(s)
171+
s, err := ctxutil.ExpectType[string](val)
172+
if err != nil {
173+
return err
163174
}
175+
tCtx.GetLogRecord().SetSeverityText(s)
164176
return nil
165177
},
166178
}
@@ -210,9 +222,11 @@ func accessStringBody[K Context]() ottl.StandardGetSetter[K] {
210222
return tCtx.GetLogRecord().Body().AsString(), nil
211223
},
212224
Setter: func(_ context.Context, tCtx K, val any) error {
213-
if str, ok := val.(string); ok {
214-
tCtx.GetLogRecord().Body().SetStr(str)
225+
str, err := ctxutil.ExpectType[string](val)
226+
if err != nil {
227+
return err
215228
}
229+
tCtx.GetLogRecord().Body().SetStr(str)
216230
return nil
217231
},
218232
}
@@ -246,9 +260,11 @@ func accessDroppedAttributesCount[K Context]() ottl.StandardGetSetter[K] {
246260
return int64(tCtx.GetLogRecord().DroppedAttributesCount()), nil
247261
},
248262
Setter: func(_ context.Context, tCtx K, val any) error {
249-
if i, ok := val.(int64); ok {
250-
tCtx.GetLogRecord().SetDroppedAttributesCount(uint32(i))
263+
i, err := ctxutil.ExpectType[int64](val)
264+
if err != nil {
265+
return err
251266
}
267+
tCtx.GetLogRecord().SetDroppedAttributesCount(uint32(i))
252268
return nil
253269
},
254270
}
@@ -260,9 +276,11 @@ func accessFlags[K Context]() ottl.StandardGetSetter[K] {
260276
return int64(tCtx.GetLogRecord().Flags()), nil
261277
},
262278
Setter: func(_ context.Context, tCtx K, val any) error {
263-
if i, ok := val.(int64); ok {
264-
tCtx.GetLogRecord().SetFlags(plog.LogRecordFlags(i))
279+
i, err := ctxutil.ExpectType[int64](val)
280+
if err != nil {
281+
return err
265282
}
283+
tCtx.GetLogRecord().SetFlags(plog.LogRecordFlags(i))
266284
return nil
267285
},
268286
}
@@ -274,9 +292,11 @@ func accessTraceID[K Context]() ottl.StandardGetSetter[K] {
274292
return tCtx.GetLogRecord().TraceID(), nil
275293
},
276294
Setter: func(_ context.Context, tCtx K, val any) error {
277-
if newTraceID, ok := val.(pcommon.TraceID); ok {
278-
tCtx.GetLogRecord().SetTraceID(newTraceID)
295+
newTraceID, err := ctxutil.ExpectType[pcommon.TraceID](val)
296+
if err != nil {
297+
return err
279298
}
299+
tCtx.GetLogRecord().SetTraceID(newTraceID)
280300
return nil
281301
},
282302
}
@@ -289,13 +309,15 @@ func accessStringTraceID[K Context]() ottl.StandardGetSetter[K] {
289309
return hex.EncodeToString(id[:]), nil
290310
},
291311
Setter: func(_ context.Context, tCtx K, val any) error {
292-
if str, ok := val.(string); ok {
293-
id, err := ctxcommon.ParseTraceID(str)
294-
if err != nil {
295-
return err
296-
}
297-
tCtx.GetLogRecord().SetTraceID(id)
312+
str, err := ctxutil.ExpectType[string](val)
313+
if err != nil {
314+
return err
298315
}
316+
id, err := ctxcommon.ParseTraceID(str)
317+
if err != nil {
318+
return err
319+
}
320+
tCtx.GetLogRecord().SetTraceID(id)
299321
return nil
300322
},
301323
}
@@ -307,9 +329,11 @@ func accessSpanID[K Context]() ottl.StandardGetSetter[K] {
307329
return tCtx.GetLogRecord().SpanID(), nil
308330
},
309331
Setter: func(_ context.Context, tCtx K, val any) error {
310-
if newSpanID, ok := val.(pcommon.SpanID); ok {
311-
tCtx.GetLogRecord().SetSpanID(newSpanID)
332+
newSpanID, err := ctxutil.ExpectType[pcommon.SpanID](val)
333+
if err != nil {
334+
return err
312335
}
336+
tCtx.GetLogRecord().SetSpanID(newSpanID)
313337
return nil
314338
},
315339
}
@@ -322,13 +346,15 @@ func accessStringSpanID[K Context]() ottl.StandardGetSetter[K] {
322346
return hex.EncodeToString(id[:]), nil
323347
},
324348
Setter: func(_ context.Context, tCtx K, val any) error {
325-
if str, ok := val.(string); ok {
326-
id, err := ctxcommon.ParseSpanID(str)
327-
if err != nil {
328-
return err
329-
}
330-
tCtx.GetLogRecord().SetSpanID(id)
349+
str, err := ctxutil.ExpectType[string](val)
350+
if err != nil {
351+
return err
352+
}
353+
id, err := ctxcommon.ParseSpanID(str)
354+
if err != nil {
355+
return err
331356
}
357+
tCtx.GetLogRecord().SetSpanID(id)
332358
return nil
333359
},
334360
}
@@ -340,9 +366,11 @@ func accessEventName[K Context]() ottl.StandardGetSetter[K] {
340366
return tCtx.GetLogRecord().EventName(), nil
341367
},
342368
Setter: func(_ context.Context, tCtx K, val any) error {
343-
if v, ok := val.(string); ok {
344-
tCtx.GetLogRecord().SetEventName(v)
369+
v, err := ctxutil.ExpectType[string](val)
370+
if err != nil {
371+
return err
345372
}
373+
tCtx.GetLogRecord().SetEventName(v)
346374
return nil
347375
},
348376
}

pkg/ottl/contexts/internal/ctxmetric/metric.go

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ func accessName[K Context]() ottl.StandardGetSetter[K] {
4848
return tCtx.GetMetric().Name(), nil
4949
},
5050
Setter: func(_ context.Context, tCtx K, val any) error {
51-
if str, ok := val.(string); ok {
52-
tCtx.GetMetric().SetName(str)
51+
str, err := ctxutil.ExpectType[string](val)
52+
if err != nil {
53+
return err
5354
}
55+
tCtx.GetMetric().SetName(str)
5456
return nil
5557
},
5658
}
@@ -62,9 +64,11 @@ func accessDescription[K Context]() ottl.StandardGetSetter[K] {
6264
return tCtx.GetMetric().Description(), nil
6365
},
6466
Setter: func(_ context.Context, tCtx K, val any) error {
65-
if str, ok := val.(string); ok {
66-
tCtx.GetMetric().SetDescription(str)
67+
str, err := ctxutil.ExpectType[string](val)
68+
if err != nil {
69+
return err
6770
}
71+
tCtx.GetMetric().SetDescription(str)
6872
return nil
6973
},
7074
}
@@ -76,9 +80,11 @@ func accessUnit[K Context]() ottl.StandardGetSetter[K] {
7680
return tCtx.GetMetric().Unit(), nil
7781
},
7882
Setter: func(_ context.Context, tCtx K, val any) error {
79-
if str, ok := val.(string); ok {
80-
tCtx.GetMetric().SetUnit(str)
83+
str, err := ctxutil.ExpectType[string](val)
84+
if err != nil {
85+
return err
8186
}
87+
tCtx.GetMetric().SetUnit(str)
8288
return nil
8389
},
8490
}
@@ -112,16 +118,18 @@ func accessAggTemporality[K Context]() ottl.StandardGetSetter[K] {
112118
return nil, nil
113119
},
114120
Setter: func(_ context.Context, tCtx K, val any) error {
115-
if newAggTemporality, ok := val.(int64); ok {
116-
metric := tCtx.GetMetric()
117-
switch metric.Type() {
118-
case pmetric.MetricTypeSum:
119-
metric.Sum().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
120-
case pmetric.MetricTypeHistogram:
121-
metric.Histogram().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
122-
case pmetric.MetricTypeExponentialHistogram:
123-
metric.ExponentialHistogram().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
124-
}
121+
newAggTemporality, err := ctxutil.ExpectType[int64](val)
122+
if err != nil {
123+
return err
124+
}
125+
metric := tCtx.GetMetric()
126+
switch metric.Type() {
127+
case pmetric.MetricTypeSum:
128+
metric.Sum().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
129+
case pmetric.MetricTypeHistogram:
130+
metric.Histogram().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
131+
case pmetric.MetricTypeExponentialHistogram:
132+
metric.ExponentialHistogram().SetAggregationTemporality(pmetric.AggregationTemporality(newAggTemporality))
125133
}
126134
return nil
127135
},
@@ -138,11 +146,13 @@ func accessIsMonotonic[K Context]() ottl.StandardGetSetter[K] {
138146
return nil, nil
139147
},
140148
Setter: func(_ context.Context, tCtx K, val any) error {
141-
if newIsMonotonic, ok := val.(bool); ok {
142-
metric := tCtx.GetMetric()
143-
if metric.Type() == pmetric.MetricTypeSum {
144-
metric.Sum().SetIsMonotonic(newIsMonotonic)
145-
}
149+
newIsMonotonic, err := ctxutil.ExpectType[bool](val)
150+
if err != nil {
151+
return err
152+
}
153+
metric := tCtx.GetMetric()
154+
if metric.Type() == pmetric.MetricTypeSum {
155+
metric.Sum().SetIsMonotonic(newIsMonotonic)
146156
}
147157
return nil
148158
},
@@ -171,25 +181,35 @@ func accessDataPoints[K Context]() ottl.StandardGetSetter[K] {
171181
metric := tCtx.GetMetric()
172182
switch metric.Type() {
173183
case pmetric.MetricTypeSum:
174-
if newDataPoints, ok := val.(pmetric.NumberDataPointSlice); ok {
175-
newDataPoints.CopyTo(metric.Sum().DataPoints())
184+
newDataPoints, err := ctxutil.ExpectType[pmetric.NumberDataPointSlice](val)
185+
if err != nil {
186+
return err
176187
}
188+
newDataPoints.CopyTo(metric.Sum().DataPoints())
177189
case pmetric.MetricTypeGauge:
178-
if newDataPoints, ok := val.(pmetric.NumberDataPointSlice); ok {
179-
newDataPoints.CopyTo(metric.Gauge().DataPoints())
190+
newDataPoints, err := ctxutil.ExpectType[pmetric.NumberDataPointSlice](val)
191+
if err != nil {
192+
return err
180193
}
194+
newDataPoints.CopyTo(metric.Gauge().DataPoints())
181195
case pmetric.MetricTypeHistogram:
182-
if newDataPoints, ok := val.(pmetric.HistogramDataPointSlice); ok {
183-
newDataPoints.CopyTo(metric.Histogram().DataPoints())
196+
newDataPoints, err := ctxutil.ExpectType[pmetric.HistogramDataPointSlice](val)
197+
if err != nil {
198+
return err
184199
}
200+
newDataPoints.CopyTo(metric.Histogram().DataPoints())
185201
case pmetric.MetricTypeExponentialHistogram:
186-
if newDataPoints, ok := val.(pmetric.ExponentialHistogramDataPointSlice); ok {
187-
newDataPoints.CopyTo(metric.ExponentialHistogram().DataPoints())
202+
newDataPoints, err := ctxutil.ExpectType[pmetric.ExponentialHistogramDataPointSlice](val)
203+
if err != nil {
204+
return err
188205
}
206+
newDataPoints.CopyTo(metric.ExponentialHistogram().DataPoints())
189207
case pmetric.MetricTypeSummary:
190-
if newDataPoints, ok := val.(pmetric.SummaryDataPointSlice); ok {
191-
newDataPoints.CopyTo(metric.Summary().DataPoints())
208+
newDataPoints, err := ctxutil.ExpectType[pmetric.SummaryDataPointSlice](val)
209+
if err != nil {
210+
return err
192211
}
212+
newDataPoints.CopyTo(metric.Summary().DataPoints())
193213
}
194214
return nil
195215
},

0 commit comments

Comments
 (0)