Skip to content

Commit 4c4f243

Browse files
florianledmocosta
andauthored
[pkg/ottl]: Create ctxprofilecommon for common attribute handling (#42107)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Most Profiling messages do have some attributes. Create ctxprofilecommon for shared functionality. Follow up to #41814 (comment) <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes <!--Describe what testing was performed and which tests were added.--> #### Testing <!--Describe the documentation added.--> #### Documentation <!--Please delete paragraphs that you did not use before submitting.--> --------- Signed-off-by: Florian Lehner <florian.lehner@elastic.co> Co-authored-by: edmocosta <11836452+edmocosta@users.noreply.github.com>
1 parent ae7887a commit 4c4f243

File tree

8 files changed

+597
-127
lines changed

8 files changed

+597
-127
lines changed

.chloggen/ctxprofilecommon.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: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
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: Create ctxprofilecommon for common attribute handling in various profiling sub messages
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: [42107]
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]

pkg/ottl/contexts/internal/ctxprofile/profile.go

Lines changed: 6 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
1616
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon"
1717
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxerror"
18+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxprofilecommon"
1819
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxutil"
1920
)
2021

@@ -59,10 +60,13 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) {
5960
case "original_payload":
6061
return accessOriginalPayload[K](), nil
6162
case "attributes":
63+
attributable := func(ctx K) (pprofile.ProfilesDictionary, ctxprofilecommon.ProfileAttributable) {
64+
return ctx.GetProfilesDictionary(), ctx.GetProfile()
65+
}
6266
if path.Keys() == nil {
63-
return accessAttributes[K](), nil
67+
return ctxprofilecommon.AccessAttributes[K](attributable), nil
6468
}
65-
return accessAttributesKey(path.Keys()), nil
69+
return ctxprofilecommon.AccessAttributesKey[K](path.Keys(), attributable), nil
6670
default:
6771
return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef)
6872
}
@@ -282,63 +286,3 @@ func accessOriginalPayload[K Context]() ottl.StandardGetSetter[K] {
282286
},
283287
}
284288
}
285-
286-
func accessAttributes[K Context]() ottl.StandardGetSetter[K] {
287-
return ottl.StandardGetSetter[K]{
288-
Getter: func(_ context.Context, tCtx K) (any, error) {
289-
return pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary()), nil
290-
},
291-
Setter: func(_ context.Context, tCtx K, val any) error {
292-
m, err := ctxutil.GetMap(val)
293-
if err != nil {
294-
return err
295-
}
296-
tCtx.GetProfile().AttributeIndices().FromRaw([]int32{})
297-
for k, v := range m.All() {
298-
if err := pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), k, v); err != nil {
299-
return err
300-
}
301-
}
302-
return nil
303-
},
304-
}
305-
}
306-
307-
func accessAttributesKey[K Context](key []ottl.Key[K]) ottl.StandardGetSetter[K] {
308-
return ottl.StandardGetSetter[K]{
309-
Getter: func(ctx context.Context, tCtx K) (any, error) {
310-
return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary()), key)
311-
},
312-
Setter: func(ctx context.Context, tCtx K, val any) error {
313-
newKey, err := ctxutil.GetMapKeyName(ctx, tCtx, key[0])
314-
if err != nil {
315-
return err
316-
}
317-
v := getAttributeValue(tCtx, *newKey)
318-
err = ctxutil.SetIndexableValue[K](ctx, tCtx, v, val, key[1:])
319-
if err != nil {
320-
return err
321-
}
322-
return pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), *newKey, v)
323-
},
324-
}
325-
}
326-
327-
func getAttributeValue[K Context](tCtx K, key string) pcommon.Value {
328-
// Find the index of the attribute in the profile's attribute indices
329-
// and return the corresponding value from the attribute table.
330-
table := tCtx.GetProfilesDictionary().AttributeTable()
331-
strTable := tCtx.GetProfilesDictionary().StringTable()
332-
333-
for _, tableIndex := range tCtx.GetProfile().AttributeIndices().All() {
334-
attr := table.At(int(tableIndex))
335-
if strTable.At(int(attr.KeyStrindex())) == key {
336-
// Copy the value because OTTL expects to do inplace updates for the values.
337-
v := pcommon.NewValueEmpty()
338-
attr.Value().CopyTo(v)
339-
return v
340-
}
341-
}
342-
343-
return pcommon.NewValueEmpty()
344-
}

