Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .chloggen/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ components:
- pkg/xexporterhelper
- pkg/xprocessor
- pkg/xreceiver
- pkg/xscraper
- processor/batch
- processor/memory_limiter
- processor/sample
Expand Down
25 changes: 25 additions & 0 deletions .chloggen/scraper-profiles.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: pkg/xscraper

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Implement xscraper for Profiles.

# One or more tracking issues or pull requests related to the change
issues: [13915]

# (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:

# 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]
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ receiver/otlpreceiver/ @open-telemetry/collector-approvers
receiver/receiverhelper/ @open-telemetry/collector-approvers
receiver/xreceiver/ @open-telemetry/collector-approvers @mx-psi @dmathieu
scraper/ @open-telemetry/collector-approvers
scraper/xscraper @open-telemetry/collector-approvers
scraper/scraperhelper/ @open-telemetry/collector-approvers
service/ @open-telemetry/collector-approvers
service/internal/graph/ @open-telemetry/collector-approvers
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/utils/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@
"fileprovider",
"filterprocessor",
"filterset",
"florianl",
"fluentbit",
"fluentforward",
"forwardconnector",
Expand Down Expand Up @@ -503,6 +504,7 @@
"xprocessor",
"xprocessorhelper",
"xreceiver",
"xscraper",
"yamlmapprovider",
"yamlprovider",
"yamls",
Expand Down
44 changes: 44 additions & 0 deletions pdata/pprofile/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,54 @@

package pprofile // import "go.opentelemetry.io/collector/pdata/pprofile"

import "fmt"

// Equal checks equality with another Function
func (fn Function) Equal(val Function) bool {
return fn.NameStrindex() == val.NameStrindex() &&
fn.SystemNameStrindex() == val.SystemNameStrindex() &&
fn.FilenameStrindex() == val.FilenameStrindex() &&
fn.StartLine() == val.StartLine()
}

// switchDictionary updates the Function, switching its indices from one
// dictionary to another.
func (fn Function) switchDictionary(src, dst ProfilesDictionary) error {
if fn.NameStrindex() > 0 {
if src.StringTable().Len() < int(fn.NameStrindex()) {
return fmt.Errorf("invalid name index %d", fn.NameStrindex())
}

idx, err := SetString(dst.StringTable(), src.StringTable().At(int(fn.NameStrindex())))
if err != nil {
return fmt.Errorf("couldn't set name: %w", err)
}
fn.SetNameStrindex(idx)
}

if fn.SystemNameStrindex() > 0 {
if src.StringTable().Len() < int(fn.SystemNameStrindex()) {
return fmt.Errorf("invalid system name index %d", fn.SystemNameStrindex())
}

idx, err := SetString(dst.StringTable(), src.StringTable().At(int(fn.SystemNameStrindex())))
if err != nil {
return fmt.Errorf("couldn't set system name: %w", err)
}
fn.SetSystemNameStrindex(idx)
}

if fn.FilenameStrindex() > 0 {
if src.StringTable().Len() < int(fn.FilenameStrindex()) {
return fmt.Errorf("invalid filename index %d", fn.FilenameStrindex())
}

idx, err := SetString(dst.StringTable(), src.StringTable().At(int(fn.FilenameStrindex())))
if err != nil {
return fmt.Errorf("couldn't set filename: %w", err)
}
fn.SetFilenameStrindex(idx)
}

return nil
}
189 changes: 189 additions & 0 deletions pdata/pprofile/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
package pprofile

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFunctionEqual(t *testing.T) {
Expand Down Expand Up @@ -63,6 +65,193 @@ func TestFunctionEqual(t *testing.T) {
}
}

