From 1dc3951e77f962f2ee4033a91ac0194b62a5493e Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Thu, 4 Sep 2025 14:39:37 +0200 Subject: [PATCH 01/14] fix all tests in pkg --- .../contexts/internal/ctxprofile/profile.go | 48 +-- .../internal/ctxprofile/profile_test.go | 26 +- .../ctxprofilesample/profilesample.go | 55 +--- .../ctxprofilesample/profilesample_test.go | 8 - .../contexts/internal/logprofile/logging.go | 71 ++-- .../internal/logprofile/logging_test.go | 4 +- .../ottlprofilesample/profilesample_test.go | 4 +- pkg/ottl/e2e/profiles/e2e_test.go | 34 +- pkg/pdatatest/pprofiletest/options.go | 4 +- pkg/pdatatest/pprofiletest/profiles.go | 121 ++----- pkg/pdatatest/pprofiletest/profiles_test.go | 304 +++++------------- pkg/pdatatest/pprofiletest/types.go | 68 ++-- pkg/pdatatest/pprofiletest/validate.go | 77 +---- pkg/pdatatest/pprofiletest/validate_test.go | 199 ++---------- 14 files changed, 230 insertions(+), 793 deletions(-) diff --git a/pkg/ottl/contexts/internal/ctxprofile/profile.go b/pkg/ottl/contexts/internal/ctxprofile/profile.go index eeaffede93bea..bfc9d30e71584 100644 --- a/pkg/ottl/contexts/internal/ctxprofile/profile.go +++ b/pkg/ottl/contexts/internal/ctxprofile/profile.go @@ -27,8 +27,6 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) { return accessSampleType[K](), nil case "sample": return accessSample[K](), nil - case "location_indices": - return accessLocationIndices[K](), nil case "time_unix_nano": return accessTimeUnixNano[K](), nil case "time": @@ -43,8 +41,6 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) { return accessPeriod[K](), nil case "comment_string_indices": return accessCommentStringIndices[K](), nil - case "default_sample_type_index": - return accessDefaultSampleTypeIndex[K](), nil case "profile_id": nextPath := path.Next() if nextPath != nil { @@ -72,20 +68,6 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) { } } -func accessSampleType[K Context]() ottl.StandardGetSetter[K] { - return ottl.StandardGetSetter[K]{ - Getter: func(_ context.Context, tCtx K) (any, error) { - return tCtx.GetProfile().SampleType(), nil - }, - Setter: func(_ context.Context, tCtx K, val any) error { - if v, ok := val.(pprofile.ValueTypeSlice); ok { - v.CopyTo(tCtx.GetProfile().SampleType()) - } - return nil - }, - } -} - func accessSample[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { @@ -100,17 +82,6 @@ func accessSample[K Context]() ottl.StandardGetSetter[K] { } } -func accessLocationIndices[K Context]() ottl.StandardGetSetter[K] { - return ottl.StandardGetSetter[K]{ - Getter: func(_ context.Context, tCtx K) (any, error) { - return ctxutil.GetCommonIntSliceValues[int32](tCtx.GetProfile().LocationIndices()), nil - }, - Setter: func(_ context.Context, tCtx K, val any) error { - return ctxutil.SetCommonIntSliceValues[int32](tCtx.GetProfile().LocationIndices(), val) - }, - } -} - func accessTimeUnixNano[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { @@ -206,14 +177,14 @@ func accessCommentStringIndices[K Context]() ottl.StandardGetSetter[K] { } } -func accessDefaultSampleTypeIndex[K Context]() ottl.StandardGetSetter[K] { +func accessSampleType[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { - return int64(tCtx.GetProfile().DefaultSampleTypeIndex()), nil + return tCtx.GetProfile().SampleType(), nil }, Setter: func(_ context.Context, tCtx K, val any) error { - if i, ok := val.(int64); ok { - tCtx.GetProfile().SetDefaultSampleTypeIndex(int32(i)) + if v, ok := val.(pprofile.ValueType); ok { + v.CopyTo(tCtx.GetProfile().SampleType()) } return nil }, @@ -315,7 +286,7 @@ func accessOriginalPayload[K Context]() ottl.StandardGetSetter[K] { func accessAttributes[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { - return pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile()), nil + return pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary()), nil }, Setter: func(_ context.Context, tCtx K, val any) error { m, err := ctxutil.GetMap(val) @@ -324,7 +295,7 @@ func accessAttributes[K Context]() ottl.StandardGetSetter[K] { } tCtx.GetProfile().AttributeIndices().FromRaw([]int32{}) for k, v := range m.All() { - if err := pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), k, v); err != nil { + if err := pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), k, v); err != nil { return err } } @@ -336,7 +307,7 @@ func accessAttributes[K Context]() ottl.StandardGetSetter[K] { func accessAttributesKey[K Context](key []ottl.Key[K]) ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(ctx context.Context, tCtx K) (any, error) { - return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile()), key) + return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary()), key) }, Setter: func(ctx context.Context, tCtx K, val any) error { newKey, err := ctxutil.GetMapKeyName(ctx, tCtx, key[0]) @@ -348,7 +319,7 @@ func accessAttributesKey[K Context](key []ottl.Key[K]) ottl.StandardGetSetter[K] if err != nil { return err } - return pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), *newKey, v) + return pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), *newKey, v) }, } } @@ -357,10 +328,11 @@ func getAttributeValue[K Context](tCtx K, key string) pcommon.Value { // Find the index of the attribute in the profile's attribute indices // and return the corresponding value from the attribute table. table := tCtx.GetProfilesDictionary().AttributeTable() + strTable := tCtx.GetProfilesDictionary().StringTable() for _, tableIndex := range tCtx.GetProfile().AttributeIndices().All() { attr := table.At(int(tableIndex)) - if attr.Key() == key { + if strTable.At(int(attr.KeyStrindex())) == key { // Copy the value because OTTL expects to do inplace updates for the values. v := pcommon.NewValueEmpty() attr.Value().CopyTo(v) diff --git a/pkg/ottl/contexts/internal/ctxprofile/profile_test.go b/pkg/ottl/contexts/internal/ctxprofile/profile_test.go index abbe58d49832b..c8b4b236f93b6 100644 --- a/pkg/ottl/contexts/internal/ctxprofile/profile_test.go +++ b/pkg/ottl/contexts/internal/ctxprofile/profile_test.go @@ -29,21 +29,12 @@ func TestPathGetSetter(t *testing.T) { }{ { path: "sample_type", - val: createValueTypeSlice(), + val: createValueType(), }, { path: "sample", val: createSampleSlice(), }, - { - path: "location_indices", - val: []int64{5}, - }, - { - path: "location_indices error", - val: []string{"x"}, - setFails: true, - }, { path: "time_unix_nano", val: int64(123), @@ -72,10 +63,6 @@ func TestPathGetSetter(t *testing.T) { path: "comment_string_indices", val: []int64{345}, }, - { - path: "default_sample_type_index", - val: int64(456), - }, { path: "profile_id", val: createProfileID(), @@ -209,13 +196,6 @@ func newProfileContext(profile pprofile.Profile, dictionary pprofile.ProfilesDic return &profileContext{profile: profile, dictionary: dictionary} } -func createValueTypeSlice() pprofile.ValueTypeSlice { - sl := pprofile.NewValueTypeSlice() - vt := sl.AppendEmpty() - vt.CopyTo(createValueType()) - return sl -} - func createValueType() pprofile.ValueType { vt := pprofile.NewValueType() vt.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) @@ -238,9 +218,7 @@ func createProfileID() pprofile.ProfileID { func createSample() pprofile.Sample { sample := pprofile.NewSample() sample.AttributeIndices().Append(1) - sample.SetLocationsLength(2) - sample.SetLocationsStartIndex(3) sample.TimestampsUnixNano().Append(4) - sample.Value().Append(5) + sample.Values().Append(5) return sample } diff --git a/pkg/ottl/contexts/internal/ctxprofilesample/profilesample.go b/pkg/ottl/contexts/internal/ctxprofilesample/profilesample.go index 4f3cf7437da44..938e42eba165f 100644 --- a/pkg/ottl/contexts/internal/ctxprofilesample/profilesample.go +++ b/pkg/ottl/contexts/internal/ctxprofilesample/profilesample.go @@ -27,10 +27,6 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) { return nil, ctxerror.New("nil", "nil", Name, DocRef) } switch path.Name() { - case "locations_start_index": - return accessLocationsStartIndex[K](), nil - case "locations_length": - return accessLocationsLength[K](), nil case "values": return accessValues[K](), nil case "attribute_indices": @@ -51,49 +47,13 @@ func PathGetSetter[K Context](path ottl.Path[K]) (ottl.GetSetter[K], error) { } } -func accessLocationsStartIndex[K Context]() ottl.StandardGetSetter[K] { - return ottl.StandardGetSetter[K]{ - Getter: func(_ context.Context, tCtx K) (any, error) { - return int64(tCtx.GetProfileSample().LocationsStartIndex()), nil - }, - Setter: func(_ context.Context, tCtx K, val any) error { - if v, ok := val.(int64); ok { - if v >= math.MaxInt32 { - return errMaxValueExceed - } - tCtx.GetProfileSample().SetLocationsStartIndex(int32(v)) - return nil - } - return errInvalidValueType - }, - } -} - -func accessLocationsLength[K Context]() ottl.StandardGetSetter[K] { - return ottl.StandardGetSetter[K]{ - Getter: func(_ context.Context, tCtx K) (any, error) { - return int64(tCtx.GetProfileSample().LocationsLength()), nil - }, - Setter: func(_ context.Context, tCtx K, val any) error { - if v, ok := val.(int64); ok { - if v >= math.MaxInt32 { - return errMaxValueExceed - } - tCtx.GetProfileSample().SetLocationsLength(int32(v)) - return nil - } - return errInvalidValueType - }, - } -} - func accessValues[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { - return ctxutil.GetCommonIntSliceValues[int64](tCtx.GetProfileSample().Value()), nil + return ctxutil.GetCommonIntSliceValues[int64](tCtx.GetProfileSample().Values()), nil }, Setter: func(_ context.Context, tCtx K, val any) error { - return ctxutil.SetCommonIntSliceValues[int64](tCtx.GetProfileSample().Value(), val) + return ctxutil.SetCommonIntSliceValues[int64](tCtx.GetProfileSample().Values(), val) }, } } @@ -162,7 +122,7 @@ func accessTimestamps[K Context]() ottl.StandardGetSetter[K] { func accessAttributes[K Context]() ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(_ context.Context, tCtx K) (any, error) { - return pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample()), nil + return pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), tCtx.GetProfilesDictionary()), nil }, Setter: func(_ context.Context, tCtx K, val any) error { m, err := ctxutil.GetMap(val) @@ -171,7 +131,7 @@ func accessAttributes[K Context]() ottl.StandardGetSetter[K] { } tCtx.GetProfileSample().AttributeIndices().FromRaw([]int32{}) for k, v := range m.All() { - if err := pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), k, v); err != nil { + if err := pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), tCtx.GetProfilesDictionary(), k, v); err != nil { return err } } @@ -183,7 +143,7 @@ func accessAttributes[K Context]() ottl.StandardGetSetter[K] { func accessAttributesKey[K Context](key []ottl.Key[K]) ottl.StandardGetSetter[K] { return ottl.StandardGetSetter[K]{ Getter: func(ctx context.Context, tCtx K) (any, error) { - return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample()), key) + return ctxutil.GetMapValue[K](ctx, tCtx, pprofile.FromAttributeIndices(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), tCtx.GetProfilesDictionary()), key) }, Setter: func(ctx context.Context, tCtx K, val any) error { newKey, err := ctxutil.GetMapKeyName(ctx, tCtx, key[0]) @@ -194,7 +154,7 @@ func accessAttributesKey[K Context](key []ottl.Key[K]) ottl.StandardGetSetter[K] if err := ctxutil.SetIndexableValue[K](ctx, tCtx, v, val, key[1:]); err != nil { return err } - return pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), *newKey, v) + return pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfileSample(), tCtx.GetProfilesDictionary(), *newKey, v) }, } } @@ -203,10 +163,11 @@ func getAttributeValue[K Context](tCtx K, key string) pcommon.Value { // Find the index of the attribute in the profile's attribute indices // and return the corresponding value from the attribute table. table := tCtx.GetProfilesDictionary().AttributeTable() + strTable := tCtx.GetProfilesDictionary().StringTable() for _, tableIndex := range tCtx.GetProfileSample().AttributeIndices().All() { attr := table.At(int(tableIndex)) - if attr.Key() == key { + if strTable.At(int(attr.KeyStrindex())) == key { // Copy the value because OTTL expects to do inplace updates for the values. v := pcommon.NewValueEmpty() attr.Value().CopyTo(v) diff --git a/pkg/ottl/contexts/internal/ctxprofilesample/profilesample_test.go b/pkg/ottl/contexts/internal/ctxprofilesample/profilesample_test.go index 1fd486bd87739..be4b2970bac0a 100644 --- a/pkg/ottl/contexts/internal/ctxprofilesample/profilesample_test.go +++ b/pkg/ottl/contexts/internal/ctxprofilesample/profilesample_test.go @@ -23,14 +23,6 @@ func TestPathGetSetter(t *testing.T) { val any keys []ottl.Key[*profileSampleContext] }{ - { - path: "locations_start_index", - val: int64(42), - }, - { - path: "locations_length", - val: int64(43), - }, { path: "values", val: []int64{73, 74, 75}, diff --git a/pkg/ottl/contexts/internal/logprofile/logging.go b/pkg/ottl/contexts/internal/logprofile/logging.go index aac71645951c3..1e69d62b1fbc9 100644 --- a/pkg/ottl/contexts/internal/logprofile/logging.go +++ b/pkg/ottl/contexts/internal/logprofile/logging.go @@ -21,19 +21,15 @@ func getMapping(dict pprofile.ProfilesDictionary, idx int32) (mapping, error) { return newMapping(dict, mTable.At(int(idx))) } -func getLocations(dict pprofile.ProfilesDictionary, locIdxs pcommon.Int32Slice, start, length int32) (locations, error) { - if start >= int32(locIdxs.Len()) { - return locations{}, fmt.Errorf("location start index out of bounds: %d", start) - } - if start+length > int32(locIdxs.Len()) { - return locations{}, fmt.Errorf("location end index out of bounds: %d", start+length) - } - +func getLocations(dict pprofile.ProfilesDictionary, stackIDx int32) (locations, error) { locTable := dict.LocationTable() + stackTable := dict.StackTable() + var joinedErr error - ls := make(locations, 0, length) - for i := range length { - locIdx := locIdxs.At(int(start + i)) + locIdxs := stackTable.At(int(stackIDx)).LocationIndices() + ls := make(locations, 0, locIdxs.Len()) + for i := range locIdxs.Len() { + locIdx := locIdxs.At(i) l, err := newLocation(dict, locTable.At(int(locIdx))) joinedErr = errors.Join(joinedErr, err) ls = append(ls, l) @@ -68,12 +64,13 @@ func getString(dict pprofile.ProfilesDictionary, idx int32) (string, error) { func getAttribute(dict pprofile.ProfilesDictionary, idx int32) (attribute, error) { attrTable := dict.AttributeTable() + strTable := dict.StringTable() if idx >= int32(attrTable.Len()) { return attribute{}, fmt.Errorf("attribute index out of bounds: %d", idx) } attr := attrTable.At(int(idx)) // Is there a better way to marshal the value? - return attribute{attr.Key(), attr.Value().AsString()}, nil + return attribute{strTable.At(int(attr.KeyStrindex())), attr.Value().AsString()}, nil } type Profile struct { @@ -84,9 +81,9 @@ type Profile struct { func (p Profile) MarshalLogObject(encoder zapcore.ObjectEncoder) error { var joinedErr error - vts, err := newValueTypes(p, p.SampleType()) + vts, err := newValueType(p, p.SampleType()) joinedErr = errors.Join(joinedErr, err) - joinedErr = errors.Join(joinedErr, encoder.AddArray("sample_type", vts)) + joinedErr = errors.Join(joinedErr, encoder.AddObject("sample_type", vts)) samples := p.Sample() for _, s := range samples.All() { @@ -110,10 +107,6 @@ func (p Profile) MarshalLogObject(encoder zapcore.ObjectEncoder) error { joinedErr = errors.Join(joinedErr, err) joinedErr = errors.Join(joinedErr, encoder.AddArray("comments", cs)) - dst, err := getString(p.Dictionary, p.DefaultSampleTypeIndex()) - joinedErr = errors.Join(joinedErr, err) - encoder.AddString("default_sample_type", dst) - pid := p.ProfileID() encoder.AddString("profile_id", hex.EncodeToString(pid[:])) encoder.AddUint32("dropped_attributes_count", p.DroppedAttributesCount()) @@ -136,18 +129,18 @@ type ProfileSample struct { func (s ProfileSample) MarshalLogObject(encoder zapcore.ObjectEncoder) error { var joinedErr error - locs, err := getLocations(s.Dictionary, s.Profile.LocationIndices(), s.LocationsStartIndex(), s.LocationsLength()) + locs, err := getLocations(s.Dictionary, s.StackIndex()) joinedErr = errors.Join(joinedErr, err) joinedErr = errors.Join(joinedErr, encoder.AddArray("locations", locs)) - values := newValues(s.Value()) + values := newValues(s.Values()) joinedErr = errors.Join(joinedErr, encoder.AddArray("values", values)) ats, err := newAttributes(s.Dictionary, s.AttributeIndices()) joinedErr = errors.Join(joinedErr, err) joinedErr = errors.Join(joinedErr, encoder.AddArray("attributes", ats)) - if s.HasLinkIndex() { + if s.LinkIndex() > 0 { l, err := getLink(s.Dictionary, s.LinkIndex()) joinedErr = errors.Join(joinedErr, err) joinedErr = errors.Join(joinedErr, encoder.AddObject("link", l)) @@ -169,19 +162,6 @@ func (s valueTypes) MarshalLogArray(encoder zapcore.ArrayEncoder) error { return err } -func newValueTypes(p Profile, sampleTypes pprofile.ValueTypeSlice) (valueTypes, error) { - var joinedErr error - - vts := make(valueTypes, 0, sampleTypes.Len()) - for i := range sampleTypes.Len() { - vt, err := newValueType(p, sampleTypes.At(i)) - joinedErr = errors.Join(joinedErr, err) - vts = append(vts, vt) - } - - return vts, joinedErr -} - type valueType struct { typ string unit string @@ -222,7 +202,6 @@ type location struct { mapping mapping address uint64 lines lines - isFolded bool attributes attributes } @@ -242,28 +221,22 @@ func newLocation(dict pprofile.ProfilesDictionary, pl pprofile.Location) (locati joinedErr = errors.Join(joinedErr, err) } l.address = pl.Address() - l.isFolded = pl.IsFolded() return l, joinedErr } func (l location) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddUint64("address", l.address) - encoder.AddBool("is_folded", l.isFolded) err := encoder.AddObject("mapping", l.mapping) err = errors.Join(err, encoder.AddArray("lines", l.lines)) return errors.Join(err, encoder.AddArray("attributes", l.attributes)) } type mapping struct { - filename string - memoryStart uint64 - memoryLimit uint64 - fileOffset uint64 - hasFunctions bool - hasFilenames bool - hasLineNumbers bool - hasInlineFrames bool + filename string + memoryStart uint64 + memoryLimit uint64 + fileOffset uint64 } func newMapping(dict pprofile.ProfilesDictionary, pm pprofile.Mapping) (mapping, error) { @@ -274,10 +247,6 @@ func newMapping(dict pprofile.ProfilesDictionary, pm pprofile.Mapping) (mapping, m.memoryStart = pm.MemoryStart() m.memoryLimit = pm.MemoryLimit() m.fileOffset = pm.FileOffset() - m.hasFunctions = pm.HasFunctions() - m.hasFilenames = pm.HasFilenames() - m.hasLineNumbers = pm.HasLineNumbers() - m.hasInlineFrames = pm.HasInlineFrames() return m, err } @@ -287,10 +256,6 @@ func (m mapping) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddUint64("memory_start", m.memoryStart) encoder.AddUint64("memory_limit", m.memoryLimit) encoder.AddUint64("file_offset", m.fileOffset) - encoder.AddBool("has_functions", m.hasFunctions) - encoder.AddBool("has_filenames", m.hasFilenames) - encoder.AddBool("has_line_numbers", m.hasLineNumbers) - encoder.AddBool("has_inline_frames", m.hasInlineFrames) return nil } diff --git a/pkg/ottl/contexts/internal/logprofile/logging_test.go b/pkg/ottl/contexts/internal/logprofile/logging_test.go index 9c6ec1b8f7fcc..9bf1d3456520b 100644 --- a/pkg/ottl/contexts/internal/logprofile/logging_test.go +++ b/pkg/ottl/contexts/internal/logprofile/logging_test.go @@ -41,7 +41,7 @@ func TestProfile_MarshalLogObject(t *testing.T) { Address: 0x42, }, }, - Value: []int64{73}, + Values: []int64{73}, Link: &pprofiletest.Link{ TraceID: pcommon.TraceID{ 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, @@ -56,7 +56,7 @@ func TestProfile_MarshalLogObject(t *testing.T) { Address: 0x43, }, }, - Value: []int64{74}, + Values: []int64{74}, Attributes: []pprofiletest.Attribute{ {Key: "sample2", Value: "value2"}, }, diff --git a/pkg/ottl/contexts/ottlprofilesample/profilesample_test.go b/pkg/ottl/contexts/ottlprofilesample/profilesample_test.go index f2cb30d801f68..9f690d75ec51a 100644 --- a/pkg/ottl/contexts/ottlprofilesample/profilesample_test.go +++ b/pkg/ottl/contexts/ottlprofilesample/profilesample_test.go @@ -190,8 +190,6 @@ func createProfileSampleTelemetry() (pprofile.Sample, pprofile.Profile) { profile := pprofile.NewProfile() sample := profile.Sample().AppendEmpty() sample.SetLinkIndex(42) - sample.SetLocationsStartIndex(73) - sample.SetLocationsLength(97) timestamps := sample.TimestampsUnixNano() if timestamps.Len() == 0 { @@ -199,7 +197,7 @@ func createProfileSampleTelemetry() (pprofile.Sample, pprofile.Profile) { timestamps.Append(uint64(time.Now().Unix())) } - values := sample.Value() + values := sample.Values() if values.Len() == 0 { values.EnsureCapacity(1) values.Append(3) diff --git a/pkg/ottl/e2e/profiles/e2e_test.go b/pkg/ottl/e2e/profiles/e2e_test.go index e12181eff1ced..e9ad1218cb86e 100644 --- a/pkg/ottl/e2e/profiles/e2e_test.go +++ b/pkg/ottl/e2e/profiles/e2e_test.go @@ -272,7 +272,7 @@ func Test_e2e_editors(t *testing.T) { v := pcommon.NewValueEmpty() getProfileAttribute(t, tCtx, "foo").CopyTo(v) v.Map().PutStr("test", "pass") - _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), "foo", v) + _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), "foo", v) }, }, { @@ -297,7 +297,7 @@ func Test_e2e_editors(t *testing.T) { mv, _ := v.Map().Get("slice") s := mv.Slice() s.AppendEmpty().SetStr("sample_value") - _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), "foo", v) + _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), "foo", v) }, }, { @@ -307,7 +307,7 @@ func Test_e2e_editors(t *testing.T) { getProfileAttribute(t, tCtx, "foo").CopyTo(v) mv, _ := v.Map().Get("flags") _ = mv.FromRaw([]any{"pass", "sample_value"}) - _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), "foo", v) + _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), "foo", v) }, }, { @@ -317,7 +317,7 @@ func Test_e2e_editors(t *testing.T) { getProfileAttribute(t, tCtx, "foo").CopyTo(v) mv, _ := v.Map().Get("slice") _ = mv.FromRaw([]any{"val", 5, 6}) - _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), "foo", v) + _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), "foo", v) }, }, { @@ -327,7 +327,7 @@ func Test_e2e_editors(t *testing.T) { getProfileAttribute(t, tCtx, "foo").CopyTo(v) s := v.Map().PutEmptySlice("new_slice") _ = s.FromRaw([]any{5, 6}) - _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), "foo", v) + _ = pprofile.PutAttribute(tCtx.GetProfilesDictionary().AttributeTable(), tCtx.GetProfile(), tCtx.GetProfilesDictionary(), "foo", v) }, }, } @@ -379,8 +379,8 @@ func (validator dictionaryValidator) validate() error { if err := compareTables(validator.orig.StringTable(), validator.dic.StringTable()); err != nil { return fmt.Errorf("string table: %w", err) } - if err := compareTables(validator.orig.AttributeUnits(), validator.dic.AttributeUnits()); err != nil { - return fmt.Errorf("attribute units table: %w", err) + if err := compareTables(validator.orig.AttributeTable(), validator.dic.AttributeTable()); err != nil { + return fmt.Errorf("attribute table: %w", err) } if err := compareTables(validator.orig.FunctionTable(), validator.dic.FunctionTable()); err != nil { return fmt.Errorf("function table: %w", err) @@ -1673,21 +1673,21 @@ func putProfileAttribute(t *testing.T, tCtx ottlprofile.TransformContext, key st profile := tCtx.GetProfile() switch v := value.(type) { case string: - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, pcommon.NewValueStr(v))) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, pcommon.NewValueStr(v))) case float64: - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, pcommon.NewValueDouble(v))) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, pcommon.NewValueDouble(v))) case int: - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, pcommon.NewValueInt(int64(v)))) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, pcommon.NewValueInt(int64(v)))) case bool: - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, pcommon.NewValueBool(v))) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, pcommon.NewValueBool(v))) case []any: sl := pcommon.NewValueSlice() require.NoError(t, sl.FromRaw(v)) - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, sl)) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, sl)) case map[string]any: m := pcommon.NewValueMap() require.NoError(t, m.FromRaw(v)) - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, m)) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, m)) default: t.Fatalf("unsupported value type: %T", v) } @@ -1697,7 +1697,7 @@ func removeAttribute(t *testing.T, tCtx ottlprofile.TransformContext, key string table := tCtx.GetProfilesDictionary().AttributeTable() indices := tCtx.GetProfile().AttributeIndices().AsRaw() - idx := findAttributeIndex(table, indices, key) + idx := findAttributeIndex(tCtx.GetProfilesDictionary(), table, indices, key) if idx == -1 { t.Fatalf("attribute %s not found", key) return @@ -1714,7 +1714,7 @@ func getProfileAttribute(t *testing.T, tCtx ottlprofile.TransformContext, key st table := tCtx.GetProfilesDictionary().AttributeTable() indices := tCtx.GetProfile().AttributeIndices().AsRaw() - idx := findAttributeIndex(table, indices, key) + idx := findAttributeIndex(tCtx.GetProfilesDictionary(), table, indices, key) if idx == -1 { t.Fatalf("attribute %s not found", key) } @@ -1722,10 +1722,10 @@ func getProfileAttribute(t *testing.T, tCtx ottlprofile.TransformContext, key st return table.At(int(indices[idx])).Value() } -func findAttributeIndex(table pprofile.AttributeTableSlice, indices []int32, key string) int { +func findAttributeIndex(dic pprofile.ProfilesDictionary, table pprofile.KeyValueAndUnitSlice, indices []int32, key string) int { for i, tableIndex := range indices { attr := table.At(int(tableIndex)) - if attr.Key() == key { + if dic.StringTable().At(int(attr.KeyStrindex())) == key { return i } } diff --git a/pkg/pdatatest/pprofiletest/options.go b/pkg/pdatatest/pprofiletest/options.go index 786ee65e56efc..f60424dd2a982 100644 --- a/pkg/pdatatest/pprofiletest/options.go +++ b/pkg/pdatatest/pprofiletest/options.go @@ -101,7 +101,7 @@ func (opt ignoreProfileAttributeValue) maskProfileAttributeValue(profiles pprofi dic := profiles.Dictionary() for l := 0; l < dic.AttributeTable().Len(); l++ { a := dic.AttributeTable().At(l) - if a.Key() == opt.attributeName { + if dic.StringTable().At(int(a.KeyStrindex())) == opt.attributeName { a.Value().SetEmptyBytes() } } @@ -206,7 +206,7 @@ func profileAttributesToMap(dic pprofile.ProfilesDictionary, p pprofile.Profile) d := map[string]string{} for _, i := range p.AttributeIndices().AsRaw() { v := dic.AttributeTable().At(int(i)) - d[v.Key()] = v.Value().AsString() + d[dic.StringTable().At(int(v.KeyStrindex()))] = v.Value().AsString() } return d diff --git a/pkg/pdatatest/pprofiletest/profiles.go b/pkg/pdatatest/pprofiletest/profiles.go index e43c61be611ae..808a5cb0cce92 100644 --- a/pkg/pdatatest/pprofiletest/profiles.go +++ b/pkg/pdatatest/pprofiletest/profiles.go @@ -252,10 +252,6 @@ func CompareProfile(expectedDic, actualDic pprofile.ProfilesDictionary, expected errs = multierr.Append(errs, fmt.Errorf("profileID does not match expected '%s', actual '%s'", expected.ProfileID().String(), actual.ProfileID().String())) } - if !reflect.DeepEqual(expected.LocationIndices(), actual.LocationIndices()) { - errs = multierr.Append(errs, errors.New("locationIndicies do not match expected")) - } - if !reflect.DeepEqual(expected.CommentStrindices(), actual.CommentStrindices()) { errs = multierr.Append(errs, errors.New("comment does not match expected")) } @@ -280,10 +276,6 @@ func CompareProfile(expectedDic, actualDic pprofile.ProfilesDictionary, expected errs = multierr.Append(errs, fmt.Errorf("period does not match expected '%d', actual '%d'", expected.Period(), actual.Period())) } - if expected.DefaultSampleTypeIndex() != actual.DefaultSampleTypeIndex() { - errs = multierr.Append(errs, fmt.Errorf("defaultSampleType does not match expected '%d', actual '%d'", expected.DefaultSampleTypeIndex(), actual.DefaultSampleTypeIndex())) - } - if expected.PeriodType().TypeStrindex() != actual.PeriodType().TypeStrindex() || expected.PeriodType().UnitStrindex() != actual.PeriodType().UnitStrindex() || expected.PeriodType().AggregationTemporality() != actual.PeriodType().AggregationTemporality() { @@ -292,73 +284,21 @@ func CompareProfile(expectedDic, actualDic pprofile.ProfilesDictionary, expected actual.PeriodType().UnitStrindex(), actual.PeriodType().TypeStrindex(), actual.PeriodType().AggregationTemporality())) } - errs = multierr.Append(errs, internal.AddErrPrefix("sampleType", CompareProfileValueTypeSlice(expected.SampleType(), actual.SampleType()))) + errs = multierr.Append(errs, internal.AddErrPrefix("sampleType", CompareProfileValueType(expected.SampleType(), actual.SampleType()))) errs = multierr.Append(errs, internal.AddErrPrefix("sample", CompareProfileSampleSlice(expected.Sample(), actual.Sample()))) return errs } -func CompareProfileValueTypeSlice(expected, actual pprofile.ValueTypeSlice) error { - var errs error - if expected.Len() != actual.Len() { - errs = multierr.Append(errs, fmt.Errorf("number of valueTypes doesn't match expected: %d, actual: %d", - expected.Len(), actual.Len())) - return errs +func CompareProfileValueType(expected, actual pprofile.ValueType) error { + if !isValueTypeEqual(expected, actual) { + return fmt.Errorf(`expected valueType "unit: %d, type: %d, aggregationTemporality: %d",`+ + `got "unit: %d, type: %d, aggregationTemporality: %d"`, expected.UnitStrindex(), expected.TypeStrindex(), expected.AggregationTemporality(), + actual.UnitStrindex(), actual.TypeStrindex(), actual.AggregationTemporality()) } - numValueTypes := expected.Len() - - matchingValueTypes := make(map[pprofile.ValueType]pprofile.ValueType, numValueTypes) - - var outOfOrderErrs error - for e := 0; e < numValueTypes; e++ { - elr := expected.At(e) - var foundMatch bool - for a := 0; a < numValueTypes; a++ { - alr := actual.At(a) - if _, ok := matchingValueTypes[alr]; ok { - continue - } - if elr.TypeStrindex() == alr.TypeStrindex() && elr.UnitStrindex() == alr.UnitStrindex() { - foundMatch = true - matchingValueTypes[alr] = elr - if e != a { - outOfOrderErrs = multierr.Append(outOfOrderErrs, - fmt.Errorf(`valueTypes are out of order: valueType "unit: %d, type: %d, aggregationTemporality: %d" expected at index %d, found at index %d`, - elr.UnitStrindex(), elr.TypeStrindex(), elr.AggregationTemporality(), e, a)) - } - break - } - } - if !foundMatch { - errs = multierr.Append(errs, fmt.Errorf(`missing expected valueType "unit: %d, type: %d, aggregationTemporality: %d"`, elr.UnitStrindex(), elr.TypeStrindex(), elr.AggregationTemporality())) - } - } - - for i := 0; i < numValueTypes; i++ { - if _, ok := matchingValueTypes[actual.At(i)]; !ok { - errs = multierr.Append(errs, fmt.Errorf(`unexpected valueType "unit: %d, type: %d, aggregationTemporality: %d"`, - actual.At(i).UnitStrindex(), actual.At(i).TypeStrindex(), actual.At(i).AggregationTemporality())) - } - } - - if errs != nil { - return errs - } - if outOfOrderErrs != nil { - return outOfOrderErrs - } - - for alr, elr := range matchingValueTypes { - if !isValueTypeEqual(elr, alr) { - errs = multierr.Append(errs, fmt.Errorf(`expected valueType "unit: %d, type: %d, aggregationTemporality: %d",`+ - `got "unit: %d, type: %d, aggregationTemporality: %d"`, elr.UnitStrindex(), elr.TypeStrindex(), elr.AggregationTemporality(), - alr.UnitStrindex(), alr.TypeStrindex(), alr.AggregationTemporality())) - } - } - - return errs + return nil } func isValueTypeEqual(expected, actual pprofile.ValueType) bool { @@ -428,20 +368,13 @@ func CompareProfileSampleSlice(expected, actual pprofile.SampleSlice) error { func CompareProfileSample(expected, actual pprofile.Sample) error { var errs error - if expected.LocationsStartIndex() != actual.LocationsStartIndex() { - errs = multierr.Append(errs, fmt.Errorf("expected locationStartIndex '%d', got '%d'", expected.LocationsStartIndex(), actual.LocationsStartIndex())) - } - - if expected.LocationsLength() != actual.LocationsLength() { - errs = multierr.Append(errs, fmt.Errorf("expected locationLenght '%d', got '%d'", expected.LocationsLength(), actual.LocationsLength())) - } if !reflect.DeepEqual(expected.TimestampsUnixNano().AsRaw(), actual.TimestampsUnixNano().AsRaw()) { errs = multierr.Append(errs, fmt.Errorf("expected timestampUnixNano '%v', got '%v'", expected.TimestampsUnixNano().AsRaw(), actual.TimestampsUnixNano().AsRaw())) } - if !reflect.DeepEqual(expected.Value().AsRaw(), actual.Value().AsRaw()) { - errs = multierr.Append(errs, fmt.Errorf("expected value '%v', got '%v'", expected.Value().AsRaw(), actual.Value().AsRaw())) + if !reflect.DeepEqual(expected.Values().AsRaw(), actual.Values().AsRaw()) { + errs = multierr.Append(errs, fmt.Errorf("expected values '%v', got '%v'", expected.Values().AsRaw(), actual.Values().AsRaw())) } if !reflect.DeepEqual(expected.TimestampsUnixNano().AsRaw(), actual.TimestampsUnixNano().AsRaw()) { @@ -507,7 +440,7 @@ func CompareProfileMappingSlice(expected, actual pprofile.MappingSlice) error { } for alr, elr := range matchingItems { - if !isMappingEqual(elr, alr) { + if !elr.Equal(alr) { errs = multierr.Append(errs, fmt.Errorf(`mapping with "attributes: %v", does not match expected`, alr.AttributeIndices().AsRaw())) } @@ -516,18 +449,6 @@ func CompareProfileMappingSlice(expected, actual pprofile.MappingSlice) error { return errs } -func isMappingEqual(expected, actual pprofile.Mapping) bool { - return expected.MemoryStart() == actual.MemoryStart() && - expected.MemoryLimit() == actual.MemoryLimit() && - expected.FileOffset() == actual.FileOffset() && - expected.FilenameStrindex() == actual.FilenameStrindex() && - reflect.DeepEqual(expected.AttributeIndices().AsRaw(), actual.AttributeIndices().AsRaw()) && - expected.HasFunctions() == actual.HasFunctions() && - expected.HasFilenames() == actual.HasFilenames() && - expected.HasLineNumbers() == actual.HasLineNumbers() && - expected.HasInlineFrames() == actual.HasInlineFrames() -} - func CompareProfileFunctionSlice(expected, actual pprofile.FunctionSlice) error { var errs error if expected.Len() != actual.Len() { @@ -665,10 +586,6 @@ func CompareProfileLocation(expected, actual pprofile.Location) error { errs = multierr.Append(errs, fmt.Errorf("expected address '%d', got '%d'", expected.Address(), actual.Address())) } - if expected.IsFolded() != actual.IsFolded() { - errs = multierr.Append(errs, fmt.Errorf("expected isFolded '%v', got '%v'", expected.IsFolded(), actual.IsFolded())) - } - if !reflect.DeepEqual(expected.AttributeIndices().AsRaw(), actual.AttributeIndices().AsRaw()) { errs = multierr.Append(errs, fmt.Errorf("expected attributes '%v', got '%v'", expected.AttributeIndices().AsRaw(), actual.AttributeIndices().AsRaw())) } @@ -745,17 +662,17 @@ func isLineEqual(expected, actual pprofile.Line) bool { expected.Column() == actual.Column() } -func CompareProfileAttributeUnitSlice(expected, actual pprofile.AttributeUnitSlice) error { +func CompareKeyValueAndUnitSlice(expected, actual pprofile.KeyValueAndUnitSlice) error { var errs error if expected.Len() != actual.Len() { - errs = multierr.Append(errs, fmt.Errorf("number of attributeUnits doesn't match expected: %d, actual: %d", + errs = multierr.Append(errs, fmt.Errorf("number of keyValueAndUnits doesn't match expected: %d, actual: %d", expected.Len(), actual.Len())) return errs } numItems := expected.Len() - matchingItems := make(map[pprofile.AttributeUnit]pprofile.AttributeUnit, numItems) + matchingItems := make(map[pprofile.KeyValueAndUnit]pprofile.KeyValueAndUnit, numItems) var outOfOrderErrs error for e := 0; e < numItems; e++ { @@ -766,26 +683,26 @@ func CompareProfileAttributeUnitSlice(expected, actual pprofile.AttributeUnitSli if _, ok := matchingItems[alr]; ok { continue } - if elr.AttributeKeyStrindex() == alr.AttributeKeyStrindex() && elr.UnitStrindex() == alr.UnitStrindex() { + if elr.KeyStrindex() == alr.KeyStrindex() && elr.Value().AsRaw() == alr.Value().AsRaw() && elr.UnitStrindex() == alr.UnitStrindex() { foundMatch = true matchingItems[alr] = elr if e != a { outOfOrderErrs = multierr.Append(outOfOrderErrs, - fmt.Errorf(`attributeUnits are out of order: attributeUnit "attributeKey: %d" expected at index %d, found at index %d`, - elr.AttributeKeyStrindex(), e, a)) + fmt.Errorf(`keyValueAndUnits are out of order: keyValueAndUnit "key: %d" expected at index %d, found at index %d`, + elr.KeyStrindex(), e, a)) } break } } if !foundMatch { - errs = multierr.Append(errs, fmt.Errorf(`missing expected attributeUnit "attributeKey: %d"`, elr.AttributeKeyStrindex())) + errs = multierr.Append(errs, fmt.Errorf(`missing expected keyValueAndUnit "key: %d"`, elr.KeyStrindex())) } } for i := 0; i < numItems; i++ { if _, ok := matchingItems[actual.At(i)]; !ok { - errs = multierr.Append(errs, fmt.Errorf(`unexpected profile attributeUnit "attributeKey: %d"`, - actual.At(i).AttributeKeyStrindex())) + errs = multierr.Append(errs, fmt.Errorf(`unexpected profile keyValueAndUnit "key: %d"`, + actual.At(i).KeyStrindex())) } } diff --git a/pkg/pdatatest/pprofiletest/profiles_test.go b/pkg/pdatatest/pprofiletest/profiles_test.go index 0c6fff4d480c0..e27039b9eccff 100644 --- a/pkg/pdatatest/pprofiletest/profiles_test.go +++ b/pkg/pdatatest/pprofiletest/profiles_test.go @@ -666,7 +666,7 @@ func TestCompareProfile(t *testing.T) { AggregationTemporality: pprofile.AggregationTemporalityCumulative, }, }, - AttributeUnits: []AttributeUnit{{AttributeKey: "cpu", Unit: "nanoseconds"}}, + KeyValueAndUnits: []KeyValueAndUnit{{Key: "cpu", Value: "", Unit: "nanoseconds"}}, }, } tr := p.Transform() @@ -692,7 +692,7 @@ func TestCompareProfile(t *testing.T) { AggregationTemporality: pprofile.AggregationTemporalityCumulative, }, }, - AttributeUnits: []AttributeUnit{{AttributeKey: "cpu", Unit: "nanoseconds"}}, + KeyValueAndUnits: []KeyValueAndUnit{{Key: "cpu", Value: "", Unit: "nanoseconds"}}, }, } tr := p.Transform() @@ -721,7 +721,7 @@ func TestCompareProfile(t *testing.T) { AggregationTemporality: pprofile.AggregationTemporalityCumulative, }, }, - AttributeUnits: []AttributeUnit{{AttributeKey: "cpu", Unit: "nanoseconds"}}, + KeyValueAndUnits: []KeyValueAndUnit{{Key: "cpu", Value: "", Unit: "nanoseconds"}}, }, } tr := p.Transform() @@ -747,7 +747,7 @@ func TestCompareProfile(t *testing.T) { AggregationTemporality: pprofile.AggregationTemporalityCumulative, }, }, - AttributeUnits: []AttributeUnit{{AttributeKey: "cpu2", Unit: "nanoseconds2"}}, + KeyValueAndUnits: []KeyValueAndUnit{{Key: "cpu2", Value: "", Unit: "nanoseconds2"}}, }, } tr := p.Transform() @@ -756,8 +756,7 @@ func TestCompareProfile(t *testing.T) { err: multierr.Combine( errors.New(`attributes don't match expected: map[key:val], actual: map[key1:val1]`), errors.New(`period does not match expected '1', actual '2'`), - fmt.Errorf(`sampleType: %w`, errors.New(`missing expected valueType "unit: 4, type: 3, aggregationTemporality: 1"`)), - fmt.Errorf(`sampleType: %w`, errors.New(`unexpected valueType "unit: 6, type: 5, aggregationTemporality: 1"`)), + fmt.Errorf(`sampleType: %w`, errors.New(`expected valueType "unit: 4, type: 3, aggregationTemporality: 1",got "unit: 6, type: 5, aggregationTemporality: 1"`)), ), }, } @@ -770,173 +769,65 @@ func TestCompareProfile(t *testing.T) { } } -func TestCompareProfileValueTypeSlice(t *testing.T) { +func TestCompareProfileValueType(t *testing.T) { tests := []struct { name string - expected pprofile.ValueTypeSlice - actual pprofile.ValueTypeSlice + expected pprofile.ValueType + actual pprofile.ValueType err error }{ { name: "empty", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() + expected: func() pprofile.ValueType { + l := pprofile.NewValueType() return l }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() + actual: func() pprofile.ValueType { + l := pprofile.NewValueType() return l }(), }, { name: "equal", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) - return l - }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) - return l - }(), - }, - { - name: "equal wrong order", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) + expected: func() pprofile.ValueType { + l := pprofile.NewValueType() + l.SetTypeStrindex(1) + l.SetUnitStrindex(1) + l.SetAggregationTemporality(1) return l }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) + actual: func() pprofile.ValueType { + l := pprofile.NewValueType() + l.SetTypeStrindex(1) + l.SetUnitStrindex(1) + l.SetAggregationTemporality(1) return l }(), - err: multierr.Combine( - errors.New(`valueTypes are out of order: valueType "unit: 1, type: 1, aggregationTemporality: 1" expected at index 0, found at index 1`), - errors.New(`valueTypes are out of order: valueType "unit: 2, type: 2, aggregationTemporality: 1" expected at index 1, found at index 0`), - ), - }, - { - name: "wrong length", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - return l - }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) - return l - }(), - err: multierr.Combine( - errors.New(`number of valueTypes doesn't match expected: 1, actual: 2`), - ), }, { name: "not equal - does not match expected", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) + expected: func() pprofile.ValueType { + l := pprofile.NewValueType() + l.SetTypeStrindex(1) + l.SetUnitStrindex(1) + l.SetAggregationTemporality(1) return l }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(2) + actual: func() pprofile.ValueType { + l := pprofile.NewValueType() + l.SetTypeStrindex(1) + l.SetUnitStrindex(1) + l.SetAggregationTemporality(2) return l }(), err: multierr.Combine( - errors.New(`expected valueType "unit: 2, type: 2, aggregationTemporality: 1",got "unit: 2, type: 2, aggregationTemporality: 2"`), - ), - }, - { - name: "not equal - missing", - expected: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(2) - i2.SetUnitStrindex(2) - i2.SetAggregationTemporality(1) - return l - }(), - actual: func() pprofile.ValueTypeSlice { - l := pprofile.NewValueTypeSlice() - i1 := l.AppendEmpty() - i1.SetTypeStrindex(1) - i1.SetUnitStrindex(1) - i1.SetAggregationTemporality(1) - i2 := l.AppendEmpty() - i2.SetTypeStrindex(3) - i2.SetUnitStrindex(3) - i2.SetAggregationTemporality(1) - return l - }(), - err: multierr.Combine( - errors.New(`missing expected valueType "unit: 2, type: 2, aggregationTemporality: 1"`), - errors.New(`unexpected valueType "unit: 3, type: 3, aggregationTemporality: 1"`), + errors.New(`expected valueType "unit: 1, type: 1, aggregationTemporality: 1",got "unit: 1, type: 1, aggregationTemporality: 2"`), ), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - require.Equal(t, test.err, CompareProfileValueTypeSlice(test.expected, test.actual)) + require.Equal(t, test.err, CompareProfileValueType(test.expected, test.actual)) }) } } @@ -964,21 +855,17 @@ func TestCompareProfileSampleSlice(t *testing.T) { expected: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) return l }(), actual: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) return l }(), }, @@ -987,20 +874,16 @@ func TestCompareProfileSampleSlice(t *testing.T) { expected: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) return l }(), actual: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) return l }(), @@ -1014,18 +897,15 @@ func TestCompareProfileSampleSlice(t *testing.T) { expected: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) return l }(), actual: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) return l }(), err: multierr.Combine( @@ -1037,25 +917,22 @@ func TestCompareProfileSampleSlice(t *testing.T) { expected: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() - i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) + i2.AttributeIndices().Append(1, 3) return l }(), actual: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(3) return l }(), err: multierr.Combine( - fmt.Errorf(`sample "attributes: [1 2 3]": %w`, errors.New(`expected locationLenght '2', got '3'`)), + errors.New(`missing expected sample "attributes: [1 3]"`), + errors.New(`unexpected sample "attributes: [1 2 3]"`), ), }, { @@ -1063,21 +940,17 @@ func TestCompareProfileSampleSlice(t *testing.T) { expected: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3) - i2.SetLocationsLength(2) return l }(), actual: func() pprofile.SampleSlice { l := pprofile.NewSampleSlice() i1 := l.AppendEmpty() - i1.SetLocationsLength(1) i1.AttributeIndices().Append(1, 2) i2 := l.AppendEmpty() i2.AttributeIndices().Append(1, 2, 3, 5) - i2.SetLocationsLength(3) return l }(), err: multierr.Combine( @@ -1115,15 +988,11 @@ func TestCompareProfileSample(t *testing.T) { name: "equal", expected: func() pprofile.Sample { l := pprofile.NewSample() - l.SetLocationsStartIndex(1) - l.SetLocationsLength(1) l.AttributeIndices().Append(1, 2) return l }(), actual: func() pprofile.Sample { l := pprofile.NewSample() - l.SetLocationsStartIndex(1) - l.SetLocationsLength(1) l.AttributeIndices().Append(1, 2) return l }(), @@ -1132,21 +1001,15 @@ func TestCompareProfileSample(t *testing.T) { name: "not equal", expected: func() pprofile.Sample { l := pprofile.NewSample() - l.SetLocationsStartIndex(1) - l.SetLocationsLength(1) l.AttributeIndices().Append(1, 2) return l }(), actual: func() pprofile.Sample { l := pprofile.NewSample() - l.SetLocationsStartIndex(2) - l.SetLocationsLength(3) l.AttributeIndices().Append(1, 2, 3) return l }(), err: multierr.Combine( - errors.New(`expected locationStartIndex '1', got '2'`), - errors.New(`expected locationLenght '1', got '3'`), errors.New(`expected attributes '[1 2]', got '[1 2 3]'`), ), }, @@ -1636,7 +1499,6 @@ func TestCompareProfileLocation(t *testing.T) { expected: func() pprofile.Location { l := pprofile.NewLocation() l.SetAddress(2) - l.SetIsFolded(true) l.SetMappingIndex(4) l.AttributeIndices().Append(1, 2, 3) l.Line().AppendEmpty().Line() @@ -1645,7 +1507,6 @@ func TestCompareProfileLocation(t *testing.T) { actual: func() pprofile.Location { l := pprofile.NewLocation() l.SetAddress(2) - l.SetIsFolded(true) l.SetMappingIndex(4) l.AttributeIndices().Append(1, 2, 3) l.Line().AppendEmpty() @@ -1657,7 +1518,6 @@ func TestCompareProfileLocation(t *testing.T) { expected: func() pprofile.Location { l := pprofile.NewLocation() l.SetAddress(3) - l.SetIsFolded(false) l.SetMappingIndex(2) l.AttributeIndices().Append(1, 2, 3, 4) l.Line().AppendEmpty().SetFunctionIndex(3) @@ -1666,7 +1526,6 @@ func TestCompareProfileLocation(t *testing.T) { actual: func() pprofile.Location { l := pprofile.NewLocation() l.SetAddress(2) - l.SetIsFolded(true) l.SetMappingIndex(4) l.AttributeIndices().Append(1, 2, 3) l.Line().AppendEmpty().Line() @@ -1675,7 +1534,6 @@ func TestCompareProfileLocation(t *testing.T) { err: multierr.Combine( errors.New(`expected mappingIndex '2', got '4'`), errors.New(`expected address '3', got '2'`), - errors.New(`expected isFolded 'false', got 'true'`), errors.New(`expected attributes '[1 2 3 4]', got '[1 2 3]'`), fmt.Errorf(`line of location with "attributes: [1 2 3 4]": %w`, errors.New(`missing expected line "functionIndex: 3"`)), fmt.Errorf(`line of location with "attributes: [1 2 3 4]": %w`, errors.New(`unexpected profile line "functionIndex: 0"`)), @@ -1860,128 +1718,128 @@ func TestCompareProfileLineSlice(t *testing.T) { } } -func TestCompareProfileAttributeUnitSlice(t *testing.T) { +func TestCompareCompareKeyValueAndUnitSlice(t *testing.T) { tests := []struct { name string - expected pprofile.AttributeUnitSlice - actual pprofile.AttributeUnitSlice + expected pprofile.KeyValueAndUnitSlice + actual pprofile.KeyValueAndUnitSlice err error }{ { name: "empty", - expected: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + expected: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() return l }(), - actual: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + actual: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() return l }(), }, { name: "equal", - expected: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + expected: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) return l }(), - actual: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + actual: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) return l }(), }, { name: "equal wrong order", - expected: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + expected: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) return l }(), - actual: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + actual: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) return l }(), err: multierr.Combine( - errors.New(`attributeUnits are out of order: attributeUnit "attributeKey: 2" expected at index 0, found at index 1`), - errors.New(`attributeUnits are out of order: attributeUnit "attributeKey: 4" expected at index 1, found at index 0`), + errors.New(`keyValueAndUnits are out of order: keyValueAndUnit "key: 2" expected at index 0, found at index 1`), + errors.New(`keyValueAndUnits are out of order: keyValueAndUnit "key: 4" expected at index 1, found at index 0`), ), }, { name: "wrong length", - expected: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + expected: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) return l }(), - actual: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + actual: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) return l }(), err: multierr.Combine( - errors.New(`number of attributeUnits doesn't match expected: 1, actual: 2`), + errors.New(`number of keyValueAndUnits doesn't match expected: 1, actual: 2`), ), }, { name: "not equal", - expected: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + expected: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(4) + i2.SetKeyStrindex(4) i2.SetUnitStrindex(5) return l }(), - actual: func() pprofile.AttributeUnitSlice { - l := pprofile.NewAttributeUnitSlice() + actual: func() pprofile.KeyValueAndUnitSlice { + l := pprofile.NewKeyValueAndUnitSlice() i1 := l.AppendEmpty() - i1.SetAttributeKeyStrindex(2) + i1.SetKeyStrindex(2) i1.SetUnitStrindex(3) i2 := l.AppendEmpty() - i2.SetAttributeKeyStrindex(6) + i2.SetKeyStrindex(6) i2.SetUnitStrindex(7) return l }(), err: multierr.Combine( - errors.New(`missing expected attributeUnit "attributeKey: 4"`), - errors.New(`unexpected profile attributeUnit "attributeKey: 6"`), + errors.New(`missing expected keyValueAndUnit "key: 4"`), + errors.New(`unexpected profile keyValueAndUnit "key: 6"`), ), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - require.Equal(t, test.err, CompareProfileAttributeUnitSlice(test.expected, test.actual)) + require.Equal(t, test.err, CompareKeyValueAndUnitSlice(test.expected, test.actual)) }) } } diff --git a/pkg/pdatatest/pprofiletest/types.go b/pkg/pdatatest/pprofiletest/types.go index 1bfd6cea8b23e..e061cd8f1a3bb 100644 --- a/pkg/pdatatest/pprofiletest/types.go +++ b/pkg/pdatatest/pprofiletest/types.go @@ -97,7 +97,7 @@ type Profile struct { OriginalPayloadFormat string OriginalPayload []byte Attributes []Attribute - AttributeUnits []AttributeUnit + KeyValueAndUnits []KeyValueAndUnit } func (p *Profile) Transform(dic pprofile.ProfilesDictionary, psp pprofile.ScopeProfiles) pprofile.Profile { @@ -134,7 +134,7 @@ func (p *Profile) Transform(dic pprofile.ProfilesDictionary, psp pprofile.ScopeP for _, at := range p.Attributes { at.Transform(dic, pp) } - for _, au := range p.AttributeUnits { + for _, au := range p.KeyValueAndUnits { au.Transform(dic) } @@ -166,13 +166,11 @@ type ValueType struct { } func (vt *ValueType) exists(dic pprofile.ProfilesDictionary, pp pprofile.Profile) bool { - for i := range pp.SampleType().Len() { - st := pp.SampleType().At(i) - if vt.Typ == dic.StringTable().At(int(st.TypeStrindex())) && - vt.Unit == dic.StringTable().At(int(st.UnitStrindex())) && - vt.AggregationTemporality == st.AggregationTemporality() { - return true - } + st := pp.SampleType() + if vt.Typ == dic.StringTable().At(int(st.TypeStrindex())) && + vt.Unit == dic.StringTable().At(int(st.UnitStrindex())) && + vt.AggregationTemporality == st.AggregationTemporality() { + return true } return false } @@ -185,32 +183,31 @@ func (vt *ValueType) CopyTo(dic pprofile.ProfilesDictionary, pvt pprofile.ValueT func (vt *ValueType) Transform(dic pprofile.ProfilesDictionary, pp pprofile.Profile) { if !vt.exists(dic, pp) { - vt.CopyTo(dic, pp.SampleType().AppendEmpty()) + vt.CopyTo(dic, pp.SampleType()) } } type Sample struct { Link *Link // optional - Value []int64 + Values []int64 Locations []Location Attributes []Attribute TimestampsUnixNano []uint64 } func (sa *Sample) Transform(dic pprofile.ProfilesDictionary, pp pprofile.Profile) { - if len(sa.Value) != pp.SampleType().Len() { - panic("length of profile.sample_type must be equal to the length of sample.value") - } + stack := dic.StackTable().AppendEmpty() psa := pp.Sample().AppendEmpty() - psa.SetLocationsStartIndex(int32(pp.LocationIndices().Len())) + psa.SetStackIndex(int32(dic.StackTable().Len() - 1)) + for _, loc := range sa.Locations { - pp.LocationIndices().Append(int32(pp.LocationIndices().Len())) ploc := dic.LocationTable().AppendEmpty() + stack.LocationIndices().Append(int32(dic.LocationTable().Len() - 1)) + if loc.Mapping != nil { loc.Mapping.Transform(dic) } ploc.SetAddress(loc.Address) - ploc.SetIsFolded(loc.IsFolded) for _, l := range loc.Line { pl := ploc.Line().AppendEmpty() pl.SetLine(l.Line) @@ -221,8 +218,7 @@ func (sa *Sample) Transform(dic pprofile.ProfilesDictionary, pp pprofile.Profile at.Transform(dic, ploc) } } - psa.SetLocationsLength(int32(pp.LocationIndices().Len()) - psa.LocationsStartIndex()) - psa.Value().FromRaw(sa.Value) + psa.Values().FromRaw(sa.Values) for _, at := range sa.Attributes { at.Transform(dic, psa) } @@ -254,15 +250,11 @@ func (l *Link) Transform(dic pprofile.ProfilesDictionary) int32 { } type Mapping struct { - MemoryStart uint64 - MemoryLimit uint64 - FileOffset uint64 - Filename string - Attributes []Attribute - HasFunctions bool - HasFileNames bool - HasLineNumbers bool - HasInlineFrames bool + MemoryStart uint64 + MemoryLimit uint64 + FileOffset uint64 + Filename string + Attributes []Attribute } func (m *Mapping) Transform(dic pprofile.ProfilesDictionary) { @@ -274,10 +266,6 @@ func (m *Mapping) Transform(dic pprofile.ProfilesDictionary) { for _, at := range m.Attributes { at.Transform(dic, pm) } - pm.SetHasFunctions(m.HasFunctions) - pm.SetHasFilenames(m.HasFileNames) - pm.SetHasLineNumbers(m.HasLineNumbers) - pm.SetHasInlineFrames(m.HasInlineFrames) } type Attribute struct { @@ -295,20 +283,22 @@ func (a *Attribute) Transform(dic pprofile.ProfilesDictionary, record attributab panic(fmt.Sprintf("unsupported attribute value: {%s: %v (type %T)}", a.Key, a.Value, a.Value)) } - if err := pprofile.PutAttribute(dic.AttributeTable(), record, a.Key, v); err != nil { + if err := pprofile.PutAttribute(dic.AttributeTable(), record, dic, a.Key, v); err != nil { panic(fmt.Sprintf("failed to put attribute: {%s: %v (type %T)}: %v", a.Key, a.Value, a.Value, err)) } } -type AttributeUnit struct { - AttributeKey string - Unit string +type KeyValueAndUnit struct { + Key string + Value any + Unit string } -func (a *AttributeUnit) Transform(dic pprofile.ProfilesDictionary) int32 { - pa := dic.AttributeUnits().AppendEmpty() - pa.SetAttributeKeyStrindex(addString(dic, a.AttributeKey)) +func (a *KeyValueAndUnit) Transform(dic pprofile.ProfilesDictionary) int32 { + pa := dic.AttributeTable().AppendEmpty() + pa.SetKeyStrindex(addString(dic, a.Key)) + pa.Value().FromRaw(a.Value) pa.SetUnitStrindex(addString(dic, a.Unit)) return int32(dic.AttributeTable().Len() - 1) } diff --git a/pkg/pdatatest/pprofiletest/validate.go b/pkg/pdatatest/pprofiletest/validate.go index 95c133f94bea0..a5a42db687c26 100644 --- a/pkg/pdatatest/pprofiletest/validate.go +++ b/pkg/pdatatest/pprofiletest/validate.go @@ -23,12 +23,6 @@ func ValidateProfile(dic pprofile.ProfilesDictionary, pp pprofile.Profile) error errs = errors.Join(errs, errors.New("string table must start with the empty string")) } - if pp.SampleType().Len() < 1 { - // Since the proto field 'default_sample_type_index' is always valid, there must be at least - // one sample type in the profile. - errs = errors.Join(errs, errors.New("missing sample type, need at least a default")) - } - errs = errors.Join(errs, validateSampleType(dic, pp)) errs = errors.Join(errs, validateSamples(dic, pp)) @@ -37,10 +31,6 @@ func ValidateProfile(dic pprofile.ProfilesDictionary, pp pprofile.Profile) error errs = errors.Join(errs, fmt.Errorf("period_type: %w", err)) } - if err := validateIndex(stLen, pp.DefaultSampleTypeIndex()); err != nil { - errs = errors.Join(errs, fmt.Errorf("default_sample_type_strindex: %w", err)) - } - if err := validateIndices(stLen, pp.CommentStrindices()); err != nil { errs = errors.Join(errs, fmt.Errorf("comment_strindices: %w", err)) } @@ -49,7 +39,7 @@ func ValidateProfile(dic pprofile.ProfilesDictionary, pp pprofile.Profile) error errs = errors.Join(errs, fmt.Errorf("attribute_indices: %w", err)) } - errs = errors.Join(errs, validateAttributeUnits(dic)) + errs = errors.Join(errs, validateKeyValueAndUnits(dic)) return errs } @@ -75,16 +65,12 @@ func validateIndex(length int, idx int32) error { } func validateSampleType(dic pprofile.ProfilesDictionary, pp pprofile.Profile) error { - var errs error - stLen := dic.StringTable().Len() - for i := range pp.SampleType().Len() { - if err := validateValueType(stLen, pp.SampleType().At(i)); err != nil { - errs = errors.Join(errs, fmt.Errorf("sample_type[%d]: %w", i, err)) - } + if err := validateValueType(stLen, pp.SampleType()); err != nil { + return fmt.Errorf("sample_type: %w", err) } - return errs + return nil } func validateValueType(stLen int, pvt pprofile.ValueType) error { @@ -122,45 +108,6 @@ func validateSamples(dic pprofile.ProfilesDictionary, pp pprofile.Profile) error func validateSample(dic pprofile.ProfilesDictionary, pp pprofile.Profile, sample pprofile.Sample) error { var errs error - length := sample.LocationsLength() - if length < 0 { - errs = errors.Join(errs, fmt.Errorf("locations_length %d is negative", length)) - } - - if length > 0 { - start := sample.LocationsStartIndex() - if err := validateIndex(pp.LocationIndices().Len(), start); err != nil { - errs = errors.Join(errs, fmt.Errorf("locations_start_index: %w", err)) - } - - end := start + length - if err := validateIndex(pp.LocationIndices().Len(), end-1); err != nil { - errs = errors.Join(errs, fmt.Errorf("locations end (%d+%d): %w", start, length, err)) - } - - if errs != nil { - // Return here to avoid panicking when accessing the location indices. - return errs - } - - for i := start; i < end; i++ { - locIdx := pp.LocationIndices().At(int(i)) - if err := validateIndex(dic.LocationTable().Len(), locIdx); err != nil { - errs = errors.Join(errs, fmt.Errorf("location_indices[%d]: %w", i, err)) - continue - } - if err := validateLocation(dic, dic.LocationTable().At(int(locIdx))); err != nil { - errs = errors.Join(errs, fmt.Errorf("locations[%d]: %w", i, err)) - } - } - } - - numValues := pp.SampleType().Len() - if sample.Value().Len() != numValues { - errs = errors.Join(errs, fmt.Errorf("value length %d does not match sample_type length=%d", - sample.Value().Len(), numValues)) - } - if err := validateIndices(dic.AttributeTable().Len(), sample.AttributeIndices()); err != nil { errs = errors.Join(errs, fmt.Errorf("attribute_indices: %w", err)) } @@ -175,7 +122,7 @@ func validateSample(dic pprofile.ProfilesDictionary, pp pprofile.Profile, sample } } - if sample.HasLinkIndex() { + if sample.LinkIndex() > 0 { if err := validateIndex(dic.LinkTable().Len(), sample.LinkIndex()); err != nil { errs = errors.Join(errs, fmt.Errorf("link_index: %w", err)) } @@ -187,7 +134,7 @@ func validateSample(dic pprofile.ProfilesDictionary, pp pprofile.Profile, sample func validateLocation(dic pprofile.ProfilesDictionary, loc pprofile.Location) error { var errs error - if loc.HasMappingIndex() { + if loc.MappingIndex() > 0 { if err := validateIndex(dic.MappingTable().Len(), loc.MappingIndex()); err != nil { // Continuing would run into a panic. return fmt.Errorf("mapping_index: %w", err) @@ -233,11 +180,11 @@ func validateMapping(dic pprofile.ProfilesDictionary, mapping pprofile.Mapping) return errs } -func validateAttributeUnits(dic pprofile.ProfilesDictionary) error { +func validateKeyValueAndUnits(dic pprofile.ProfilesDictionary) error { var errs error - for i := range dic.AttributeUnits().Len() { - if err := validateAttributeUnit(dic, dic.AttributeUnits().At(i)); err != nil { + for i := range dic.AttributeTable().Len() { + if err := validateKeyValueAndUnit(dic, dic.AttributeTable().At(i)); err != nil { errs = errors.Join(errs, fmt.Errorf("attribute_units[%d]: %w", i, err)) } } @@ -245,11 +192,11 @@ func validateAttributeUnits(dic pprofile.ProfilesDictionary) error { return errs } -func validateAttributeUnit(dic pprofile.ProfilesDictionary, au pprofile.AttributeUnit) error { +func validateKeyValueAndUnit(dic pprofile.ProfilesDictionary, au pprofile.KeyValueAndUnit) error { var errs error - if err := validateIndex(dic.StringTable().Len(), au.AttributeKeyStrindex()); err != nil { - errs = errors.Join(errs, fmt.Errorf("attribute_key: %w", err)) + if err := validateIndex(dic.StringTable().Len(), au.KeyStrindex()); err != nil { + errs = errors.Join(errs, fmt.Errorf("key: %w", err)) } if err := validateIndex(dic.StringTable().Len(), au.UnitStrindex()); err != nil { diff --git a/pkg/pdatatest/pprofiletest/validate_test.go b/pkg/pdatatest/pprofiletest/validate_test.go index a79a81ef949cc..9aaa016187850 100644 --- a/pkg/pdatatest/pprofiletest/validate_test.go +++ b/pkg/pdatatest/pprofiletest/validate_test.go @@ -47,20 +47,6 @@ func Test_validateProfile(t *testing.T) { profile: pprofile.NewProfile(), wantErr: assert.Error, }, - { - name: "invalid sample type", - dictionary: func() pprofile.ProfilesDictionary { - dic := pprofile.NewProfilesDictionary() - dic.StringTable().Append("") - return dic - }(), - profile: func() pprofile.Profile { - pp := pprofile.NewProfile() - pp.SampleType().AppendEmpty() - return pp - }(), - wantErr: assert.Error, - }, { name: "invalid sample", dictionary: func() pprofile.ProfilesDictionary { @@ -70,29 +56,10 @@ func Test_validateProfile(t *testing.T) { }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) - pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) - pp.Sample().AppendEmpty() - return pp - }(), - wantErr: assert.Error, - }, - { - name: "invalid default sample type string index", - dictionary: func() pprofile.ProfilesDictionary { - dic := pprofile.NewProfilesDictionary() - dic.StringTable().Append("") - return dic - }(), - profile: func() pprofile.Profile { - pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) s := pp.Sample().AppendEmpty() - s.Value().Append(0) - pp.SetDefaultSampleTypeIndex(1) + s.SetLinkIndex(42) return pp }(), wantErr: assert.Error, @@ -106,12 +73,10 @@ func Test_validateProfile(t *testing.T) { }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) s := pp.Sample().AppendEmpty() - s.Value().Append(0) - pp.SetDefaultSampleTypeIndex(0) + s.Values().Append(0) pp.CommentStrindices().Append(1) return pp }(), @@ -126,12 +91,10 @@ func Test_validateProfile(t *testing.T) { }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) s := pp.Sample().AppendEmpty() - s.Value().Append(0) - pp.SetDefaultSampleTypeIndex(0) + s.Values().Append(0) pp.CommentStrindices().Append(0) pp.AttributeIndices().Append(1) return pp @@ -143,18 +106,16 @@ func Test_validateProfile(t *testing.T) { dictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("") - au := dic.AttributeUnits().AppendEmpty() - au.SetAttributeKeyStrindex(1) + au := dic.AttributeTable().AppendEmpty() + au.SetKeyStrindex(1) return dic }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) s := pp.Sample().AppendEmpty() - s.Value().Append(0) - pp.SetDefaultSampleTypeIndex(0) + s.Values().Append(0) pp.CommentStrindices().Append(0) pp.AttributeIndices().Append(0) return pp @@ -166,23 +127,21 @@ func Test_validateProfile(t *testing.T) { dictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("") - au := dic.AttributeUnits().AppendEmpty() - au.SetAttributeKeyStrindex(0) + au := dic.AttributeTable().AppendEmpty() + au.SetKeyStrindex(0) return dic }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - st := pp.SampleType().AppendEmpty() - st.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) pp.PeriodType().SetAggregationTemporality(pprofile.AggregationTemporalityDelta) s := pp.Sample().AppendEmpty() - s.Value().Append(0) - pp.SetDefaultSampleTypeIndex(0) + s.Values().Append(0) pp.CommentStrindices().Append(0) pp.AttributeIndices().Append(0) return pp }(), - wantErr: assert.Error, + wantErr: assert.NoError, }, } for _, tt := range tests { @@ -219,7 +178,7 @@ func Test_validateSampleTypes(t *testing.T) { name: "empty", dictionary: pprofile.NewProfilesDictionary(), profile: pprofile.NewProfile(), - wantErr: assert.NoError, + wantErr: assert.Error, }, { name: "valid", @@ -230,10 +189,7 @@ func Test_validateSampleTypes(t *testing.T) { }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - s := pp.SampleType().AppendEmpty() - s.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) - s = pp.SampleType().AppendEmpty() - s.SetAggregationTemporality(pprofile.AggregationTemporalityCumulative) + pp.SampleType().SetAggregationTemporality(pprofile.AggregationTemporalityCumulative) return pp }(), wantErr: assert.NoError, @@ -247,10 +203,7 @@ func Test_validateSampleTypes(t *testing.T) { }(), profile: func() pprofile.Profile { pp := pprofile.NewProfile() - s := pp.SampleType().AppendEmpty() - s.SetAggregationTemporality(pprofile.AggregationTemporalityDelta) - s = pp.SampleType().AppendEmpty() - s.SetAggregationTemporality(3) + pp.SampleType().SetAggregationTemporality(3) return pp }(), wantErr: assert.Error, @@ -396,100 +349,6 @@ func Test_validateSample(t *testing.T) { sample: pprofile.NewSample(), wantErr: assert.NoError, }, - { - name: "negative location length", - dictionary: pprofile.NewProfilesDictionary(), - profile: pprofile.NewProfile(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.SetLocationsLength(-1) - return s - }(), - wantErr: assert.Error, - }, - { - name: "location length out of range", - dictionary: pprofile.NewProfilesDictionary(), - profile: pprofile.NewProfile(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.SetLocationsStartIndex(0) - s.SetLocationsLength(1) - return s - }(), - wantErr: assert.Error, - }, - { - name: "location start plus location length in range", - dictionary: func() pprofile.ProfilesDictionary { - dic := pprofile.NewProfilesDictionary() - dic.LocationTable().AppendEmpty() - return dic - }(), - profile: func() pprofile.Profile { - pp := pprofile.NewProfile() - pp.LocationIndices().Append(0) - return pp - }(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.SetLocationsStartIndex(0) - s.SetLocationsLength(1) - return s - }(), - wantErr: assert.NoError, - }, - { - name: "location start plus location length out of range", - dictionary: func() pprofile.ProfilesDictionary { - dic := pprofile.NewProfilesDictionary() - dic.LocationTable().AppendEmpty() - return dic - }(), - profile: func() pprofile.Profile { - pp := pprofile.NewProfile() - pp.LocationIndices().Append(0) - return pp - }(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.SetLocationsStartIndex(0) - s.SetLocationsLength(2) - return s - }(), - wantErr: assert.Error, - }, - { - name: "location index out of range", - dictionary: func() pprofile.ProfilesDictionary { - dic := pprofile.NewProfilesDictionary() - dic.LocationTable().AppendEmpty() - return dic - }(), - profile: func() pprofile.Profile { - pp := pprofile.NewProfile() - pp.LocationIndices().Append(1) - return pp - }(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.SetLocationsStartIndex(0) - s.SetLocationsLength(1) - return s - }(), - wantErr: assert.Error, - }, - { - name: "sample type length does not match", - dictionary: pprofile.NewProfilesDictionary(), - profile: pprofile.NewProfile(), - sample: func() pprofile.Sample { - s := pprofile.NewSample() - s.Value().Append(123) - return s - }(), - wantErr: assert.Error, - }, { name: "attribute in range", dictionary: func() pprofile.ProfilesDictionary { @@ -765,7 +624,7 @@ func Test_validateMapping(t *testing.T) { } } -func Test_validateAttributeUnits(t *testing.T) { +func Test_validateKeyValueAndUnitsUnits(t *testing.T) { tests := []struct { name string dictionary pprofile.ProfilesDictionary @@ -781,7 +640,7 @@ func Test_validateAttributeUnits(t *testing.T) { dictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("") - dic.AttributeUnits().AppendEmpty() + dic.AttributeTable().AppendEmpty() return dic }(), wantErr: assert.NoError, @@ -791,7 +650,7 @@ func Test_validateAttributeUnits(t *testing.T) { dictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("") - au := dic.AttributeUnits().AppendEmpty() + au := dic.AttributeTable().AppendEmpty() au.SetUnitStrindex(1) return dic }(), @@ -802,8 +661,8 @@ func Test_validateAttributeUnits(t *testing.T) { dictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("") - au := dic.AttributeUnits().AppendEmpty() - au.SetAttributeKeyStrindex(1) + au := dic.AttributeTable().AppendEmpty() + au.SetKeyStrindex(1) return dic }(), wantErr: assert.Error, @@ -811,22 +670,22 @@ func Test_validateAttributeUnits(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.wantErr(t, validateAttributeUnits(tt.dictionary)) + tt.wantErr(t, validateKeyValueAndUnits(tt.dictionary)) }) } } -func Test_validateAttributeUnitAt(t *testing.T) { +func Test_validateKeyValueAndUnit(t *testing.T) { tests := []struct { name string dictionary pprofile.ProfilesDictionary - attrUnit pprofile.AttributeUnit + attrUnit pprofile.KeyValueAndUnit wantErr assert.ErrorAssertionFunc }{ { name: "out of range", dictionary: pprofile.NewProfilesDictionary(), - attrUnit: pprofile.NewAttributeUnit(), + attrUnit: pprofile.NewKeyValueAndUnit(), wantErr: assert.Error, }, { @@ -836,13 +695,13 @@ func Test_validateAttributeUnitAt(t *testing.T) { dic.StringTable().Append("") return dic }(), - attrUnit: pprofile.NewAttributeUnit(), + attrUnit: pprofile.NewKeyValueAndUnit(), wantErr: assert.NoError, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.wantErr(t, validateAttributeUnit(tt.dictionary, tt.attrUnit)) + tt.wantErr(t, validateKeyValueAndUnit(tt.dictionary, tt.attrUnit)) }) } } From 71a26ccf1ae1c888d16f84eda4197a87db79717e Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Thu, 4 Sep 2025 16:25:04 +0200 Subject: [PATCH 02/14] upgrade elasticsearch exporter --- .../serializer/otelserializer/profile_test.go | 25 ++- .../serializeprofiles/benchmark_test.go | 17 +- .../serializeprofiles/transform.go | 53 +++--- .../serializeprofiles/transform_test.go | 173 +++++++++++------- 4 files changed, 156 insertions(+), 112 deletions(-) diff --git a/exporter/elasticsearchexporter/internal/serializer/otelserializer/profile_test.go b/exporter/elasticsearchexporter/internal/serializer/otelserializer/profile_test.go index 5f6d16bc0a45e..6669fca4255a5 100644 --- a/exporter/elasticsearchexporter/internal/serializer/otelserializer/profile_test.go +++ b/exporter/elasticsearchexporter/internal/serializer/otelserializer/profile_test.go @@ -44,7 +44,7 @@ func basicProfiles() pprofiletest.Profiles { Sample: []pprofiletest.Sample{ { TimestampsUnixNano: []uint64{0}, - Value: []int64{1}, + Values: []int64{1}, Locations: []pprofiletest.Location{ { Mapping: &pprofiletest.Mapping{}, @@ -78,30 +78,38 @@ func TestSerializeProfile(t *testing.T) { dic.StringTable().Append("samples", "count", "cpu", "nanoseconds") a := dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(4) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr("600DCAFE4A110000F2BF38C493F5FB92") a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(5) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("host.id") + a.SetKeyStrindex(6) + dic.StringTable().Append("host.id") a.Value().SetStr("localhost") a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.name") + a.SetKeyStrindex(7) + dic.StringTable().Append("process.executable.name") a.Value().SetStr("libc.so.6") + dic.MappingTable().AppendEmpty() m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(0) l := dic.LocationTable().AppendEmpty() - l.SetMappingIndex(0) + l.SetMappingIndex(1) l.SetAddress(111) l.AttributeIndices().Append(1) + stack := dic.StackTable().AppendEmpty() + stack.LocationIndices().Append(0) + return dic }, profileCustomizer: func(_ pcommon.Resource, _ pcommon.InstrumentationScope, profile pprofile.Profile) { - st := profile.SampleType().AppendEmpty() + st := profile.SampleType() st.SetTypeStrindex(0) st.SetUnitStrindex(1) pt := profile.PeriodType() @@ -110,12 +118,11 @@ func TestSerializeProfile(t *testing.T) { profile.SetPeriod(1e9 / 20) profile.AttributeIndices().Append(2) - profile.LocationIndices().Append(0) sample := profile.Sample().AppendEmpty() sample.TimestampsUnixNano().Append(0) - sample.SetLocationsLength(1) sample.AttributeIndices().Append(3) + sample.SetStackIndex(0) }, wantErr: false, expected: []map[string]any{ diff --git a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/benchmark_test.go b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/benchmark_test.go index cb6823148f570..b322db3a168c6 100644 --- a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/benchmark_test.go +++ b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/benchmark_test.go @@ -19,14 +19,19 @@ func BenchmarkTransform(b *testing.B) { name: "with a basic recorded sample", buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + dic.StringTable().Append("") + a := dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + dic.StringTable().Append("profile.frame.type") + a.SetKeyStrindex(1) a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(2) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(3) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) dic.StringTable().Append("firefox", "libc.so", "samples", "count", "cpu", "nanoseconds") @@ -55,7 +60,7 @@ func BenchmarkTransform(b *testing.B) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - st := p.SampleType().AppendEmpty() + st := p.SampleType() st.SetTypeStrindex(2) st.SetUnitStrindex(3) pt := p.PeriodType() @@ -64,9 +69,7 @@ func BenchmarkTransform(b *testing.B) { s := p.Sample().AppendEmpty() s.TimestampsUnixNano().Append(42) - s.Value().Append(1) - s.SetLocationsLength(2) - s.SetLocationsStartIndex(0) + s.Values().Append(1) return rp }, diff --git a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform.go b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform.go index 9c63fced824cb..d32f4974d3478 100644 --- a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform.go +++ b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform.go @@ -46,12 +46,9 @@ func Transform(dic pprofile.ProfilesDictionary, resource pcommon.Resource, scope // and mixing profiles will make profiling information unusable. func checkProfileType(dic pprofile.ProfilesDictionary, profile pprofile.Profile) error { sampleType := profile.SampleType() - if sampleType.Len() != 1 { - return fmt.Errorf("expected 1 sample type but got %d", sampleType.Len()) - } - sType := getString(dic, int(sampleType.At(0).TypeStrindex())) - sUnit := getString(dic, int(sampleType.At(0).UnitStrindex())) + sType := getString(dic, int(sampleType.TypeStrindex())) + sUnit := getString(dic, int(sampleType.UnitStrindex())) // Make sure only on-CPU profiling data is accepted at the moment. // This needs to match with @@ -96,7 +93,7 @@ func stackPayloads(dic pprofile.ProfilesDictionary, resource pcommon.Resource, s } for _, sample := range profile.Sample().All() { - frames, frameTypes, leafFrame, err := stackFrames(dic, profile, sample) + frames, frameTypes, leafFrame, err := stackFrames(dic, sample) if err != nil { return nil, fmt.Errorf("failed to create stackframes: %w", err) } @@ -144,8 +141,8 @@ func stackPayloads(dic pprofile.ProfilesDictionary, resource pcommon.Resource, s event.TimeStamp = newUnixTime64(t) count := 1 - if j < sample.Value().Len() { - count = int(sample.Value().At(j)) + if j < sample.Values().Len() { + count = int(sample.Values().At(j)) } for range count { stackPayload = append(stackPayload, StackPayload{ @@ -237,8 +234,9 @@ func stackTraceEvent(dic pprofile.ProfilesDictionary, traceID string, sample ppr continue } attr := dic.AttributeTable().At(int(idx)) + key := dic.StringTable().At(int(attr.KeyStrindex())) - switch attribute.Key(attr.Key()) { + switch attribute.Key(key) { case semconv.ThreadNameKey: event.ThreadName = attr.Value().AsString() case semconv.ProcessExecutableNameKey: @@ -273,10 +271,11 @@ func stackTrace(stackTraceID string, frames []StackFrame, frameTypes []libpf.Fra } } -func stackFrames(dic pprofile.ProfilesDictionary, profile pprofile.Profile, sample pprofile.Sample) ([]StackFrame, []libpf.FrameType, *frameID, error) { - frames := make([]StackFrame, 0, sample.LocationsLength()) +func stackFrames(dic pprofile.ProfilesDictionary, sample pprofile.Sample) ([]StackFrame, []libpf.FrameType, *frameID, error) { + stack := dic.StackTable().At(int(sample.StackIndex())) + frames := make([]StackFrame, 0, stack.LocationIndices().Len()) - locations := getLocations(dic, profile, sample) + locations := getLocations(dic, stack) totalFrames := 0 for _, location := range locations { totalFrames += location.Line().Len() @@ -331,7 +330,8 @@ func stackFrames(dic pprofile.ProfilesDictionary, profile pprofile.Profile, samp func getFrameID(dic pprofile.ProfilesDictionary, location pprofile.Location) *frameID { // The MappingIndex is known to be valid. fileID := libpf.FileID{} - if location.HasMappingIndex() { + + if location.MappingIndex() > 0 { mapping := dic.MappingTable().At(int(location.MappingIndex())) fileID, _ = getBuildID(dic, mapping) } @@ -380,7 +380,9 @@ func getStringFromAttribute(dic pprofile.ProfilesDictionary, record attributable return "", fmt.Errorf("requested attribute index (%d) "+ "exceeds size of attribute table (%d)", idx, lenAttrTable) } - if dic.AttributeTable().At(idx).Key() == attrKey { + + key := dic.StringTable().At(int(dic.AttributeTable().At(idx).KeyStrindex())) + if key == attrKey { return dic.AttributeTable().At(idx).Value().AsString(), nil } } @@ -408,7 +410,11 @@ func executables(dic pprofile.ProfilesDictionary, mappings pprofile.MappingSlice metadata := make([]ExeMetadata, 0, mappings.Len()) lastSeen := GetStartOfWeekFromTime(time.Now()) - for _, mapping := range mappings.All() { + for i, mapping := range mappings.All() { + if i == 0 { + continue + } + filename := dic.StringTable().At(int(mapping.FilenameStrindex())) if filename == "" { // This is true for interpreted languages like Python. @@ -463,18 +469,13 @@ func stackTraceID(frames []StackFrame) (string, error) { return traceHash.Base64(), nil } -func getLocations(dic pprofile.ProfilesDictionary, profile pprofile.Profile, sample pprofile.Sample) []pprofile.Location { - locations := make([]pprofile.Location, 0, sample.LocationsLength()) +func getLocations(dic pprofile.ProfilesDictionary, stack pprofile.Stack) []pprofile.Location { + locations := make([]pprofile.Location, 0, stack.LocationIndices().Len()) - firstIndexPos := int(sample.LocationsStartIndex()) - lastIndexPos := int(sample.LocationsStartIndex() + sample.LocationsLength()) - lastIndexPos = min(lastIndexPos, profile.LocationIndices().Len()) - for i := firstIndexPos; i < lastIndexPos; i++ { - locationIndex := int(profile.LocationIndices().At(i)) - if locationIndex < dic.LocationTable().Len() { - locations = append(locations, dic.LocationTable().At(locationIndex)) - } + for i := range stack.LocationIndices().All() { + locations = append(locations, dic.LocationTable().At(i)) } + return locations } @@ -505,7 +506,7 @@ func newHostMetadata(dic pprofile.ProfilesDictionary, resource pcommon.Resource, addEventHostData(attrs, resource.Attributes()) addEventHostData(attrs, scope.Attributes()) - addEventHostData(attrs, pprofile.FromAttributeIndices(dic.AttributeTable(), profile)) + addEventHostData(attrs, pprofile.FromAttributeIndices(dic.AttributeTable(), profile, dic)) return attrs } diff --git a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform_test.go b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform_test.go index 38949ff5c48ce..da2a44fce92b5 100644 --- a/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform_test.go +++ b/exporter/elasticsearchexporter/internal/serializer/otelserializer/serializeprofiles/transform_test.go @@ -71,6 +71,7 @@ func TestTransform(t *testing.T) { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("samples", "count", "cpu", "nanoseconds") + dic.StackTable().AppendEmpty() return dic }, @@ -80,7 +81,7 @@ func TestTransform(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - st := p.SampleType().AppendEmpty() + st := p.SampleType() st.SetTypeStrindex(0) st.SetUnitStrindex(1) pt := p.PeriodType() @@ -100,6 +101,7 @@ func TestTransform(t *testing.T) { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("off-CPU", "events") + dic.StackTable().AppendEmpty() return dic }, @@ -109,7 +111,7 @@ func TestTransform(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - st := p.SampleType().AppendEmpty() + st := p.SampleType() st.SetTypeStrindex(0) st.SetUnitStrindex(1) @@ -126,6 +128,7 @@ func TestTransform(t *testing.T) { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append("samples", "count", "cpu", "nanoseconds") + dic.StackTable().AppendEmpty() l := dic.LocationTable().AppendEmpty() l.SetAddress(111) @@ -137,7 +140,7 @@ func TestTransform(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - st := p.SampleType().AppendEmpty() + st := p.SampleType() st.SetTypeStrindex(0) st.SetUnitStrindex(1) pt := p.PeriodType() @@ -157,18 +160,24 @@ func TestTransform(t *testing.T) { name: "with a single indexed sample", buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + stack := dic.StackTable().AppendEmpty() + + dic.StringTable().Append("firefox", "libc.so", "samples", "count", "cpu", "nanoseconds") + a := dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(6) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(7) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(8) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) - dic.StringTable().Append("firefox", "libc.so", "samples", "count", "cpu", "nanoseconds") - + dic.MappingTable().AppendEmpty() m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(1) m.SetFilenameStrindex(0) @@ -179,11 +188,12 @@ func TestTransform(t *testing.T) { l := dic.LocationTable().AppendEmpty() l.SetAddress(address) l.AttributeIndices().Append(0) - l.SetMappingIndex(0) + l.SetMappingIndex(1) l = dic.LocationTable().AppendEmpty() l.SetAddress(address2) l.AttributeIndices().Append(0) - l.SetMappingIndex(1) + l.SetMappingIndex(2) + stack.LocationIndices().Append(0, 1) return dic }, @@ -192,10 +202,9 @@ func TestTransform(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - p.LocationIndices().FromRaw([]int32{0, 1}) p.SetPeriod(1e9 / 20) - st := p.SampleType().AppendEmpty() + st := p.SampleType() st.SetTypeStrindex(2) st.SetUnitStrindex(3) pt := p.PeriodType() @@ -204,9 +213,8 @@ func TestTransform(t *testing.T) { s := p.Sample().AppendEmpty() s.TimestampsUnixNano().Append(42) - s.Value().Append(1) - s.SetLocationsLength(2) - s.SetLocationsStartIndex(0) + s.Values().Append(1) + s.SetStackIndex(0) return rp }, @@ -305,30 +313,37 @@ func TestStackPayloads(t *testing.T) { "with a single indexed sample": { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + stack := dic.StackTable().AppendEmpty() dic.StringTable().Append(stacktraceIDBase64, "firefox", "libc.so") a := dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(3) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(4) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(5) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(6) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") l := dic.LocationTable().AppendEmpty() - l.SetMappingIndex(0) + l.SetMappingIndex(1) l.SetAddress(address) l.AttributeIndices().Append(3) l = dic.LocationTable().AppendEmpty() - l.SetMappingIndex(1) + l.SetMappingIndex(2) l.SetAddress(address2) l.AttributeIndices().Append(3) + stack.LocationIndices().Append(0, 1) + dic.MappingTable().AppendEmpty() m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(1) m.SetFilenameStrindex(1) @@ -343,14 +358,12 @@ func TestStackPayloads(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - p.LocationIndices().FromRaw([]int32{0, 1}) p.SetPeriod(1e9 / 20) s := p.Sample().AppendEmpty() s.TimestampsUnixNano().Append(1) - s.Value().Append(1) - s.SetLocationsLength(2) - s.SetLocationsStartIndex(0) + s.Values().Append(1) + s.SetStackIndex(0) return rp }, @@ -419,27 +432,33 @@ func TestStackPayloads(t *testing.T) { "with a duplicated sample": { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + stack := dic.StackTable().AppendEmpty() dic.StringTable().Append(stacktraceIDBase64, "firefox", "libc.so") a := dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(3) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(4) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(5) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") l := dic.LocationTable().AppendEmpty() - l.SetMappingIndex(0) + l.SetMappingIndex(1) l.SetAddress(address) l.AttributeIndices().Append(2) l = dic.LocationTable().AppendEmpty() - l.SetMappingIndex(1) + l.SetMappingIndex(2) l.SetAddress(address2) l.AttributeIndices().Append(2) + stack.LocationIndices().Append(0, 1) + dic.MappingTable().AppendEmpty() m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(0) m.SetFilenameStrindex(1) @@ -454,14 +473,11 @@ func TestStackPayloads(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - p.LocationIndices().FromRaw([]int32{0, 1}) p.SetPeriod(1e9 / 20) s := p.Sample().AppendEmpty() s.TimestampsUnixNano().Append(1) - s.Value().Append(2) - s.SetLocationsLength(2) - s.SetLocationsStartIndex(0) + s.Values().Append(2) return rp }, @@ -538,27 +554,33 @@ func TestStackPayloads(t *testing.T) { "with a mapping without BuildID": { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + stack := dic.StackTable().AppendEmpty() dic.StringTable().Append(stacktraceIDBase64, "firefox", "libc.so", "no_build_id_binary") a := dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(4) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(5) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(6) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") l := dic.LocationTable().AppendEmpty() - l.SetMappingIndex(0) + l.SetMappingIndex(1) l.SetAddress(address) l.AttributeIndices().Append(2) l = dic.LocationTable().AppendEmpty() - l.SetMappingIndex(1) + l.SetMappingIndex(2) l.SetAddress(address2) l.AttributeIndices().Append(2) + stack.LocationIndices().Append(0, 1) + dic.MappingTable().AppendEmpty() m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(0) m.SetFilenameStrindex(1) @@ -576,14 +598,11 @@ func TestStackPayloads(t *testing.T) { sp := rp.ScopeProfiles().AppendEmpty() p := sp.Profiles().AppendEmpty() - p.LocationIndices().FromRaw([]int32{0, 1}) p.SetPeriod(1e9 / 20) s := p.Sample().AppendEmpty() s.TimestampsUnixNano().Append(1) - s.Value().Append(1) - s.SetLocationsLength(2) - s.SetLocationsStartIndex(0) + s.Values().Append(1) return rp }, @@ -761,12 +780,15 @@ func TestStackTraceEvent(t *testing.T) { buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() dic.StringTable().Append(stacktraceIDBase64) + dic.StackTable().AppendEmpty() a := dic.AttributeTable().AppendEmpty() - a.SetKey(string(semconv.ThreadNameKey)) + a.SetKeyStrindex(1) + dic.StringTable().Append(string(semconv.ThreadNameKey)) a.Value().SetStr("my_thread") a = dic.AttributeTable().AppendEmpty() - a.SetKey(string(semconv.ServiceNameKey)) + a.SetKeyStrindex(2) + dic.StringTable().Append(string(semconv.ServiceNameKey)) a.Value().SetStr("my_service") return dic @@ -829,32 +851,40 @@ func TestStackTrace(t *testing.T) { name: "creates a stack trace", buildDictionary: func() pprofile.ProfilesDictionary { dic := pprofile.NewProfilesDictionary() + stack := dic.StackTable().AppendEmpty() + + dic.StringTable().Append( + stacktraceIDBase64, + "kernel", + "native", + "dotnet", + ) + a := dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(4) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("kernel") a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(5) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("dotnet") a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(6) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(7) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildIDEncoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(8) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID2Encoded) a = dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(9) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(buildID3Encoded) - dic.StringTable().Append( - stacktraceIDBase64, - "kernel", - "native", - "dotnet", - ) - l := dic.LocationTable().AppendEmpty() l.SetMappingIndex(1) l.SetAddress(address) @@ -884,6 +914,7 @@ func TestStackTrace(t *testing.T) { locWithoutBuildID.AttributeIndices().Append(0) li = locWithoutBuildID.Line().AppendEmpty() li.SetLine(99) + stack.LocationIndices().Append(0, 1, 2, 3) dic.MappingTable().AppendEmpty() // empty default mapping at pos 0 m := dic.MappingTable().AppendEmpty() @@ -897,11 +928,7 @@ func TestStackTrace(t *testing.T) { }, buildProfile: func() pprofile.Profile { p := pprofile.NewProfile() - p.LocationIndices().FromRaw([]int32{0, 1, 2, 3}) - - s := p.Sample().AppendEmpty() - s.SetLocationsStartIndex(0) - s.SetLocationsLength(4) + p.Sample().AppendEmpty() return p }, @@ -923,7 +950,7 @@ func TestStackTrace(t *testing.T) { p := tt.buildProfile() s := p.Sample().At(0) - frames, frameTypes, _, err := stackFrames(dic, p, s) + frames, frameTypes, _, err := stackFrames(dic, s) require.NoError(t, err) stacktrace := stackTrace("", frames, frameTypes) @@ -947,36 +974,42 @@ func frameTypesToString(frameTypes []libpf.FrameType) string { func mkStackTraceID(t *testing.T, frameIDs []frameID) string { dic := pprofile.NewProfilesDictionary() + dic.MappingTable().AppendEmpty() + p := pprofile.NewProfile() indices := make([]int32, len(frameIDs)) for i := range frameIDs { indices[i] = int32(i) } - p.LocationIndices().FromRaw(indices) s := p.Sample().AppendEmpty() - s.SetLocationsLength(int32(len(frameIDs))) a := dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(0) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") + stack := dic.StackTable().AppendEmpty() + for i, frameID := range frameIDs { dic.StringTable().Append(frameID.FileID().StringNoQuotes()) a := dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(int32(dic.StringTable().Len())) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr(frameID.FileID().StringNoQuotes()) m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(int32(i + 1)) l := dic.LocationTable().AppendEmpty() - l.SetMappingIndex(int32(i)) + l.SetMappingIndex(int32(i + 1)) l.SetAddress(uint64(frameID.AddressOrLine())) l.AttributeIndices().Append(0) + + stack.LocationIndices().Append(int32(dic.LocationTable().Len() - 1)) } - frames, _, _, err := stackFrames(dic, p, s) + frames, _, _, err := stackFrames(dic, s) require.NoError(t, err) traceID, err := stackTraceID(frames) From 3e20638e38838d7d98ae5ba99aacfc47c2698cd9 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 10:35:35 +0200 Subject: [PATCH 03/14] upgrade coreinternal/testdata --- internal/coreinternal/testdata/profile.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/coreinternal/testdata/profile.go b/internal/coreinternal/testdata/profile.go index 4ff079d9d06ac..8731d011467a1 100644 --- a/internal/coreinternal/testdata/profile.go +++ b/internal/coreinternal/testdata/profile.go @@ -54,11 +54,13 @@ func fillProfileOne(dic pprofile.ProfilesDictionary, profile pprofile.Profile) { profile.AttributeIndices().Append(0) a := dic.AttributeTable().AppendEmpty() - a.SetKey("app") + a.SetKeyStrindex(int32(dic.StringTable().Len())) + dic.StringTable().Append("app") a.Value().SetStr("server") profile.AttributeIndices().Append(0) a = dic.AttributeTable().AppendEmpty() - a.SetKey("instance_num") + a.SetKeyStrindex(int32(dic.StringTable().Len())) + dic.StringTable().Append("instance_num") a.Value().SetInt(1) } @@ -68,10 +70,12 @@ func fillProfileTwo(dic pprofile.ProfilesDictionary, profile pprofile.Profile) { profile.AttributeIndices().Append(0) a := dic.AttributeTable().AppendEmpty() - a.SetKey("customer") + a.SetKeyStrindex(int32(dic.StringTable().Len())) + dic.StringTable().Append("customer") a.Value().SetStr("acme") profile.AttributeIndices().Append(0) a = dic.AttributeTable().AppendEmpty() - a.SetKey("env") + a.SetKeyStrindex(int32(dic.StringTable().Len())) + dic.StringTable().Append("env") a.Value().SetStr("dev") } From b11d48801c99a82052fc66c1e1848b55acca0c03 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 11:41:43 +0200 Subject: [PATCH 04/14] upgrade transform processor --- .../internal/profiles/processor_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/processor/transformprocessor/internal/profiles/processor_test.go b/processor/transformprocessor/internal/profiles/processor_test.go index 676a248639d17..ae9fee6083cf8 100644 --- a/processor/transformprocessor/internal/profiles/processor_test.go +++ b/processor/transformprocessor/internal/profiles/processor_test.go @@ -1350,11 +1350,11 @@ func putProfileAttribute(t *testing.T, td pprofile.Profiles, profileIndex int, k profile := td.ResourceProfiles().At(0).ScopeProfiles().At(0).Profiles().At(profileIndex) switch v := value.(type) { case string: - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, pcommon.NewValueStr(v))) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, pcommon.NewValueStr(v))) case []any: sl := pcommon.NewValueSlice() require.NoError(t, sl.FromRaw(v)) - require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, key, sl)) + require.NoError(t, pprofile.PutAttribute(dic.AttributeTable(), profile, dic, key, sl)) default: t.Fatalf("unsupported value type: %T", v) } @@ -1371,7 +1371,7 @@ func deleteProfileAttribute(pp pprofile.Profiles, idx int, key string) { profile := pp.ResourceProfiles().At(0).ScopeProfiles().At(0).Profiles().At(idx) indices := profile.AttributeIndices().AsRaw() for i := range indices { - if dic.AttributeTable().At(int(indices[i])).Key() == key { + if dic.StringTable().At(int(dic.AttributeTable().At(int(indices[i])).KeyStrindex())) == key { indices[i] = indices[len(indices)-1] profile.AttributeIndices().FromRaw(indices[:len(indices)-1]) return @@ -1386,7 +1386,7 @@ func deleteProfileAttributeSequential(pp pprofile.Profiles, idx int, key string) indices := profile.AttributeIndices().AsRaw() j := 0 for i := range indices { - if dic.AttributeTable().At(int(indices[i])).Key() == key { + if dic.StringTable().At(int(dic.AttributeTable().At(int(indices[i])).KeyStrindex())) == key { continue } indices[j] = indices[i] From f81445a1628f3d924b7e1ad8adcd86eaec572f68 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 14:12:16 +0200 Subject: [PATCH 05/14] fix count connector --- connector/countconnector/connector.go | 2 +- .../testdata/profiles/input.yaml | 92 ++++++++----------- 2 files changed, 41 insertions(+), 53 deletions(-) diff --git a/connector/countconnector/connector.go b/connector/countconnector/connector.go index 4f237752e9563..a5ad90418d2d4 100644 --- a/connector/countconnector/connector.go +++ b/connector/countconnector/connector.go @@ -217,7 +217,7 @@ func (c *count) ConsumeProfiles(ctx context.Context, ld pprofile.Profiles) error profile := scopeProfile.Profiles().At(k) pCtx := ottlprofile.NewTransformContext(profile, ld.Dictionary(), scopeProfile.Scope(), resourceProfile.Resource(), scopeProfile, resourceProfile) - attributes := pprofile.FromAttributeIndices(ld.Dictionary().AttributeTable(), profile) + attributes := pprofile.FromAttributeIndices(ld.Dictionary().AttributeTable(), profile, ld.Dictionary()) multiError = errors.Join(multiError, counter.update(ctx, attributes, pCtx)) } } diff --git a/connector/countconnector/testdata/profiles/input.yaml b/connector/countconnector/testdata/profiles/input.yaml index 68729e2f7fd1f..8f022e5b89a6e 100644 --- a/connector/countconnector/testdata/profiles/input.yaml +++ b/connector/countconnector/testdata/profiles/input.yaml @@ -11,30 +11,26 @@ resourceProfiles: - profiles: - attributeIndices: [0, 1] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [0, 2] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [3] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 - attributeIndices: [] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 100 scope: {} @@ -50,30 +46,26 @@ resourceProfiles: - profiles: - attributeIndices: [0, 1] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [0, 2] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [3] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 - attributeIndices: [] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 100 scope: {} @@ -86,30 +78,26 @@ resourceProfiles: - profiles: - attributeIndices: [0, 1] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [0, 2] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [3] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 - attributeIndices: [] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 100 scope: {} @@ -118,45 +106,45 @@ resourceProfiles: - profiles: - attributeIndices: [0, 1] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [0, 2] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [3] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 - attributeIndices: [] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 100 scope: {} dictionary: attributeTable: - - key: profile.required + - keyStrindex: 1 value: stringValue: foo - - key: profile.optional + - keyStrindex: 2 value: stringValue: bar - - key: profile.optional + - keyStrindex: 2 value: stringValue: notbar - - key: profile.required + - keyStrindex: 1 value: stringValue: notfoo stringTable: - count + - profile.required + - profile.optional + stackTable: + - {} From 92c4e5cd56189ccbf01c63d150369f1d13fa98c7 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 14:32:48 +0200 Subject: [PATCH 06/14] fix signaltometrics connector --- .../signaltometricsconnector/connector.go | 2 +- .../testdata/profiles/profiles.yaml | 32 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/connector/signaltometricsconnector/connector.go b/connector/signaltometricsconnector/connector.go index a8d3c1d5933d6..e28f33264bc54 100644 --- a/connector/signaltometricsconnector/connector.go +++ b/connector/signaltometricsconnector/connector.go @@ -264,7 +264,7 @@ func (sm *signalToMetrics) ConsumeProfiles(ctx context.Context, profiles pprofil for k := 0; k < scopeProfile.Profiles().Len(); k++ { profile := scopeProfile.Profiles().At(k) - profileAttrs := pprofile.FromAttributeIndices(profiles.Dictionary().AttributeTable(), profile) + profileAttrs := pprofile.FromAttributeIndices(profiles.Dictionary().AttributeTable(), profile, profiles.Dictionary()) for _, md := range sm.profileMetricDefs { filteredProfileAttrs, ok := md.FilterAttributes(profileAttrs) diff --git a/connector/signaltometricsconnector/testdata/profiles/profiles.yaml b/connector/signaltometricsconnector/testdata/profiles/profiles.yaml index 814e35f1eef2c..0afd48b3804d7 100644 --- a/connector/signaltometricsconnector/testdata/profiles/profiles.yaml +++ b/connector/signaltometricsconnector/testdata/profiles/profiles.yaml @@ -11,44 +11,46 @@ resourceProfiles: - profiles: - attributeIndices: [0, 1] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 duration: 10000 - attributeIndices: [2, 3] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 stringTable: - count duration: 10000 - attributeIndices: [5] sample: - - locationsLength: 0 - timestampsUnixNano: ["0"] + - timestampsUnixNano: ["0"] sampleType: - - unitStrindex: 0 + unitStrindex: 0 scope: {} dictionary: attributeTable: - - key: profile.foo + - keyStrindex: 0 value: stringValue: foo - - key: profile.bar + - keyStrindex: 1 value: stringValue: bar - - key: profile.required + - keyStrindex: 2 value: stringValue: foo - - key: profile.optional + - keyStrindex: 3 value: stringValue: notbar - - key: profile.optional + - keyStrindex: 3 value: stringValue: notbar - - key: profile.required + - keyStrindex: 2 value: stringValue: notfoo + stringTable: + - profile.foo + - profile.bar + - profile.required + - profile.optional From 0992a5128c1d49c696f495ff4042435d5444fc53 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 15:12:32 +0200 Subject: [PATCH 07/14] fix golden pkg --- pkg/golden/golden_test.go | 17 +++++++++++------ .../testdata/profiles-roundtrip/expected.yaml | 18 +++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/pkg/golden/golden_test.go b/pkg/golden/golden_test.go index a33ff3e0c1d05..7a95bc8747bde 100644 --- a/pkg/golden/golden_test.go +++ b/pkg/golden/golden_test.go @@ -352,7 +352,7 @@ func TestWriteProfiles(t *testing.T) { expectedBytes = bytes.ReplaceAll(expectedBytes, []byte("\r\n"), []byte("\n")) } - require.Equal(t, expectedBytes, actualBytes) + require.Equal(t, string(expectedBytes), string(actualBytes)) } func TestProfilesRoundTrip(t *testing.T) { @@ -374,7 +374,7 @@ func CreateTestProfiles() pprofile.Profiles { profile := scope.Profiles().AppendEmpty() dic.StringTable().Append("samples", "count", "cpu", "nanoseconds") - st := profile.SampleType().AppendEmpty() + st := profile.SampleType() st.SetTypeStrindex(0) st.SetUnitStrindex(1) pt := profile.PeriodType() @@ -382,20 +382,25 @@ func CreateTestProfiles() pprofile.Profiles { pt.SetUnitStrindex(3) a := dic.AttributeTable().AppendEmpty() - a.SetKey("process.executable.build_id.htlhash") + a.SetKeyStrindex(4) + dic.StringTable().Append("process.executable.build_id.htlhash") a.Value().SetStr("600DCAFE4A110000F2BF38C493F5FB92") a = dic.AttributeTable().AppendEmpty() - a.SetKey("profile.frame.type") + a.SetKeyStrindex(5) + dic.StringTable().Append("profile.frame.type") a.Value().SetStr("native") a = dic.AttributeTable().AppendEmpty() - a.SetKey("host.id") + a.SetKeyStrindex(6) + dic.StringTable().Append("host.id") a.Value().SetStr("localhost") profile.AttributeIndices().Append(2) sample := profile.Sample().AppendEmpty() sample.TimestampsUnixNano().Append(0) - sample.SetLocationsLength(1) + + stack := dic.StackTable().AppendEmpty() + stack.LocationIndices().Append(0) m := dic.MappingTable().AppendEmpty() m.AttributeIndices().Append(0) diff --git a/pkg/golden/testdata/profiles-roundtrip/expected.yaml b/pkg/golden/testdata/profiles-roundtrip/expected.yaml index 8b4aeb4f8e529..31a8d93c0067f 100644 --- a/pkg/golden/testdata/profiles-roundtrip/expected.yaml +++ b/pkg/golden/testdata/profiles-roundtrip/expected.yaml @@ -1,27 +1,32 @@ dictionary: attributeTable: - - key: process.executable.build_id.htlhash + - keyStrindex: 4 value: stringValue: 600DCAFE4A110000F2BF38C493F5FB92 - - key: profile.frame.type + - keyStrindex: 5 value: stringValue: native - - key: host.id + - keyStrindex: 6 value: stringValue: localhost locationTable: - address: "111" attributeIndices: - 1 - mappingIndex: 0 mappingTable: - attributeIndices: - 0 + stackTable: + - locationIndices: + - 0 stringTable: - samples - count - cpu - nanoseconds + - process.executable.build_id.htlhash + - profile.frame.type + - host.id resourceProfiles: - resource: {} scopeProfiles: @@ -32,9 +37,8 @@ resourceProfiles: typeStrindex: 2 unitStrindex: 3 sample: - - locationsLength: 1 - timestampsUnixNano: + - timestampsUnixNano: - "0" sampleType: - - unitStrindex: 1 + unitStrindex: 1 scope: {} From 4a0f60a0323d2f84006cb81c143a5a5455186745 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 15:48:35 +0200 Subject: [PATCH 08/14] fix pprofiletest linter --- pkg/pdatatest/pprofiletest/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/pdatatest/pprofiletest/types.go b/pkg/pdatatest/pprofiletest/types.go index e061cd8f1a3bb..1a9cfb28b9b97 100644 --- a/pkg/pdatatest/pprofiletest/types.go +++ b/pkg/pdatatest/pprofiletest/types.go @@ -298,7 +298,7 @@ type KeyValueAndUnit struct { func (a *KeyValueAndUnit) Transform(dic pprofile.ProfilesDictionary) int32 { pa := dic.AttributeTable().AppendEmpty() pa.SetKeyStrindex(addString(dic, a.Key)) - pa.Value().FromRaw(a.Value) + _ = pa.Value().FromRaw(a.Value) pa.SetUnitStrindex(addString(dic, a.Unit)) return int32(dic.AttributeTable().Len() - 1) } From af7d20922cf8d461aa723e4f3bea2ce9fbd87252 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 16:07:15 +0200 Subject: [PATCH 09/14] fix linter in pkg/ottl --- pkg/ottl/contexts/internal/logprofile/logging.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkg/ottl/contexts/internal/logprofile/logging.go b/pkg/ottl/contexts/internal/logprofile/logging.go index 1e69d62b1fbc9..7eafff537e979 100644 --- a/pkg/ottl/contexts/internal/logprofile/logging.go +++ b/pkg/ottl/contexts/internal/logprofile/logging.go @@ -152,16 +152,6 @@ func (s ProfileSample) MarshalLogObject(encoder zapcore.ObjectEncoder) error { return joinedErr } -type valueTypes []valueType - -func (s valueTypes) MarshalLogArray(encoder zapcore.ArrayEncoder) error { - var err error - for _, vt := range s { - err = errors.Join(err, encoder.AppendObject(vt)) - } - return err -} - type valueType struct { typ string unit string From 5b3039a6cf1831063281997545a42d4af9ff2224 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Fri, 5 Sep 2025 16:12:14 +0200 Subject: [PATCH 10/14] add changelog entries --- .chloggen/countconnector-pdata-upgrade.yaml | 27 +++++++++++++++++++ .../elasticsearchexporter-pdata-upgrade.yaml | 27 +++++++++++++++++++ .chloggen/golden-pdata-upgrade.yaml | 27 +++++++++++++++++++ .chloggen/ottl-pdata-upgrade.yaml | 27 +++++++++++++++++++ ...ignaltometricsconnector-pdata-upgrade.yaml | 27 +++++++++++++++++++ .../transformprocessor-pdata-upgrade.yaml | 27 +++++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 .chloggen/countconnector-pdata-upgrade.yaml create mode 100644 .chloggen/elasticsearchexporter-pdata-upgrade.yaml create mode 100644 .chloggen/golden-pdata-upgrade.yaml create mode 100644 .chloggen/ottl-pdata-upgrade.yaml create mode 100644 .chloggen/signaltometricsconnector-pdata-upgrade.yaml create mode 100644 .chloggen/transformprocessor-pdata-upgrade.yaml diff --git a/.chloggen/countconnector-pdata-upgrade.yaml b/.chloggen/countconnector-pdata-upgrade.yaml new file mode 100644 index 0000000000000..b256b5d68692c --- /dev/null +++ b/.chloggen/countconnector-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: countconnector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/elasticsearchexporter-pdata-upgrade.yaml b/.chloggen/elasticsearchexporter-pdata-upgrade.yaml new file mode 100644 index 0000000000000..9d93d0f053a9d --- /dev/null +++ b/.chloggen/elasticsearchexporter-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: elasticsearchexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/golden-pdata-upgrade.yaml b/.chloggen/golden-pdata-upgrade.yaml new file mode 100644 index 0000000000000..3bab4ec214c3f --- /dev/null +++ b/.chloggen/golden-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: golden + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/ottl-pdata-upgrade.yaml b/.chloggen/ottl-pdata-upgrade.yaml new file mode 100644 index 0000000000000..9bb9c60c2e815 --- /dev/null +++ b/.chloggen/ottl-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: ottl + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/signaltometricsconnector-pdata-upgrade.yaml b/.chloggen/signaltometricsconnector-pdata-upgrade.yaml new file mode 100644 index 0000000000000..c9d6a6324be61 --- /dev/null +++ b/.chloggen/signaltometricsconnector-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: signaltometricsconnector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/transformprocessor-pdata-upgrade.yaml b/.chloggen/transformprocessor-pdata-upgrade.yaml new file mode 100644 index 0000000000000..859b0c6730a5c --- /dev/null +++ b/.chloggen/transformprocessor-pdata-upgrade.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: transformprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Upgrade profiles proto to 1.8.0 + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42526] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] From 7a28e9b064fded7f13066d4f9bfea32e8c420459 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Tue, 9 Sep 2025 09:10:34 +0200 Subject: [PATCH 11/14] Update .chloggen/ottl-pdata-upgrade.yaml Co-authored-by: Edmo Vamerlatti Costa <11836452+edmocosta@users.noreply.github.com> --- .chloggen/ottl-pdata-upgrade.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.chloggen/ottl-pdata-upgrade.yaml b/.chloggen/ottl-pdata-upgrade.yaml index 9bb9c60c2e815..2e3cfacc93a64 100644 --- a/.chloggen/ottl-pdata-upgrade.yaml +++ b/.chloggen/ottl-pdata-upgrade.yaml @@ -4,7 +4,7 @@ change_type: breaking # The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) -component: ottl +component: pkg/ottl # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). note: Upgrade profiles proto to 1.8.0 From 5e36185cd76096051dae54b0d2eb7ee128254544 Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Tue, 9 Sep 2025 09:12:28 +0200 Subject: [PATCH 12/14] fix ottlprofile readme --- pkg/ottl/contexts/ottlprofile/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/ottl/contexts/ottlprofile/README.md b/pkg/ottl/contexts/ottlprofile/README.md index 2c65213b02ee7..02c3906a68e20 100644 --- a/pkg/ottl/contexts/ottlprofile/README.md +++ b/pkg/ottl/contexts/ottlprofile/README.md @@ -24,9 +24,8 @@ The following paths are supported. | instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | | profile.attributes | attributes of the profile being processed | pcommon.Map | | profile.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profile.sample_type | the sample types of the profile being processed | pprofile.ValueTypeSlice | +| profile.sample_type | the sample type of the profile being processed | pprofile.ValueType | | profile.sample | the samples of the profile being processed | pprofile.SampleSlice | -| profile.location_indices | the location indices of the profile being processed | []int64 | | profile.time_unix_nano | the time in unix nano of the profile being processed | int64 | | profile.time | the time in `time.Time` of the profile being processed | time.Time | | profile.duration_unix_nano | the duration in unix nano of the profile being processed | int64 | @@ -34,7 +33,6 @@ The following paths are supported. | profile.period_type | the period type of the profile being processed | pprofile.ValueType | | profile.period | the period of the profile being processed | int64 | | profile.comment_string_indices | the comment string indices of the profile being processed | []int64 | -| profile.default_sample_type_index | the default sample type string index of the profile being processed | int64 | | profile.profile_id | the profile id of the profile being processed | pprofile.ProfileID | | profile.profile_id.string | a string representation of the profile id | string | | profile.attribute_indices | the attribute indices of the profile being processed | []int64 | From f221687346e76894508ec0db52c4d550c429319f Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Tue, 9 Sep 2025 09:14:19 +0200 Subject: [PATCH 13/14] add linkto proto changelog in changelog entry --- .chloggen/ottl-pdata-upgrade.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.chloggen/ottl-pdata-upgrade.yaml b/.chloggen/ottl-pdata-upgrade.yaml index 2e3cfacc93a64..be41d6221432f 100644 --- a/.chloggen/ottl-pdata-upgrade.yaml +++ b/.chloggen/ottl-pdata-upgrade.yaml @@ -15,7 +15,7 @@ issues: [42526] # (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: +subtext: See proto changelog. https://github.com/open-telemetry/opentelemetry-proto/blob/main/CHANGELOG.md#180---2025-09-02 # If your change doesn't affect end users or the exported elements of any package, # you should instead start your pull request title with [chore] or use the "Skip Changelog" label. From a7e0547116603f7d41f4f87faaa021a103ff64eb Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Tue, 9 Sep 2025 14:20:32 +0200 Subject: [PATCH 14/14] update ottlprofilesamples too --- pkg/ottl/contexts/ottlprofilesample/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/ottl/contexts/ottlprofilesample/README.md b/pkg/ottl/contexts/ottlprofilesample/README.md index 8618dc6f71eab..c9387a674cc20 100644 --- a/pkg/ottl/contexts/ottlprofilesample/README.md +++ b/pkg/ottl/contexts/ottlprofilesample/README.md @@ -24,10 +24,8 @@ The following paths are supported. | instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | | profilesample.attributes | attributes of the profile being processed | pcommon.Map | | profilesample.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profilesample.locations_start_index | the locations start index into the ProfilesDictionary of the sample being processed. | int64 | -| profilesample.locations_length | the locations length of the sample being processed. | int64 | | profilesample.values | the values of the sample being processed. | []int64 | | profilesample.link_index | the link index into the ProfilesDictionary of the sample being processed. | int64 | -| profilesample.timestamps_unix_nano | the timestamps in unix nano associated with the sample being processed. | []int64 | -| profilesample.timestamps | the timestamps in `time.Time` associated with the sample being processed. | []time.Time | +| profilesample.timestamps_unix_nano | the timestamps in unix nano associated with the sample being processed. | []int64 | +| profilesample.timestamps | the timestamps in `time.Time` associated with the sample being processed. | []time.Time | | profilesample.attribute_indices | the attribute indices of the sample being processed. | []int64 |