Skip to content

Commit 9247868

Browse files
committed
[chore] handle breaking change in pdata/pprofile
open-telemetry/opentelemetry-collector#15517 is a breaking change to prevent a panic. Handle this change for OTel collector contrib. Signed-off-by: Florian Lehner <florian.lehner@elastic.co>
1 parent e64fdc5 commit 9247868

6 files changed

Lines changed: 57 additions & 11 deletions

File tree

.chloggen/collector-15517.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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: 'breaking'
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
7+
component: all
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: handle breaking change in pdata/pprofile
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: []
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+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [api]

connector/countconnector/connector.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,12 @@ func (c *count) ConsumeProfiles(ctx context.Context, ld pprofile.Profiles) error
247247
profile := scopeProfile.Profiles().At(k)
248248
counter.updateTimestamp(profile.Time())
249249
pCtx := ottlprofile.NewTransformContextPtr(resourceProfile, scopeProfile, profile, ld.Dictionary())
250-
attributes := pprofile.FromAttributeIndices(ld.Dictionary().AttributeTable(), profile, ld.Dictionary())
251-
multiError = errors.Join(multiError, counter.update(ctx, attributes, scopeAttrs, resourceAttrs, pCtx))
250+
attributes, attrErr := pprofile.FromAttributeIndices(ld.Dictionary().AttributeTable(), profile, ld.Dictionary())
251+
if attrErr != nil {
252+
multiError = errors.Join(multiError, attrErr)
253+
} else {
254+
multiError = errors.Join(multiError, counter.update(ctx, attributes, scopeAttrs, resourceAttrs, pCtx))
255+
}
252256
pCtx.Close()
253257
}
254258
}

connector/signaltometricsconnector/connector.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,10 @@ func (sm *signalToMetrics) ConsumeProfiles(ctx context.Context, profiles pprofil
346346

347347
for k := 0; k < scopeProfile.Profiles().Len(); k++ {
348348
profile := scopeProfile.Profiles().At(k)
349-
profileAttrs := pprofile.FromAttributeIndices(profiles.Dictionary().AttributeTable(), profile, profiles.Dictionary())
349+
profileAttrs, err := pprofile.FromAttributeIndices(profiles.Dictionary().AttributeTable(), profile, profiles.Dictionary())
350+
if err != nil {
351+
return fmt.Errorf("failed to get profile attributes: %w", err)
352+
}
350353
for mdIdx, md := range sm.profileMetricDefs {
351354
if !md.MatchAttributes(profileAttrs) {
352355
continue

exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ func stackPayloads(dic pprofile.ProfilesDictionary, resource pcommon.Resource, s
8383
unsymbolizedExecutablesSet := make(map[libpf.FileID]struct{})
8484
stackPayload := make([]StackPayload, 0, profile.Samples().Len())
8585

86-
commonResourceAttributes := populateResourceData(dic, resource, scope, profile)
86+
commonResourceAttributes, err := populateResourceData(dic, resource, scope, profile)
87+
if err != nil {
88+
return nil, fmt.Errorf("failed to populate resource data: %w", err)
89+
}
8790

8891
frequency := int64(math.Round(1e9 / float64(profile.Period())))
8992
if frequency <= 0 {
@@ -513,16 +516,20 @@ func int64ToBytes(value int64) []byte {
513516
return buf
514517
}
515518

516-
func populateResourceData(dic pprofile.ProfilesDictionary, resource pcommon.Resource, scope pcommon.InstrumentationScope, profile pprofile.Profile) map[string]string {
519+
func populateResourceData(dic pprofile.ProfilesDictionary, resource pcommon.Resource, scope pcommon.InstrumentationScope, profile pprofile.Profile) (map[string]string, error) {
517520
numAttrs := resource.Attributes().Len() + scope.Attributes().Len() + profile.AttributeIndices().Len()
518521
if numAttrs == 0 {
519-
return map[string]string{}
522+
return map[string]string{}, nil
520523
}
521524
attrs := make(map[string]string, numAttrs)
522525

523526
addEventHostData(attrs, resource.Attributes())
524527
addEventHostData(attrs, scope.Attributes())
525-
addEventHostData(attrs, pprofile.FromAttributeIndices(dic.AttributeTable(), profile, dic))
528+
profileAttrs, err := pprofile.FromAttributeIndices(dic.AttributeTable(), profile, dic)
529+
if err != nil {
530+
return nil, err
531+
}
532+
addEventHostData(attrs, profileAttrs)
526533

527-
return attrs
534+
return attrs, nil
528535
}

exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,8 @@ func TestStackTraceEvent(t *testing.T) {
847847
p := rp.ScopeProfiles().At(0).Profiles().At(0)
848848
s := p.Samples().At(0)
849849

850-
resourceAttrs := populateResourceData(dic, rp.Resource(), rp.ScopeProfiles().At(0).Scope(), p)
850+
resourceAttrs, err := populateResourceData(dic, rp.Resource(), rp.ScopeProfiles().At(0).Scope(), p)
851+
require.NoError(t, err)
851852
event := stackTraceEvent(dic, stacktraceIDBase64, s, 20, resourceAttrs)
852853
event.TimeStamp = newUnixTime64(tt.timestamp)
853854

pkg/ottl/contexts/internal/ctxprofilecommon/attributes.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func AccessAttributes[K any](source attributeSource[K]) ottl.StandardGetSetter[K
2323
return ottl.StandardGetSetter[K]{
2424
Getter: func(_ context.Context, tCtx K) (any, error) {
2525
dict, attributable := source(tCtx)
26-
return pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict), nil
26+
return pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict)
2727
},
2828
Setter: func(_ context.Context, tCtx K, val any) error {
2929
m, err := ctxutil.GetMap(val)
@@ -56,7 +56,11 @@ func AccessAttributesKey[K any](key []ottl.Key[K], source attributeSource[K]) ot
5656
return ottl.StandardGetSetter[K]{
5757
Getter: func(ctx context.Context, tCtx K) (any, error) {
5858
dict, attributable := source(tCtx)
59-
return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict), key)
59+
m, err := pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict)
60+
if err != nil {
61+
return nil, err
62+
}
63+
return ctxutil.GetMapValue[K](ctx, tCtx, m, key)
6064
},
6165
Setter: func(ctx context.Context, tCtx K, val any) error {
6266
newKey, err := ctxutil.GetMapKeyName(ctx, tCtx, key[0])

0 commit comments

Comments
 (0)