func TestFunctionSwitchDictionary(t *testing.T) {
for _, tt := range []struct {
name string
function Function

src ProfilesDictionary
dst ProfilesDictionary

wantFunction Function
wantDictionary ProfilesDictionary
wantErr error
}{
{
name: "with an empty key value and unit",
function: NewFunction(),

src: NewProfilesDictionary(),
dst: NewProfilesDictionary(),

wantFunction: NewFunction(),
wantDictionary: NewProfilesDictionary(),
},
{
name: "with an existing name",
function: func() Function {
fn := NewFunction()
fn.SetNameStrindex(1)
return fn
}(),

src: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "test")
return d
}(),
dst: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo")
return d
}(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetNameStrindex(2)
return fn
}(),
wantDictionary: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo", "test")
return d
}(),
},
{
name: "with a name index that does not match anything",
function: func() Function {
fn := NewFunction()
fn.SetNameStrindex(1)
return fn
}(),

src: NewProfilesDictionary(),
dst: NewProfilesDictionary(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetNameStrindex(1)
return fn
}(),
wantDictionary: NewProfilesDictionary(),
wantErr: errors.New("invalid name index 1"),
},
{
name: "with an existing system name",
function: func() Function {
fn := NewFunction()
fn.SetSystemNameStrindex(1)
return fn
}(),

src: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "test")
return d
}(),
dst: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo")
return d
}(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetSystemNameStrindex(2)
return fn
}(),
wantDictionary: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo", "test")
return d
}(),
},
{
name: "with a system name index that does not match anything",
function: func() Function {
fn := NewFunction()
fn.SetSystemNameStrindex(1)
return fn
}(),

src: NewProfilesDictionary(),
dst: NewProfilesDictionary(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetSystemNameStrindex(1)
return fn
}(),
wantDictionary: NewProfilesDictionary(),
wantErr: errors.New("invalid system name index 1"),
},
{
name: "with an existing filename",
function: func() Function {
fn := NewFunction()
fn.SetFilenameStrindex(1)
return fn
}(),

src: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "test")
return d
}(),
dst: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo")
return d
}(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetFilenameStrindex(2)
return fn
}(),
wantDictionary: func() ProfilesDictionary {
d := NewProfilesDictionary()
d.StringTable().Append("", "foo", "test")
return d
}(),
},
{
name: "with a filename index that does not match anything",
function: func() Function {
fn := NewFunction()
fn.SetFilenameStrindex(1)
return fn
}(),

src: NewProfilesDictionary(),
dst: NewProfilesDictionary(),

wantFunction: func() Function {
fn := NewFunction()
fn.SetFilenameStrindex(1)
return fn
}(),
wantDictionary: NewProfilesDictionary(),
wantErr: errors.New("invalid filename index 1"),
},
} {
t.Run(tt.name, func(t *testing.T) {
fn := tt.function
dst := tt.dst
err := fn.switchDictionary(tt.src, dst)

if tt.wantErr == nil {
require.NoError(t, err)
} else {
require.Equal(t, tt.wantErr, err)
}

assert.Equal(t, tt.wantFunction, fn)
assert.Equal(t, tt.wantDictionary, dst)
})
}
}

func buildFunction(name, sName, fileName int32, startLine int64) Function {
f := NewFunction()
f.SetNameStrindex(name)
Expand Down
32 changes: 32 additions & 0 deletions pdata/pprofile/keyvalueandunit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,42 @@

package pprofile // import "go.opentelemetry.io/collector/pdata/pprofile"

import "fmt"

// Equal checks equality with another KeyValueAndUnit
// It assumes both structs refer to the same dictionary.
func (ms KeyValueAndUnit) Equal(val KeyValueAndUnit) bool {
return ms.KeyStrindex() == val.KeyStrindex() &&
ms.UnitStrindex() == val.UnitStrindex() &&
ms.Value().Equal(val.Value())
}

// switchDictionary updates the KeyValueAndUnit, switching its indices from one
// dictionary to another.
func (ms KeyValueAndUnit) switchDictionary(src, dst ProfilesDictionary) error {
if ms.KeyStrindex() > 0 {
if src.StringTable().Len() < int(ms.KeyStrindex()) {
return fmt.Errorf("invalid key index %d", ms.KeyStrindex())
}

idx, err := SetString(dst.StringTable(), src.StringTable().At(int(ms.KeyStrindex())))
if err != nil {
return fmt.Errorf("couldn't set key: %w", err)
}
ms.SetKeyStrindex(idx)
}

if ms.UnitStrindex() > 0 {
if src.StringTable().Len() < int(ms.UnitStrindex()) {
return fmt.Errorf("invalid unit index %d", ms.UnitStrindex())
}

idx, err := SetString(dst.StringTable(), src.StringTable().At(int(ms.UnitStrindex())))
if err != nil {
return fmt.Errorf("couldn't set unit: %w", err)
}
ms.SetUnitStrindex(idx)
}

return nil
}
Loading