pkg/ottl/contexts/internal/ctxprofile/profile_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,15 @@ func (p *profileContext) GetProfile() pprofile.Profile {
192192
return p.profile
193193
}
194194

195+
func (p *profileContext) AttributeIndices() pcommon.Int32Slice {
196+
return p.profile.AttributeIndices()
197+
}
198+
195199
func newProfileContext(profile pprofile.Profile, dictionary pprofile.ProfilesDictionary) *profileContext {
196-
return &profileContext{profile: profile, dictionary: dictionary}
200+
return &profileContext{
201+
profile: profile,
202+
dictionary: dictionary,
203+
}
197204
}
198205

199206
func createValueType() pprofile.ValueType {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package ctxprofilecommon // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxprofilecommon"
5+
6+
import (
7+
"context"
8+
9+
"go.opentelemetry.io/collector/pdata/pcommon"
10+
"go.opentelemetry.io/collector/pdata/pprofile"
11+
12+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxutil"
14+
)
15+
16+
type ProfileAttributable interface {
17+
AttributeIndices() pcommon.Int32Slice
18+
}
19+
20+
type attributeSource[K any] = func(ctx K) (pprofile.ProfilesDictionary, ProfileAttributable)
21+
22+
func AccessAttributes[K any](source attributeSource[K]) ottl.StandardGetSetter[K] {
23+
return ottl.StandardGetSetter[K]{
24+
Getter: func(_ context.Context, tCtx K) (any, error) {
25+
dict, attributable := source(tCtx)
26+
return pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict), nil
27+
},
28+
Setter: func(_ context.Context, tCtx K, val any) error {
29+
m, err := ctxutil.GetMap(val)
30+
if err != nil {
31+
return err
32+
}
33+
34+
dict, attributable := source(tCtx)
35+
attributable.AttributeIndices().FromRaw([]int32{})
36+
for k, v := range m.All() {
37+
if err := pprofile.PutAttribute(dict.AttributeTable(), attributable, dict, k, v); err != nil {
38+
return err
39+
}
40+
}
41+
return nil
42+
},
43+
}
44+
}
45+
46+
func AccessAttributesKey[K any](key []ottl.Key[K], source attributeSource[K]) ottl.StandardGetSetter[K] {
47+
return ottl.StandardGetSetter[K]{
48+
Getter: func(ctx context.Context, tCtx K) (any, error) {
49+
dict, attributable := source(tCtx)
50+
return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(dict.AttributeTable(), attributable, dict), key)
51+
},
52+
Setter: func(ctx context.Context, tCtx K, val any) error {
53+
newKey, err := ctxutil.GetMapKeyName(ctx, tCtx, key[0])
54+
if err != nil {
55+
return err
56+
}
57+
58+
dict, attributable := source(tCtx)
59+
v := getAttributeValue(dict, attributable.AttributeIndices(), *newKey)
60+
if err := ctxutil.SetIndexableValue[K](ctx, tCtx, v, val, key[1:]); err != nil {
61+
return err
62+
}
63+
64+
return pprofile.PutAttribute(dict.AttributeTable(), attributable, dict, *newKey, v)
65+
},
66+
}
67+
}
68+
69+
func getAttributeValue(dict pprofile.ProfilesDictionary, indices pcommon.Int32Slice, key string) pcommon.Value {
70+
strTable := dict.StringTable()
71+
kvuTable := dict.AttributeTable()
72+
73+
for _, tableIndex := range indices.All() {
74+
attr := kvuTable.At(int(tableIndex))
75+
attrKey := strTable.At(int(attr.KeyStrindex()))
76+
if attrKey == key {
77+
// Copy the value because OTTL expects to do inplace updates for the values.
78+
v := pcommon.NewValueEmpty()
79+
attr.Value().CopyTo(v)
80+
return v
81+
}
82+
}
83+
84+
return pcommon.NewValueEmpty()
85+
}

0 commit comments

Comments
 (0)