From 20e88137d09349e6ac5339b98e7c864faca75853 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Mon, 9 Dec 2024 15:37:34 +0000 Subject: [PATCH 1/8] faro translator: TranslateLogsToFaroPayloads --- pkg/translator/faro/go.mod | 13 + pkg/translator/faro/go.sum | 25 +- pkg/translator/faro/internal/testutil.go | 28 + pkg/translator/faro/logs_to_faro.go | 788 ++++++++++++++++++ pkg/translator/faro/logs_to_faro_test.go | 335 ++++++++ .../faro/testdata/payload-empty.json | 1 + .../testdata/payload-meta-app-name-1.json | 22 + .../testdata/payload-meta-app-name-2.json | 22 + .../testdata/payload-meta-app-release-1.json | 23 + .../testdata/payload-meta-app-release-2.json | 23 + ...ayload-multiple-records-same-resource.json | 304 +++++++ .../payload-two-records-same-resource.json | 35 + pkg/translator/faro/translator.go | 2 +- 13 files changed, 1618 insertions(+), 3 deletions(-) create mode 100644 pkg/translator/faro/internal/testutil.go create mode 100644 pkg/translator/faro/logs_to_faro.go create mode 100644 pkg/translator/faro/logs_to_faro_test.go create mode 100644 pkg/translator/faro/testdata/payload-empty.json create mode 100644 pkg/translator/faro/testdata/payload-meta-app-name-1.json create mode 100644 pkg/translator/faro/testdata/payload-meta-app-name-2.json create mode 100644 pkg/translator/faro/testdata/payload-meta-app-release-1.json create mode 100644 pkg/translator/faro/testdata/payload-meta-app-release-2.json create mode 100644 pkg/translator/faro/testdata/payload-multiple-records-same-resource.json create mode 100644 pkg/translator/faro/testdata/payload-two-records-same-resource.json diff --git a/pkg/translator/faro/go.mod b/pkg/translator/faro/go.mod index 3efe8b9..242cd02 100644 --- a/pkg/translator/faro/go.mod +++ b/pkg/translator/faro/go.mod @@ -3,18 +3,28 @@ module github.com/grafana/faro/pkg/translator/faro go 1.23.3 require ( + github.com/go-logfmt/logfmt v0.6.0 github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d + github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/pdata v1.20.0 + go.opentelemetry.io/otel v1.32.0 ) require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/oapi-codegen/runtime v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opentelemetry.io/otel/metric v1.32.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.24.0 // indirect @@ -22,4 +32,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/grafana/faro/pkg/go => ../../go diff --git a/pkg/translator/faro/go.sum b/pkg/translator/faro/go.sum index 5cfd6d6..cef772e 100644 --- a/pkg/translator/faro/go.sum +++ b/pkg/translator/faro/go.sum @@ -2,9 +2,17 @@ github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMz github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -12,13 +20,15 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d h1:6CXkEkw8iawiV1ncovud34IkkacCw7hp+YYd9kq3T94= -github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d/go.mod h1:fJa5cS+fHDPKao/KaCRgIGplg2/2UXSP8k+evjqBcqY= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -28,6 +38,8 @@ github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmt github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -37,6 +49,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/collector/pdata v1.20.0 h1:ePcwt4bdtISP0loHaE+C9xYoU2ZkIvWv89Fob16o9SM= go.opentelemetry.io/collector/pdata v1.20.0/go.mod h1:Ox1YVLe87cZDB/TL30i4SUz1cA5s6AM6SpFMfY61ICs= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -78,5 +96,8 @@ google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/translator/faro/internal/testutil.go b/pkg/translator/faro/internal/testutil.go new file mode 100644 index 0000000..411989e --- /dev/null +++ b/pkg/translator/faro/internal/testutil.go @@ -0,0 +1,28 @@ +package internal + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" + + faro "github.com/grafana/faro/pkg/go" +) + +func PayloadFromFile(t *testing.T, filename string) *faro.Payload { + t.Helper() + + f, err := os.Open(filepath.Join("testdata", filename)) + if err != nil { + t.Fatal(err) + } + + defer f.Close() + + var p faro.Payload + if err := json.NewDecoder(f).Decode(&p); err != nil { + t.Fatal(err) + } + + return &p +} diff --git a/pkg/translator/faro/logs_to_faro.go b/pkg/translator/faro/logs_to_faro.go new file mode 100644 index 0000000..bb9e7f2 --- /dev/null +++ b/pkg/translator/faro/logs_to_faro.go @@ -0,0 +1,788 @@ +package faro + +import ( + "context" + "crypto/md5" + "encoding/json" + "fmt" + "regexp" + "strconv" + "strings" + "time" + + "go.opentelemetry.io/otel" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" + + "github.com/go-logfmt/logfmt" + faroTypes "github.com/grafana/faro/pkg/go" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/plog" +) + +// TranslateLogsToFaroPayloads converts a Logs pipeline data into []*faro.Payload +func TranslateLogsToFaroPayloads(ctx context.Context, ld plog.Logs) ([]*faroTypes.Payload, error) { + ctx, span := otel.Tracer("").Start(ctx, "TranslateLogsToFaroPayloads") + defer span.End() + + metaMap := make(map[string]*faroTypes.Payload, 0) + payloads := make([]*faroTypes.Payload, 0) + rls := ld.ResourceLogs() + + for i := 0; i < rls.Len(); i++ { + scopeLogs := rls.At(i).ScopeLogs() + resource := rls.At(i).Resource() + for j := 0; j < scopeLogs.Len(); j++ { + logs := scopeLogs.At(j).LogRecords() + for k := 0; k < logs.Len(); k++ { + log := logs.At(k) + payload, err := translateLogToFaroPayload(log, resource) + if err != nil { + return payloads, err + } + meta := payload.Meta + // if payload meta already exists in the metaMap merge payload to the existing payload + w := md5.New() + if encodeErr := json.NewEncoder(w).Encode(meta); encodeErr != nil { + return payloads, err + } + metaKey := fmt.Sprintf("%x", w.Sum(nil)) + existingPayload, found := metaMap[metaKey] + if found { + // merge payloads with the same meta + mergePayloads(existingPayload, payload) + } else { + // if payload meta doesn't exist in the metaMap add new meta key to the metaMap + metaMap[metaKey] = payload + } + } + } + } + for _, payload := range metaMap { + payloads = append(payloads, payload) + } + return payloads, nil +} + +func mergePayloads(target *faroTypes.Payload, source *faroTypes.Payload) { + // merge logs + for _, log := range source.Logs { + target.Logs = append(target.Logs, log) + } + // merge events + for _, event := range source.Events { + target.Events = append(target.Events, event) + } + // merge measurements + for _, measurement := range source.Measurements { + target.Measurements = append(target.Measurements, measurement) + } + // merge exceptions + for _, exception := range source.Exceptions { + target.Exceptions = append(target.Exceptions, exception) + } +} + +func translateLogToFaroPayload(lr plog.LogRecord, rl pcommon.Resource) (*faroTypes.Payload, error) { + var payload *faroTypes.Payload + body := lr.Body().Str() + kv, err := parseLogfmtLine(body) + if err != nil { + return nil, err + } + kind, ok := kv["kind"] + if !ok { + return nil, fmt.Errorf("%s log record body doesn't contain kind", body) + } + switch kind { + case string(faroTypes.KindLog): + payload, err = convertLogKeyValToPayload(kv, rl) + if err != nil { + return nil, err + } + case string(faroTypes.KindEvent): + payload, err = convertEventKeyValsToPayload(kv, rl) + if err != nil { + return nil, err + } + case string(faroTypes.KindMeasurement): + payload, err = convertMeasurementKeyValsToPayload(kv, rl) + if err != nil { + return nil, err + } + case string(faroTypes.KindException): + payload, err = convertExceptionKeyValsToPayload(kv, rl) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("kind: %s is not supported, it must be one of %s, %s, %s, %s", kind, faroTypes.KindLog, faroTypes.KindEvent, faroTypes.KindMeasurement, faroTypes.KindException) + } + + return payload, nil +} + +func parseLogfmtLine(line string) (map[string]string, error) { + kv := make(map[string]string) + d := logfmt.NewDecoder(strings.NewReader(line)) + for d.ScanRecord() { + for d.ScanKeyval() { + key := string(d.Key()) + value := string(d.Value()) + kv[key] = value + } + } + if err := d.Err(); err != nil { + return nil, err + } + return kv, nil +} + +func convertLogKeyValToPayload(kv map[string]string, rl pcommon.Resource) (*faroTypes.Payload, error) { + var payload faroTypes.Payload + + meta, err := extractMetaFromKeyVal(kv, rl) + if err != nil { + return nil, err + } + + log, err := extractLogFromKeyVal(kv) + if err != nil { + return nil, err + } + + payload.Meta = *meta + payload.Logs = []faroTypes.Log{ + *log, + } + + return &payload, nil +} + +func convertEventKeyValsToPayload(kv map[string]string, rl pcommon.Resource) (*faroTypes.Payload, error) { + var payload faroTypes.Payload + + meta, err := extractMetaFromKeyVal(kv, rl) + if err != nil { + return nil, err + } + + event, err := extractEventFromKeyVal(kv) + if err != nil { + return nil, err + } + + payload.Meta = *meta + payload.Events = []faroTypes.Event{ + *event, + } + + return &payload, nil +} + +func convertExceptionKeyValsToPayload(kv map[string]string, rl pcommon.Resource) (*faroTypes.Payload, error) { + var payload faroTypes.Payload + meta, err := extractMetaFromKeyVal(kv, rl) + if err != nil { + return nil, err + } + exception, err := extractExceptionFromKeyVal(kv) + if err != nil { + return nil, err + } + payload.Meta = *meta + payload.Exceptions = []faroTypes.Exception{ + *exception, + } + + return &payload, nil +} + +func convertMeasurementKeyValsToPayload(kv map[string]string, rl pcommon.Resource) (*faroTypes.Payload, error) { + var payload faroTypes.Payload + meta, err := extractMetaFromKeyVal(kv, rl) + if err != nil { + return nil, err + } + measurement, err := extractMeasurementFromKeyVal(kv) + if err != nil { + return nil, err + } + payload.Meta = *meta + payload.Measurements = []faroTypes.Measurement{ + *measurement, + } + return &payload, nil +} + +func extractMetaFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes.Meta, error) { + var meta faroTypes.Meta + app, err := extractAppFromKeyVal(kv, rl) + if err != nil { + return nil, err + } + browser, err := extractBrowserFromKeyVal(kv) + if err != nil { + return nil, err + } + geo, err := extractGeoFromKeyVal(kv) + if err != nil { + return nil, err + } + k6, err := extractK6FromKeyVal(kv) + if err != nil { + return nil, err + } + page, err := extractPageFromKeyVal(kv) + if err != nil { + return nil, err + } + sdk, err := extractSDKFromKeyVal(kv) + if err != nil { + return nil, err + } + session, err := extractSessionFromKeyVal(kv) + if err != nil { + return nil, err + } + user, err := extractUserFromKeyVal(kv) + if err != nil { + return nil, err + } + view, err := extractViewFromKeyVal(kv) + if err != nil { + return nil, err + } + + meta.App = *app + meta.Browser = *browser + meta.Geo = *geo + meta.K6 = *k6 + meta.Page = *page + meta.SDK = *sdk + meta.Session = *session + meta.User = *user + meta.View = *view + return &meta, nil +} + +func extractTimestampFromKeyVal(kv map[string]string) (time.Time, error) { + var timestamp time.Time + val, ok := kv["timestamp"] + if !ok { + return timestamp, nil + } + timestamp, err := time.Parse(string(faroTypes.TimeFormatRFC3339Milli), val) + if err != nil { + return timestamp, err + } + return timestamp, nil +} + +func extractSDKFromKeyVal(kv map[string]string) (*faroTypes.SDK, error) { + var sdk faroTypes.SDK + if name, ok := kv["sdk_name"]; ok { + sdk.Name = name + } + if version, ok := kv["sdk_version"]; ok { + sdk.Version = version + } + if integrationsStr, ok := kv["sdk_integrations"]; ok { + integrations, err := parseIntegrationsFromString(integrationsStr) + if err != nil { + return nil, err + } + sdk.Integrations = integrations + } + return &sdk, nil +} + +func parseIntegrationsFromString(integrationsString string) ([]faroTypes.SDKIntegration, error) { + sdkIntegrations := make([]faroTypes.SDKIntegration, 0) + for _, integrationString := range strings.Split(integrationsString, ",") { + integrationNameVersion := strings.Split(integrationString, ":") + sdkIntegrations = append(sdkIntegrations, faroTypes.SDKIntegration{ + Name: integrationNameVersion[0], + Version: integrationNameVersion[1], + }) + } + + return sdkIntegrations, nil +} + +func extractAppFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes.App, error) { + var app faroTypes.App + rl.Attributes().Range(func(key string, val pcommon.Value) bool { + if key == string(semconv.ServiceNameKey) { + app.Name = val.Str() + } + if key == string(semconv.ServiceNamespaceKey) { + app.Namespace = val.Str() + } + if key == string(semconv.ServiceVersionKey) { + app.Version = val.Str() + } + if key == string(semconv.DeploymentEnvironmentKey) { + app.Environment = val.Str() + } + // force the app name stored in resource attribute service.name + // if service.name resource attribute is missing try to get app name from the custom "app" resource attribute + if key == "app" && app.Name == "" { + app.Name = val.Str() + } + if key == "app_bundle_id" { + app.BundleID = val.Str() + } + return true + }) + if name, ok := kv["app_name"]; ok { + // force the app name stored in resource attribute service.name or in custom "app" resource attribute + // if service.name resource attribute is missing as well as custom "app" attribute try to get app name from the log line + if app.Name == "" { + app.Name = name + } + } + if namespace, ok := kv["app_namespace"]; ok { + // force the app namespace stored in resource attribute service.namespace + // if service.namespace resource attribute is missing try to get app namespace from the log line + if app.Namespace == "" { + app.Namespace = namespace + } + } + if release, ok := kv["app_release"]; ok { + app.Release = release + } + if version, ok := kv["app_version"]; ok { + // force the app version stored in resource attribute service.version + // if service.version resource attribute is missing try to get app version from the log line + if app.Version == "" { + app.Version = version + } + } + if environment, ok := kv["app_environment"]; ok { + // force the app environment stored in resource attribute deployment.environment + // if deployment.environment resource attribute is missing try to get app environment from the log line + if app.Environment == "" { + app.Environment = environment + } + } + return &app, nil +} + +func extractBrowserFromKeyVal(kv map[string]string) (*faroTypes.Browser, error) { + var browser faroTypes.Browser + if name, ok := kv["browser_name"]; ok { + browser.Name = name + } + if version, ok := kv["browser_version"]; ok { + browser.Version = version + } + if os, ok := kv["browser_os"]; ok { + browser.OS = os + } + if mobile, ok := kv["browser_mobile"]; ok { + isMobile, err := strconv.ParseBool(mobile) + if err != nil { + return nil, err + } + browser.Mobile = isMobile + } + if language, ok := kv["browser_language"]; ok { + browser.Language = language + } + if userAgent, ok := kv["user_agent"]; ok { + browser.UserAgent = userAgent + } + if viewportHeight, ok := kv["browser_viewportHeight"]; ok { + browser.ViewportHeight = viewportHeight + } + if viewportWidth, ok := kv["browser_viewportWidth"]; ok { + browser.ViewportWidth = viewportWidth + } + + browserBrands, err := extractBrowserBrandsFromKeyVal(kv) + if err != nil { + return nil, err + } + browser.Brands = *browserBrands + return &browser, nil +} + +func extractBrowserBrandsFromKeyVal(kv map[string]string) (*faroTypes.Browser_Brands, error) { + var brands faroTypes.Browser_Brands + if brandsAsString, ok := kv["browser_brands"]; ok { + if err := brands.FromBrandsString(brandsAsString); err != nil { + return nil, err + } + return &brands, nil + } + + brandsMap := make(map[int64]faroTypes.Brand) + for key, val := range kv { + if suffix, found := strings.CutPrefix(key, "browser_brand_"); found { + brandAsString := strings.Split(suffix, "_") + idx, err := strconv.ParseInt(brandAsString[0], 10, 64) + if err != nil { + return nil, err + } + brand, ok := brandsMap[idx] + if !ok { + brandsMap[idx] = faroTypes.Brand{} + brand = brandsMap[idx] + } + if brandAsString[1] == "brand" { + brand.Brand = val + } + if brandAsString[1] == "version" { + brand.Version = val + } + brandsMap[idx] = brand + } + } + brandsMapLen := len(brandsMap) + if brandsMapLen != 0 { + brandsAsArray := make([]faroTypes.Brand, brandsMapLen) + for i, brand := range brandsMap { + brandsAsArray[i] = brand + } + if err := brands.FromBrandsArray(brandsAsArray); err != nil { + return nil, err + } + } + return &brands, nil +} + +func extractGeoFromKeyVal(kv map[string]string) (*faroTypes.Geo, error) { + var geo faroTypes.Geo + if continentISOCode, ok := kv["geo_continent_iso"]; ok { + geo.ContinentISOCode = continentISOCode + } + if countryISOCode, ok := kv["geo_country_iso"]; ok { + geo.CountryISOCode = countryISOCode + } + if subdivisionISO, ok := kv["geo_subdivision_iso"]; ok { + geo.SubdivisionISO = subdivisionISO + } + if city, ok := kv["geo_city"]; ok { + geo.City = city + } + if connectionType, ok := kv["geo_connection_type"]; ok { + geo.ConnectionType = connectionType + } + if carrier, ok := kv["geo_carrier"]; ok { + geo.Carrier = carrier + } + + return &geo, nil +} + +func extractK6FromKeyVal(kv map[string]string) (*faroTypes.K6, error) { + var k6 faroTypes.K6 + if isK6BrowserStr, ok := kv["k6_isK6Browser"]; ok { + isK6Browser, err := strconv.ParseBool(isK6BrowserStr) + if err != nil { + return nil, err + } + k6.IsK6Browser = isK6Browser + } + return &k6, nil +} + +func extractPageFromKeyVal(kv map[string]string) (*faroTypes.Page, error) { + var page faroTypes.Page + if id, ok := kv["page_id"]; ok { + page.ID = id + } + if url, ok := kv["page_url"]; ok { + page.URL = url + } + page.Attributes = extractAttributesWithPrefixFromKeyVal("page_attr_", kv) + return &page, nil +} + +func extractSessionFromKeyVal(kv map[string]string) (*faroTypes.Session, error) { + var session faroTypes.Session + if id, ok := kv["session_id"]; ok { + session.ID = id + } + session.Attributes = extractAttributesWithPrefixFromKeyVal("session_attr_", kv) + return &session, nil +} + +func extractUserFromKeyVal(kv map[string]string) (*faroTypes.User, error) { + var user faroTypes.User + if email, ok := kv["user_email"]; ok { + user.Email = email + } + if id, ok := kv["user_id"]; ok { + user.ID = id + } + if username, ok := kv["user_username"]; ok { + user.Username = username + } + + user.Attributes = extractAttributesWithPrefixFromKeyVal("user_attr_", kv) + return &user, nil +} + +func extractViewFromKeyVal(kv map[string]string) (*faroTypes.View, error) { + var view faroTypes.View + if name, ok := kv["view_name"]; ok { + view.Name = name + } + return &view, nil +} + +func extractLogFromKeyVal(kv map[string]string) (*faroTypes.Log, error) { + var log faroTypes.Log + timestamp, err := extractTimestampFromKeyVal(kv) + if err != nil { + return nil, err + } + log.Timestamp = timestamp + + if message, ok := kv["message"]; ok { + log.Message = message + } + + if level, ok := kv["level"]; ok { + switch level { + case string(faroTypes.LogLevelError): + log.LogLevel = faroTypes.LogLevelError + case string(faroTypes.LogLevelWarning): + log.LogLevel = faroTypes.LogLevelWarning + case string(faroTypes.LogLevelTrace): + log.LogLevel = faroTypes.LogLevelTrace + case string(faroTypes.LogLevelInfo): + log.LogLevel = faroTypes.LogLevelInfo + case string(faroTypes.LogLevelDebug): + log.LogLevel = faroTypes.LogLevelDebug + } + } + + logContext := extractLogContextFromKeyVal(kv) + if len(logContext) > 0 { + log.Context = logContext + } + trace, err := extractTraceFromKeyVal(kv) + if err != nil { + return nil, err + } + log.Trace = *trace + return &log, nil +} + +func extractLogContextFromKeyVal(kv map[string]string) faroTypes.LogContext { + logContext := make(faroTypes.LogContext, 0) + for key, val := range kv { + if after, found := strings.CutPrefix(key, "context_"); found { + logContext[after] = val + } + } + + return logContext +} + +func extractTraceFromKeyVal(kv map[string]string) (*faroTypes.TraceContext, error) { + var trace faroTypes.TraceContext + if traceID, ok := kv["traceID"]; ok { + trace.TraceID = traceID + } + if spanID, ok := kv["spanID"]; ok { + trace.SpanID = spanID + } + return &trace, nil +} + +func extractEventFromKeyVal(kv map[string]string) (*faroTypes.Event, error) { + var event faroTypes.Event + if domain, ok := kv["event_domain"]; ok { + event.Domain = domain + } + if name, ok := kv["event_name"]; ok { + event.Name = name + } + timestamp, err := extractTimestampFromKeyVal(kv) + if err != nil { + return nil, err + } + event.Timestamp = timestamp + trace, err := extractTraceFromKeyVal(kv) + if err != nil { + return nil, err + } + event.Trace = *trace + event.Attributes = extractAttributesWithPrefixFromKeyVal("event_data_", kv) + return &event, nil +} + +func extractExceptionFromKeyVal(kv map[string]string) (*faroTypes.Exception, error) { + var exception faroTypes.Exception + if exceptionType, ok := kv["type"]; ok { + exception.Type = exceptionType + } + if exceptionValue, ok := kv["value"]; ok { + exception.Value = exceptionValue + } + exceptionContext := extractExceptionContextFromKeyVal(kv) + if len(exceptionContext) > 0 { + exception.Context = exceptionContext + } + stacktrace, err := extractStacktraceFromKeyVal(kv, exception.Type, exception.Value) + if err != nil { + return nil, err + } + exception.Stacktrace = stacktrace + timestamp, err := extractTimestampFromKeyVal(kv) + if err != nil { + return nil, err + } + exception.Timestamp = timestamp + trace, err := extractTraceFromKeyVal(kv) + if err != nil { + return nil, err + } + exception.Trace = *trace + return &exception, nil +} + +func extractExceptionContextFromKeyVal(kv map[string]string) faroTypes.ExceptionContext { + exceptionContext := make(faroTypes.ExceptionContext, 0) + for key, val := range kv { + if after, found := strings.CutPrefix(key, "context_"); found { + exceptionContext[after] = val + } + } + + return exceptionContext +} + +func extractStacktraceFromKeyVal(kv map[string]string, exceptionType string, exceptionValue string) (*faroTypes.Stacktrace, error) { + stacktraceStr, ok := kv["stacktrace"] + if !ok { + return nil, nil + } + stacktrace, err := parseStacktraceFromString(stacktraceStr, exceptionType, exceptionValue) + if err != nil { + return nil, err + } + return stacktrace, nil +} + +func parseStacktraceFromString(stacktraceStr, exceptionType, exceptionValue string) (*faroTypes.Stacktrace, error) { + var stacktrace faroTypes.Stacktrace + frames := make([]faroTypes.Frame, 0) + framesAsString, _ := strings.CutPrefix(stacktraceStr, fmt.Sprintf("%s: %s", exceptionType, exceptionValue)) + framesAsArrayOfStrings := strings.Split(framesAsString, "\n at ") + for _, frameStr := range framesAsArrayOfStrings { + frame, err := parseFrameFromString(frameStr) + if err != nil { + return nil, err + } + if frame != nil { + frames = append(frames, *frame) + } + } + if len(frames) > 0 { + stacktrace.Frames = frames + } + return &stacktrace, nil +} + +func parseFrameFromString(frameStr string) (*faroTypes.Frame, error) { + var frame faroTypes.Frame + if len(frameStr) == 0 { + return nil, nil + } + + pattern := regexp.MustCompile(`(?P.+)?\s\(((?P.+)\|)?(?P.+)?:(?P\d+)?:(?P\d+)?\)$`) + matches := pattern.FindStringSubmatch(frameStr) + + frame.Function = matches[pattern.SubexpIndex("function")] + frame.Module = matches[pattern.SubexpIndex("module")] + frame.Filename = matches[pattern.SubexpIndex("filename")] + + if linenoStr := matches[pattern.SubexpIndex("lineno")]; linenoStr != "" { + lineno, err := strconv.ParseInt(linenoStr, 10, 64) + if err != nil { + return nil, err + } + frame.Lineno = int(lineno) + } + if colnoStr := matches[pattern.SubexpIndex("colno")]; colnoStr != "" { + colno, err := strconv.ParseInt(colnoStr, 10, 64) + if err != nil { + return nil, err + } + frame.Colno = int(colno) + } + + return &frame, nil +} + +func extractMeasurementFromKeyVal(kv map[string]string) (*faroTypes.Measurement, error) { + var measurement faroTypes.Measurement + if measurementType, ok := kv["type"]; ok { + measurement.Type = measurementType + } + measurementContext := extractMeasurementContextFromKeyVal(kv) + if len(measurementContext) > 0 { + measurement.Context = measurementContext + } + timestamp, err := extractTimestampFromKeyVal(kv) + if err != nil { + return nil, err + } + measurement.Timestamp = timestamp + trace, err := extractTraceFromKeyVal(kv) + if err != nil { + return nil, err + } + measurement.Trace = *trace + measurementValues, err := extractMeasurementValuesFromKeyVal(kv) + if err != nil { + return nil, err + } + measurement.Values = measurementValues + return &measurement, nil +} + +func extractMeasurementContextFromKeyVal(kv map[string]string) faroTypes.MeasurementContext { + measurementContext := make(faroTypes.MeasurementContext, 0) + for key, val := range kv { + if after, found := strings.CutPrefix(key, "context_"); found { + measurementContext[after] = val + } + } + + return measurementContext +} + +func extractMeasurementValuesFromKeyVal(kv map[string]string) (map[string]float64, error) { + values := make(map[string]float64, 0) + for key, val := range kv { + if valueName, found := strings.CutPrefix(key, "value_"); found { + valFloat64, err := strconv.ParseFloat(val, 64) + if err != nil { + return nil, err + } + values[valueName] = valFloat64 + } + } + if len(values) > 0 { + return values, nil + } + return nil, nil +} + +func extractAttributesWithPrefixFromKeyVal(prefix string, kv map[string]string) map[string]string { + attributes := make(map[string]string, 0) + for key, val := range kv { + if attrName, found := strings.CutPrefix(key, prefix); found { + attributes[attrName] = val + } + } + if len(attributes) > 0 { + return attributes + } + return nil +} diff --git a/pkg/translator/faro/logs_to_faro_test.go b/pkg/translator/faro/logs_to_faro_test.go new file mode 100644 index 0000000..1d74ca9 --- /dev/null +++ b/pkg/translator/faro/logs_to_faro_test.go @@ -0,0 +1,335 @@ +package faro + +import ( + "context" + "fmt" + "testing" + + faroTypes "github.com/grafana/faro/pkg/go" + "github.com/grafana/faro/pkg/translator/faro/internal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/plog" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +var emptyLogs = func() plog.Logs { + ld := plog.NewLogs() + return ld +} + +var logRecordWithMissingKind = func() plog.Logs { + ld := plog.NewLogs() + r := ld.ResourceLogs().AppendEmpty() + lrs := r.ScopeLogs().AppendEmpty().LogRecords() + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp") + return ld +} + +var logRecordWithUnknownKind = func() plog.Logs { + ld := plog.NewLogs() + r := ld.ResourceLogs().AppendEmpty() + lrs := r.ScopeLogs().AppendEmpty().LogRecords() + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=info message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp") + return ld +} + +var twoIdenticalLogRecordsWithDifferentServiceNameResourceAttribute = func() plog.Logs { + ld := plog.NewLogs() + r1 := ld.ResourceLogs().AppendEmpty() + r1.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp") + lr1 := r1.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty() + lr1.Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp") + r2 := ld.ResourceLogs().AppendEmpty() + r2.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp-second") + lr2 := r2.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty() + lr2.Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp") + + return ld +} + +var twoLogRecordsWithDifferentAppRelease = func() plog.Logs { + ld := plog.NewLogs() + r := ld.ResourceLogs().AppendEmpty() + lrs := r.ScopeLogs().AppendEmpty().LogRecords() + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp app_release=1.2.3") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp app_release=4.5.6") + + return ld +} + +var twoLogRecordsWithTheSameResource = func() plog.Logs { + ld := plog.NewLogs() + r := ld.ResourceLogs().AppendEmpty() + r.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp") + lrs := r.ScopeLogs().AppendEmpty().LogRecords() + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def app_name=testapp") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"loading price list\" level=trace context_component=AppRoot context_page=Pricing traceID=abcd spanID=ghj app_name=testapp") + + return ld +} + +var multipleLogRecordsWithTheSameResource = func() plog.Logs { + ld := plog.NewLogs() + r := ld.ResourceLogs().AppendEmpty() + resAttrs := r.Resource().Attributes() + resAttrs.PutStr(string(semconv.ServiceNameKey), "testapp") + resAttrs.PutStr(string(semconv.ServiceVersionKey), "abcdefg") + resAttrs.PutStr(string(semconv.ServiceNamespaceKey), "testnamespace") + resAttrs.PutStr(string(semconv.DeploymentEnvironmentKey), "production") + resAttrs.PutStr("app_bundle_id", "testBundleId") + + lrs := r.ScopeLogs().AppendEmpty().LogRecords() + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"loading price list\" level=trace context_component=AppRoot context_page=Pricing traceID=abcd spanID=ghj sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=exception type=Error value=\"Cannot read property 'find' of undefined\" stacktrace=\"Error: Cannot read property 'find' of undefined\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8639:42)\\n at dispatchAction (http://fe:3002/static/js/vendors~main.chunk.js:268095:9)\\n at scheduleUpdateOnFiber (http://fe:3002/static/js/vendors~main.chunk.js:273726:13)\\n at flushSyncCallbackQueue (http://fe:3002/static/js/vendors~main.chunk.js:263362:7)\\n at flushSyncCallbackQueueImpl (http://fe:3002/static/js/vendors~main.chunk.js:263374:13)\\n at runWithPriority$1 (http://fe:3002/static/js/vendors~main.chunk.js:263325:14)\\n at unstable_runWithPriority (http://fe:3002/static/js/vendors~main.chunk.js:291265:16)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:263379:30)\\n at performSyncWorkOnRoot (http://fe:3002/static/js/vendors~main.chunk.js:274126:22)\\n at renderRootSync (http://fe:3002/static/js/vendors~main.chunk.js:274509:11)\\n at workLoopSync (http://fe:3002/static/js/vendors~main.chunk.js:274543:9)\\n at performUnitOfWork (http://fe:3002/static/js/vendors~main.chunk.js:274606:16)\\n at beginWork$1 (http://fe:3002/static/js/vendors~main.chunk.js:275746:18)\\n at beginWork (http://fe:3002/static/js/vendors~main.chunk.js:270944:20)\\n at updateFunctionComponent (http://fe:3002/static/js/vendors~main.chunk.js:269291:24)\\n at renderWithHooks (http://fe:3002/static/js/vendors~main.chunk.js:266969:22)\\n at ? (http://fe:3002/static/js/main.chunk.js:2600:74)\\n at useGetBooksQuery (http://fe:3002/static/js/main.chunk.js:1299:65)\\n at Module.useQuery (http://fe:3002/static/js/vendors~main.chunk.js:8495:85)\\n at useBaseQuery (http://fe:3002/static/js/vendors~main.chunk.js:8656:83)\\n at useDeepMemo (http://fe:3002/static/js/vendors~main.chunk.js:8696:14)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8657:55)\\n at QueryData.execute (http://fe:3002/static/js/vendors~main.chunk.js:7883:47)\\n at QueryData.getExecuteResult (http://fe:3002/static/js/vendors~main.chunk.js:7944:23)\\n at QueryData._this.getQueryResult (http://fe:3002/static/js/vendors~main.chunk.js:7790:19)\\n at new ApolloError (http://fe:3002/static/js/vendors~main.chunk.js:5164:24)\" traceID=abcd spanID=def context_ReactError=\"Annoying Error\" context_component=ReactErrorBoundary sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=measurement type=\"page load\" context_hello=world ttfb=14.000000 ttfcp=22.120000 ttfp=20.120000 traceID=abcd spanID=def value_ttfb=14 value_ttfcp=22.12 value_ttfp=20.12 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2023-11-16T10:00:55.995Z kind=event event_name=faro.performanceEntry event_domain=browser event_data_connectEnd=3656 event_data_connectStart=337 event_data_decodedBodySize=0 event_data_domainLookupEnd=590 event_data_domainLookupStart=588 event_data_duration=3371 event_data_encodedBodySize=0 event_data_entryType=resource event_data_fetchStart=331 event_data_initiatorType=other event_data_name=https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css.map event_data_nextHopProtocol=h2 event_data_redirectEnd=0 event_data_redirectStart=0 event_data_requestStart=3656 event_data_responseEnd=3702 event_data_responseStart=3690 event_data_secureConnectionStart=3638 event_data_serverTiming=[] event_data_startTime=331 event_data_transferSize=0 event_data_workerStart=0 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + + return ld +} + +func TestTranslateLogsToFaroPayload(t *testing.T) { + testcases := []struct { + name string + ld plog.Logs + wantPayloads []*faroTypes.Payload + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Empty logs", + ld: emptyLogs(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Log body doesn't contain kind", + ld: logRecordWithMissingKind(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + return payloads + }(), + wantErr: assert.Error, + }, + { + name: "Log body contains unknown kind", + ld: logRecordWithUnknownKind(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + return payloads + }(), + wantErr: assert.Error, + }, + { + name: "Two identical log records with different service.name resource attribute should produce two faro payloads", + ld: twoIdenticalLogRecordsWithDifferentServiceNameResourceAttribute(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-meta-app-name-1.json")) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-meta-app-name-2.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Two log records with the same resource should produce one faro payload", + ld: twoLogRecordsWithTheSameResource(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-two-records-same-resource.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Two log records with different app_release in log body should produce two faro payloads", + ld: twoLogRecordsWithDifferentAppRelease(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-meta-app-release-1.json")) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-meta-app-release-2.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Multiple log records of different kinds with the same resource should produce one faro payload", + ld: multipleLogRecordsWithTheSameResource(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-multiple-records-same-resource.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + faroPayloads, err := TranslateLogsToFaroPayloads(context.TODO(), tt.ld) + tt.wantErr(t, err) + assert.EqualValues(t, tt.wantPayloads, faroPayloads) + }) + } +} + +func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { + tests := []struct { + name string + kv map[string]string + wantErr assert.ErrorAssertionFunc + wantBrands *faroTypes.Browser_Brands + }{ + { + name: "brands as string", + kv: map[string]string{ + "browser_brands": "Chromium;Google Inc.;", + }, + wantErr: assert.NoError, + wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + var brands faroTypes.Browser_Brands + err := brands.FromBrandsString("Chromium;Google Inc.;") + require.NoError(t, err) + return &brands + }(t), + }, + { + name: "brands as array", + kv: map[string]string{ + "browser_brand_0_brand": "brand1", + "browser_brand_0_version": "0.1.0", + "browser_brand_1_brand": "brand2", + "browser_brand_1_version": "0.2.0", + }, + wantErr: assert.NoError, + wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + var brands faroTypes.Browser_Brands + err := brands.FromBrandsArray(faroTypes.BrandsArray{ + { + Brand: "brand1", + Version: "0.1.0", + }, + { + Brand: "brand2", + Version: "0.2.0", + }, + }) + require.NoError(t, err) + return &brands + }(t), + }, + { + name: "brands are missing", + kv: map[string]string{}, + wantErr: assert.NoError, + wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + var brands faroTypes.Browser_Brands + return &brands + }(t), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + brands, err := extractBrowserBrandsFromKeyVal(tt.kv) + tt.wantErr(t, err, fmt.Sprintf("extractBrowserBrandsFromKeyVal(%v)", tt.kv)) + assert.Equal(t, tt.wantBrands, brands) + }) + } +} + +func Test_parseFrameFromString(t *testing.T) { + testcases := []struct { + name string + frameStr string + frame *faroTypes.Frame + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Frame string is empty", + frameStr: "", + frame: nil, + wantErr: assert.NoError, + }, + { + name: "All the frame fields are present in the frame string", + frameStr: "? (http://fe:3002/static/js/vendors~main.chunk.js:8639:42)", + frame: &faroTypes.Frame{ + Colno: 42, + Lineno: 8639, + Function: "?", + Filename: "http://fe:3002/static/js/vendors~main.chunk.js", + }, + wantErr: assert.NoError, + }, + { + name: "Function contains spaces", + frameStr: "new ApolloError (http://fe:3002/static/js/vendors~main.chunk.js:5164:24)", + frame: &faroTypes.Frame{ + Colno: 24, + Lineno: 5164, + Function: "new ApolloError", + Filename: "http://fe:3002/static/js/vendors~main.chunk.js", + }, + wantErr: assert.NoError, + }, + { + name: "Module name is present in the frame string", + frameStr: "? (module_name|http://fe:3002/static/js/vendors~main.chunk.js:8639:42)", + frame: &faroTypes.Frame{ + Colno: 42, + Lineno: 8639, + Function: "?", + Filename: "http://fe:3002/static/js/vendors~main.chunk.js", + Module: "module_name", + }, + wantErr: assert.NoError, + }, + { + name: "Function name is empty", + frameStr: " (module_name|http://fe:3002/static/js/vendors~main.chunk.js:8639:42)", + frame: &faroTypes.Frame{ + Colno: 42, + Lineno: 8639, + Function: "", + Filename: "http://fe:3002/static/js/vendors~main.chunk.js", + Module: "module_name", + }, + wantErr: assert.NoError, + }, + { + name: "Filename is empty", + frameStr: " (module_name|:8639:42)", + frame: &faroTypes.Frame{ + Colno: 42, + Lineno: 8639, + Function: "", + Filename: "", + Module: "module_name", + }, + wantErr: assert.NoError, + }, + { + name: "Lineno, colno are empty", + frameStr: " (module_name|::)", + frame: &faroTypes.Frame{ + Colno: 0, + Lineno: 0, + Function: "", + Filename: "", + Module: "module_name", + }, + wantErr: assert.NoError, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + frame, err := parseFrameFromString(tt.frameStr) + tt.wantErr(t, err, fmt.Sprintf("parseFrameFromString(%s)", tt.frameStr)) + assert.Equal(t, tt.frame, frame) + }) + } +} diff --git a/pkg/translator/faro/testdata/payload-empty.json b/pkg/translator/faro/testdata/payload-empty.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/pkg/translator/faro/testdata/payload-empty.json @@ -0,0 +1 @@ +{} diff --git a/pkg/translator/faro/testdata/payload-meta-app-name-1.json b/pkg/translator/faro/testdata/payload-meta-app-name-1.json new file mode 100644 index 0000000..b69cbbb --- /dev/null +++ b/pkg/translator/faro/testdata/payload-meta-app-name-1.json @@ -0,0 +1,22 @@ +{ + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + } + ], + "meta": { + "app": { + "name": "testapp" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-meta-app-name-2.json b/pkg/translator/faro/testdata/payload-meta-app-name-2.json new file mode 100644 index 0000000..88d6c12 --- /dev/null +++ b/pkg/translator/faro/testdata/payload-meta-app-name-2.json @@ -0,0 +1,22 @@ +{ + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + } + ], + "meta": { + "app": { + "name": "testapp-second" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-meta-app-release-1.json b/pkg/translator/faro/testdata/payload-meta-app-release-1.json new file mode 100644 index 0000000..ef3c3ff --- /dev/null +++ b/pkg/translator/faro/testdata/payload-meta-app-release-1.json @@ -0,0 +1,23 @@ +{ + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + } + ], + "meta": { + "app": { + "name": "testapp", + "release": "1.2.3" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-meta-app-release-2.json b/pkg/translator/faro/testdata/payload-meta-app-release-2.json new file mode 100644 index 0000000..81741bc --- /dev/null +++ b/pkg/translator/faro/testdata/payload-meta-app-release-2.json @@ -0,0 +1,23 @@ +{ + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + } + ], + "meta": { + "app": { + "name": "testapp", + "release": "4.5.6" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json b/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json new file mode 100644 index 0000000..129f99f --- /dev/null +++ b/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json @@ -0,0 +1,304 @@ +{ + "events": [ + { + "name": "faro.performanceEntry", + "domain": "browser", + "attributes": { + "name": "https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css.map", + "entryType": "resource", + "startTime": "331", + "duration": "3371", + "initiatorType": "other", + "nextHopProtocol": "h2", + "workerStart": "0", + "redirectStart": "0", + "redirectEnd": "0", + "fetchStart": "331", + "domainLookupStart": "588", + "domainLookupEnd": "590", + "connectStart": "337", + "connectEnd": "3656", + "secureConnectionStart": "3638", + "requestStart": "3656", + "responseStart": "3690", + "responseEnd": "3702", + "transferSize": "0", + "encodedBodySize": "0", + "decodedBodySize": "0", + "serverTiming": "[]" + }, + "timestamp": "2023-11-16T10:00:55.995Z" + } + ], + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + }, + { + "message": "loading price list", + "level": "trace", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "ghj" + } + } + ], + "exceptions": [ + { + "type": "Error", + "value": "Cannot read property 'find' of undefined", + "stacktrace": { + "frames": [ + { + "colno": 42, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "?", + "in_app": true, + "lineno": 8639 + }, + { + "colno": 9, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "dispatchAction", + "in_app": true, + "lineno": 268095 + }, + { + "colno": 13, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "scheduleUpdateOnFiber", + "in_app": true, + "lineno": 273726 + }, + { + "colno": 7, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "flushSyncCallbackQueue", + "in_app": true, + "lineno": 263362 + }, + { + "colno": 13, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "flushSyncCallbackQueueImpl", + "in_app": true, + "lineno": 263374 + }, + { + "colno": 14, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "runWithPriority$1", + "lineno": 263325 + }, + { + "colno": 16, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "unstable_runWithPriority", + "lineno": 291265 + }, + { + "colno": 30, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "?", + "lineno": 263379 + }, + { + "colno": 22, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "performSyncWorkOnRoot", + "lineno": 274126 + }, + { + "colno": 11, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "renderRootSync", + "lineno": 274509 + }, + { + "colno": 9, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "workLoopSync", + "lineno": 274543 + }, + { + "colno": 16, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "performUnitOfWork", + "lineno": 274606 + }, + { + "colno": 18, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "beginWork$1", + "in_app": true, + "lineno": 275746 + }, + { + "colno": 20, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "beginWork", + "lineno": 270944 + }, + { + "colno": 24, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "updateFunctionComponent", + "lineno": 269291 + }, + { + "colno": 22, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "renderWithHooks", + "lineno": 266969 + }, + { + "colno": 74, + "filename": "http://fe:3002/static/js/main.chunk.js", + "function": "?", + "in_app": true, + "lineno": 2600 + }, + { + "colno": 65, + "filename": "http://fe:3002/static/js/main.chunk.js", + "function": "useGetBooksQuery", + "lineno": 1299 + }, + { + "colno": 85, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "Module.useQuery", + "lineno": 8495 + }, + { + "colno": 83, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "useBaseQuery", + "in_app": true, + "lineno": 8656 + }, + { + "colno": 14, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "useDeepMemo", + "lineno": 8696 + }, + { + "colno": 55, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "?", + "lineno": 8657 + }, + { + "colno": 47, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "QueryData.execute", + "in_app": true, + "lineno": 7883 + }, + { + "colno": 23, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "QueryData.getExecuteResult", + "lineno": 7944 + }, + { + "colno": 19, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "QueryData._this.getQueryResult", + "lineno": 7790 + }, + { + "colno": 24, + "filename": "http://fe:3002/static/js/vendors~main.chunk.js", + "function": "new ApolloError", + "in_app": true, + "lineno": 5164 + } + ] + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + }, + "context": { + "component": "ReactErrorBoundary", + "ReactError": "Annoying Error" + } + } + ], + "measurements": [ + { + "values": { + "ttfp": 20.12, + "ttfcp": 22.12, + "ttfb": 14 + }, + "type": "page load", + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + }, + "context": { + "hello": "world" + } + } + ], + "meta": { + "sdk": { + "name": "grafana-frontend-agent", + "version": "1.3.5" + }, + "app": { + "name": "testapp", + "namespace": "testnamespace", + "release": "0.8.2", + "version": "abcdefg", + "environment": "production", + "bundleId": "testBundleId" + }, + "user": { + "username": "domasx2", + "id": "123", + "email": "geralt@kaermorhen.org", + "attributes": { + "foo": "bar" + } + }, + "session": { + "id": "abcd", + "attributes": { + "time_elapsed": "100s" + } + }, + "page": { + "url": "https://example.com/page" + }, + "browser": { + "name": "chrome", + "version": "88.12.1", + "os": "linux", + "mobile": false + }, + "view": { + "name": "foobar" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-two-records-same-resource.json b/pkg/translator/faro/testdata/payload-two-records-same-resource.json new file mode 100644 index 0000000..2142f94 --- /dev/null +++ b/pkg/translator/faro/testdata/payload-two-records-same-resource.json @@ -0,0 +1,35 @@ +{ + "logs": [ + { + "message": "opened pricing page", + "level": "info", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "def" + } + }, + { + "message": "loading price list", + "level": "trace", + "context": { + "component": "AppRoot", + "page": "Pricing" + }, + "timestamp": "2021-09-30T10:46:17.680Z", + "trace": { + "trace_id": "abcd", + "span_id": "ghj" + } + } + ], + "meta": { + "app": { + "name": "testapp" + } + } +} diff --git a/pkg/translator/faro/translator.go b/pkg/translator/faro/translator.go index e40784f..b54de99 100644 --- a/pkg/translator/faro/translator.go +++ b/pkg/translator/faro/translator.go @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -package farotranslator // import "github.com/grafana/faro/pkg/translator/faro" +package faro // import "github.com/grafana/faro/pkg/translator/faro" import ( "context" From 180ee5a9431985b47f9e6809f0edfcfe6939e23e Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Wed, 11 Dec 2024 10:33:50 +0000 Subject: [PATCH 2/8] faro translator: TranslateTracesToFaroPayloads --- pkg/translator/faro/logs_to_faro.go | 7 + pkg/translator/faro/logs_to_faro_test.go | 2 +- .../payload-traces-meta-app-name-1.json | 42 ++++ .../payload-traces-meta-app-name-2.json | 42 ++++ ...yload-traces-two-traces-same-resource.json | 73 +++++++ pkg/translator/faro/traces_to_faro.go | 101 +++++++++ pkg/translator/faro/traces_to_faro_test.go | 193 ++++++++++++++++++ 7 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 pkg/translator/faro/testdata/payload-traces-meta-app-name-1.json create mode 100644 pkg/translator/faro/testdata/payload-traces-meta-app-name-2.json create mode 100644 pkg/translator/faro/testdata/payload-traces-two-traces-same-resource.json create mode 100644 pkg/translator/faro/traces_to_faro.go create mode 100644 pkg/translator/faro/traces_to_faro_test.go diff --git a/pkg/translator/faro/logs_to_faro.go b/pkg/translator/faro/logs_to_faro.go index bb9e7f2..5fc25b9 100644 --- a/pkg/translator/faro/logs_to_faro.go +++ b/pkg/translator/faro/logs_to_faro.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/otel" semconv "go.opentelemetry.io/otel/semconv/v1.21.0" @@ -80,6 +81,12 @@ func mergePayloads(target *faroTypes.Payload, source *faroTypes.Payload) { for _, exception := range source.Exceptions { target.Exceptions = append(target.Exceptions, exception) } + // merge traces + if source.Traces != nil { + sourceTraces := ptrace.NewTraces() + source.Traces.CopyTo(sourceTraces) + sourceTraces.ResourceSpans().MoveAndAppendTo(target.Traces.ResourceSpans()) + } } func translateLogToFaroPayload(lr plog.LogRecord, rl pcommon.Resource) (*faroTypes.Payload, error) { diff --git a/pkg/translator/faro/logs_to_faro_test.go b/pkg/translator/faro/logs_to_faro_test.go index 1d74ca9..ad58fa9 100644 --- a/pkg/translator/faro/logs_to_faro_test.go +++ b/pkg/translator/faro/logs_to_faro_test.go @@ -171,7 +171,7 @@ func TestTranslateLogsToFaroPayload(t *testing.T) { t.Run(tt.name, func(t *testing.T) { faroPayloads, err := TranslateLogsToFaroPayloads(context.TODO(), tt.ld) tt.wantErr(t, err) - assert.EqualValues(t, tt.wantPayloads, faroPayloads) + assert.ElementsMatch(t, tt.wantPayloads, faroPayloads) }) } } diff --git a/pkg/translator/faro/testdata/payload-traces-meta-app-name-1.json b/pkg/translator/faro/testdata/payload-traces-meta-app-name-1.json new file mode 100644 index 0000000..00c694d --- /dev/null +++ b/pkg/translator/faro/testdata/payload-traces-meta-app-name-1.json @@ -0,0 +1,42 @@ +{ + "traces": { + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "testapp" + } + } + ], + "droppedAttributesCount": 0 + }, + "scopeSpans": [ + { + "scope": { + "name": "@opentelemetry/instrumentation-fetch", + "version": "0.48.0" + }, + "spans": [ + { + "traceId": "bac44bf5d6d040fc5fdf9bc22442c6f2", + "spanId": "f71b2cc42962650f", + "name": "HTTP GET", + "kind": 3, + "startTimeUnixNano": "1718700770771000000", + "endTimeUnixNano": "1718700770800000000" + } + ] + } + ] + } + ] + }, + "meta": { + "app": { + "name": "testapp" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-traces-meta-app-name-2.json b/pkg/translator/faro/testdata/payload-traces-meta-app-name-2.json new file mode 100644 index 0000000..11ce7ac --- /dev/null +++ b/pkg/translator/faro/testdata/payload-traces-meta-app-name-2.json @@ -0,0 +1,42 @@ +{ + "traces": { + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "testapp-second" + } + } + ], + "droppedAttributesCount": 0 + }, + "scopeSpans": [ + { + "scope": { + "name": "@opentelemetry/instrumentation-fetch", + "version": "0.48.0" + }, + "spans": [ + { + "traceId": "bac44bf5d6d040fc5fdf9bc22442c6f2", + "spanId": "f71b2cc42962650f", + "name": "HTTP GET", + "kind": 3, + "startTimeUnixNano": "1718700770771000000", + "endTimeUnixNano": "1718700770800000000" + } + ] + } + ] + } + ] + }, + "meta": { + "app": { + "name": "testapp-second" + } + } +} diff --git a/pkg/translator/faro/testdata/payload-traces-two-traces-same-resource.json b/pkg/translator/faro/testdata/payload-traces-two-traces-same-resource.json new file mode 100644 index 0000000..277917d --- /dev/null +++ b/pkg/translator/faro/testdata/payload-traces-two-traces-same-resource.json @@ -0,0 +1,73 @@ +{ + "traces": { + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "testapp" + } + } + ], + "droppedAttributesCount": 0 + }, + "scopeSpans": [ + { + "scope": { + "name": "@opentelemetry/instrumentation-fetch", + "version": "0.48.0" + }, + "spans": [ + { + "traceId": "bac44bf5d6d040fc5fdf9bc22442c6f2", + "spanId": "f71b2cc42962650f", + "name": "HTTP GET", + "kind": 3, + "startTimeUnixNano": "1718700770771000000", + "endTimeUnixNano": "1718700770800000000" + } + ] + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "testapp" + } + } + ], + "droppedAttributesCount": 0 + }, + "scopeSpans": [ + { + "scope": { + "name": "@opentelemetry/instrumentation-fetch", + "version": "0.48.0" + }, + "spans": [ + { + "traceId": "bac44bf5d6d040fc5fdf9bc22442c6f2", + "spanId": "f71b2cc42962650f", + "name": "HTTP GET", + "kind": 3, + "startTimeUnixNano": "1718700770771000000", + "endTimeUnixNano": "1718700770800000000" + } + ] + } + ] + } + ] + }, + "meta": { + "app": { + "name": "testapp" + } + } +} diff --git a/pkg/translator/faro/traces_to_faro.go b/pkg/translator/faro/traces_to_faro.go new file mode 100644 index 0000000..42af39e --- /dev/null +++ b/pkg/translator/faro/traces_to_faro.go @@ -0,0 +1,101 @@ +package faro + +import ( + "context" + "crypto/md5" + "encoding/json" + "fmt" + + faroTypes "github.com/grafana/faro/pkg/go" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/otel" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +func TranslateTracesToFaroPayload(ctx context.Context, td ptrace.Traces) ([]*faroTypes.Payload, error) { + ctx, span := otel.Tracer("").Start(ctx, "TranslateTracesToFaroPayload") + defer span.End() + + resourceSpans := td.ResourceSpans() + resourceSpansLen := resourceSpans.Len() + if resourceSpansLen == 0 { + return nil, nil + } + metaMap := make(map[string]*faroTypes.Payload, 0) + payloads := make([]*faroTypes.Payload, 0) + + for i := 0; i < resourceSpansLen; i++ { + rs := resourceSpans.At(i) + payload := resourceSpansToFaroPayload(rs) + if payload == nil { + continue + } + + meta := payload.Meta + // if payload meta already exists in the metaMap merge payload to the existing payload + w := md5.New() + if encodeErr := json.NewEncoder(w).Encode(meta); encodeErr != nil { + return payloads, encodeErr + } + metaKey := fmt.Sprintf("%x", w.Sum(nil)) + existingPayload, found := metaMap[metaKey] + if found { + // merge payloads with the same meta + mergePayloads(existingPayload, payload) + } else { + // if payload meta doesn't exist in the metaMap add new meta key to the metaMap + metaMap[metaKey] = payload + } + } + for _, payload := range metaMap { + payloads = append(payloads, payload) + } + return payloads, nil +} + +func resourceSpansToFaroPayload(rs ptrace.ResourceSpans) *faroTypes.Payload { + resource := rs.Resource() + scopeSpans := rs.ScopeSpans() + + if resource.Attributes().Len() == 0 && scopeSpans.Len() == 0 { + return nil + } + + traces := ptrace.NewTraces() + rs.CopyTo(traces.ResourceSpans().AppendEmpty()) + + meta := extractMetaFromResourceAttributes(resource.Attributes()) + payload := &faroTypes.Payload{ + Meta: meta, + Traces: &faroTypes.Traces{ + Traces: traces, + }, + } + + return payload +} + +func extractMetaFromResourceAttributes(resourceAttributes pcommon.Map) faroTypes.Meta { + var meta faroTypes.Meta + var app faroTypes.App + + if appName, ok := resourceAttributes.Get(string(semconv.ServiceNameKey)); ok { + app.Name = appName.Str() + } + if appNamespace, ok := resourceAttributes.Get(string(semconv.ServiceNamespaceKey)); ok { + app.Namespace = appNamespace.Str() + } + if version, ok := resourceAttributes.Get(string(semconv.ServiceVersionKey)); ok { + app.Version = version.Str() + } + if environment, ok := resourceAttributes.Get(string(semconv.DeploymentEnvironmentKey)); ok { + app.Environment = environment.Str() + } + if appBundleID, ok := resourceAttributes.Get("app_bundle_id"); ok { + app.BundleID = appBundleID.Str() + } + + meta.App = app + return meta +} diff --git a/pkg/translator/faro/traces_to_faro_test.go b/pkg/translator/faro/traces_to_faro_test.go new file mode 100644 index 0000000..07b8cfc --- /dev/null +++ b/pkg/translator/faro/traces_to_faro_test.go @@ -0,0 +1,193 @@ +package faro + +import ( + "context" + "encoding/hex" + "testing" + + faroTypes "github.com/grafana/faro/pkg/go" + "github.com/grafana/faro/pkg/translator/faro/internal" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/ptrace" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +var emptyScopeSpansAndEmptyResourceAttributes = func() ptrace.Traces { + td := ptrace.NewTraces() + td.ResourceSpans().AppendEmpty() + return td +} + +var twoResourceSpansWithDifferentServiceNameResourceAttribute = func(t *testing.T) ptrace.Traces { + t.Helper() + td := ptrace.NewTraces() + rss1 := td.ResourceSpans() + rs1 := rss1.AppendEmpty() + rs1.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp") + scopeSpans1 := generateScopeSpans(t) + scopeSpans1.CopyTo(rs1.ScopeSpans().AppendEmpty()) + + rss2 := td.ResourceSpans() + rs2 := rss2.AppendEmpty() + rs2.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp-second") + scopeSpans2 := generateScopeSpans(t) + scopeSpans2.CopyTo(rs2.ScopeSpans().AppendEmpty()) + + return td +} + +var twoResourceSpansWithTheSameResource = func(t *testing.T) ptrace.Traces { + t.Helper() + td := ptrace.NewTraces() + rss := td.ResourceSpans() + rs1 := rss.AppendEmpty() + rs1.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp") + scopeSpans1 := generateScopeSpans(t) + scopeSpans1.CopyTo(rs1.ScopeSpans().AppendEmpty()) + rs2 := rss.AppendEmpty() + rs2.Resource().Attributes().PutStr(string(semconv.ServiceNameKey), "testapp") + scopeSpans2 := generateScopeSpans(t) + scopeSpans2.CopyTo(rs2.ScopeSpans().AppendEmpty()) + + return td +} + +func generateScopeSpans(t *testing.T) ptrace.ScopeSpans { + t.Helper() + var scopeSpans = ptrace.NewScopeSpans() + scope := scopeSpans.Scope() + scope.SetName("@opentelemetry/instrumentation-fetch") + scope.SetVersion("0.48.0") + spans := scopeSpans.Spans() + + span := spans.AppendEmpty() + span.SetName("HTTP GET") + span.SetKind(3) + span.SetStartTimestamp(pcommon.Timestamp(1718700770771000000)) + span.SetEndTimestamp(pcommon.Timestamp(1718700770800000000)) + spanID, err := generateSpanIDFromString("f71b2cc42962650f") + require.NoError(t, err) + span.SetSpanID(spanID) + traceID, err := generateTraceIDFromString("bac44bf5d6d040fc5fdf9bc22442c6f2") + require.NoError(t, err) + span.SetTraceID(traceID) + + return scopeSpans +} + +var generateSpanIDFromString = func(s string) ([8]byte, error) { + var spanID [8]byte + _, err := hex.Decode(spanID[:], []byte(s)) + if err != nil { + return spanID, err + } + return spanID, nil +} + +var generateTraceIDFromString = func(s string) ([16]byte, error) { + var traceID [16]byte + _, err := hex.Decode(traceID[:], []byte(s)) + if err != nil { + return traceID, err + } + return traceID, nil +} + +func TestTranslateTracesToFaroPayload(t *testing.T) { + testcases := []struct { + name string + td ptrace.Traces + wantPayloads []*faroTypes.Payload + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Empty traces", + td: ptrace.NewTraces(), + wantPayloads: func() []*faroTypes.Payload { + return nil + }(), + wantErr: assert.NoError, + }, + { + name: "Empty scope spans and empty resource attribute", + td: emptyScopeSpansAndEmptyResourceAttributes(), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Two resource spans with different resource attributes should produce two faro payloads", + td: twoResourceSpansWithDifferentServiceNameResourceAttribute(t), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-traces-meta-app-name-1.json")) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-traces-meta-app-name-2.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + { + name: "Two resource spans with the same resource attributes should produce one faro payload", + td: twoResourceSpansWithTheSameResource(t), + wantPayloads: func() []*faroTypes.Payload { + payloads := make([]*faroTypes.Payload, 0) + payloads = append(payloads, internal.PayloadFromFile(t, "payload-traces-two-traces-same-resource.json")) + return payloads + }(), + wantErr: assert.NoError, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + payloads, err := TranslateTracesToFaroPayload(context.TODO(), tt.td) + tt.wantErr(t, err) + assert.ElementsMatch(t, tt.wantPayloads, payloads) + }) + } +} + +func Test_extractMetaFromResourceAttributes(t *testing.T) { + testcases := []struct { + name string + resourceAttributes pcommon.Map + wantMeta faroTypes.Meta + }{ + { + name: "Resource attributes contain all the attributes for meta", + resourceAttributes: func() pcommon.Map { + attrs := pcommon.NewMap() + attrs.PutStr(string(semconv.ServiceNameKey), "testapp") + attrs.PutStr(string(semconv.ServiceNamespaceKey), "testnamespace") + attrs.PutStr(string(semconv.ServiceVersionKey), "1.0.0") + attrs.PutStr(string(semconv.DeploymentEnvironmentKey), "production") + attrs.PutStr("app_bundle_id", "123") + + return attrs + }(), + wantMeta: faroTypes.Meta{ + App: faroTypes.App{ + Name: "testapp", + Namespace: "testnamespace", + Version: "1.0.0", + Environment: "production", + BundleID: "123", + }, + }, + }, + { + name: "Resource attributes don't attributes for meta", + resourceAttributes: pcommon.NewMap(), + wantMeta: faroTypes.Meta{}, + }, + } + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.wantMeta, extractMetaFromResourceAttributes(tt.resourceAttributes), "extractMetaFromResourceAttributes(%v)", tt.resourceAttributes.AsRaw()) + }) + } +} From a37f84e0bb2ca78a3c06acc43fe15df2cbcac758 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Wed, 11 Dec 2024 14:07:17 +0000 Subject: [PATCH 3/8] faro translator: add more tests --- pkg/translator/faro/logs_to_faro.go | 14 +- pkg/translator/faro/logs_to_faro_test.go | 309 +++++++++++++++++- ...ayload-multiple-records-same-resource.json | 2 +- 3 files changed, 312 insertions(+), 13 deletions(-) diff --git a/pkg/translator/faro/logs_to_faro.go b/pkg/translator/faro/logs_to_faro.go index 5fc25b9..a3159ab 100644 --- a/pkg/translator/faro/logs_to_faro.go +++ b/pkg/translator/faro/logs_to_faro.go @@ -294,17 +294,17 @@ func extractSDKFromKeyVal(kv map[string]string) (*faroTypes.SDK, error) { sdk.Version = version } if integrationsStr, ok := kv["sdk_integrations"]; ok { - integrations, err := parseIntegrationsFromString(integrationsStr) - if err != nil { - return nil, err - } - sdk.Integrations = integrations + sdk.Integrations = parseIntegrationsFromString(integrationsStr) } return &sdk, nil } -func parseIntegrationsFromString(integrationsString string) ([]faroTypes.SDKIntegration, error) { +func parseIntegrationsFromString(integrationsString string) []faroTypes.SDKIntegration { sdkIntegrations := make([]faroTypes.SDKIntegration, 0) + if len(integrationsString) == 0 { + return sdkIntegrations + } + for _, integrationString := range strings.Split(integrationsString, ",") { integrationNameVersion := strings.Split(integrationString, ":") sdkIntegrations = append(sdkIntegrations, faroTypes.SDKIntegration{ @@ -313,7 +313,7 @@ func parseIntegrationsFromString(integrationsString string) ([]faroTypes.SDKInte }) } - return sdkIntegrations, nil + return sdkIntegrations } func extractAppFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes.App, error) { diff --git a/pkg/translator/faro/logs_to_faro_test.go b/pkg/translator/faro/logs_to_faro_test.go index ad58fa9..478412d 100644 --- a/pkg/translator/faro/logs_to_faro_test.go +++ b/pkg/translator/faro/logs_to_faro_test.go @@ -4,11 +4,13 @@ import ( "context" "fmt" "testing" + "time" faroTypes "github.com/grafana/faro/pkg/go" "github.com/grafana/faro/pkg/translator/faro/internal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/plog" semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) @@ -80,11 +82,11 @@ var multipleLogRecordsWithTheSameResource = func() plog.Logs { resAttrs.PutStr("app_bundle_id", "testBundleId") lrs := r.ScopeLogs().AppendEmpty().LogRecords() - lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") - lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"loading price list\" level=trace context_component=AppRoot context_page=Pricing traceID=abcd spanID=ghj sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") - lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=exception type=Error value=\"Cannot read property 'find' of undefined\" stacktrace=\"Error: Cannot read property 'find' of undefined\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8639:42)\\n at dispatchAction (http://fe:3002/static/js/vendors~main.chunk.js:268095:9)\\n at scheduleUpdateOnFiber (http://fe:3002/static/js/vendors~main.chunk.js:273726:13)\\n at flushSyncCallbackQueue (http://fe:3002/static/js/vendors~main.chunk.js:263362:7)\\n at flushSyncCallbackQueueImpl (http://fe:3002/static/js/vendors~main.chunk.js:263374:13)\\n at runWithPriority$1 (http://fe:3002/static/js/vendors~main.chunk.js:263325:14)\\n at unstable_runWithPriority (http://fe:3002/static/js/vendors~main.chunk.js:291265:16)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:263379:30)\\n at performSyncWorkOnRoot (http://fe:3002/static/js/vendors~main.chunk.js:274126:22)\\n at renderRootSync (http://fe:3002/static/js/vendors~main.chunk.js:274509:11)\\n at workLoopSync (http://fe:3002/static/js/vendors~main.chunk.js:274543:9)\\n at performUnitOfWork (http://fe:3002/static/js/vendors~main.chunk.js:274606:16)\\n at beginWork$1 (http://fe:3002/static/js/vendors~main.chunk.js:275746:18)\\n at beginWork (http://fe:3002/static/js/vendors~main.chunk.js:270944:20)\\n at updateFunctionComponent (http://fe:3002/static/js/vendors~main.chunk.js:269291:24)\\n at renderWithHooks (http://fe:3002/static/js/vendors~main.chunk.js:266969:22)\\n at ? (http://fe:3002/static/js/main.chunk.js:2600:74)\\n at useGetBooksQuery (http://fe:3002/static/js/main.chunk.js:1299:65)\\n at Module.useQuery (http://fe:3002/static/js/vendors~main.chunk.js:8495:85)\\n at useBaseQuery (http://fe:3002/static/js/vendors~main.chunk.js:8656:83)\\n at useDeepMemo (http://fe:3002/static/js/vendors~main.chunk.js:8696:14)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8657:55)\\n at QueryData.execute (http://fe:3002/static/js/vendors~main.chunk.js:7883:47)\\n at QueryData.getExecuteResult (http://fe:3002/static/js/vendors~main.chunk.js:7944:23)\\n at QueryData._this.getQueryResult (http://fe:3002/static/js/vendors~main.chunk.js:7790:19)\\n at new ApolloError (http://fe:3002/static/js/vendors~main.chunk.js:5164:24)\" traceID=abcd spanID=def context_ReactError=\"Annoying Error\" context_component=ReactErrorBoundary sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") - lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=measurement type=\"page load\" context_hello=world ttfb=14.000000 ttfcp=22.120000 ttfp=20.120000 traceID=abcd spanID=def value_ttfb=14 value_ttfcp=22.12 value_ttfp=20.12 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") - lrs.AppendEmpty().Body().SetStr("timestamp=2023-11-16T10:00:55.995Z kind=event event_name=faro.performanceEntry event_domain=browser event_data_connectEnd=3656 event_data_connectStart=337 event_data_decodedBodySize=0 event_data_domainLookupEnd=590 event_data_domainLookupStart=588 event_data_duration=3371 event_data_encodedBodySize=0 event_data_entryType=resource event_data_fetchStart=331 event_data_initiatorType=other event_data_name=https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css.map event_data_nextHopProtocol=h2 event_data_redirectEnd=0 event_data_redirectStart=0 event_data_requestStart=3656 event_data_responseEnd=3702 event_data_responseStart=3690 event_data_secureConnectionStart=3638 event_data_serverTiming=[] event_data_startTime=331 event_data_transferSize=0 event_data_workerStart=0 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=domasx2 user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"loading price list\" level=trace context_component=AppRoot context_page=Pricing traceID=abcd spanID=ghj sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=exception type=Error value=\"Cannot read property 'find' of undefined\" stacktrace=\"Error: Cannot read property 'find' of undefined\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8639:42)\\n at dispatchAction (http://fe:3002/static/js/vendors~main.chunk.js:268095:9)\\n at scheduleUpdateOnFiber (http://fe:3002/static/js/vendors~main.chunk.js:273726:13)\\n at flushSyncCallbackQueue (http://fe:3002/static/js/vendors~main.chunk.js:263362:7)\\n at flushSyncCallbackQueueImpl (http://fe:3002/static/js/vendors~main.chunk.js:263374:13)\\n at runWithPriority$1 (http://fe:3002/static/js/vendors~main.chunk.js:263325:14)\\n at unstable_runWithPriority (http://fe:3002/static/js/vendors~main.chunk.js:291265:16)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:263379:30)\\n at performSyncWorkOnRoot (http://fe:3002/static/js/vendors~main.chunk.js:274126:22)\\n at renderRootSync (http://fe:3002/static/js/vendors~main.chunk.js:274509:11)\\n at workLoopSync (http://fe:3002/static/js/vendors~main.chunk.js:274543:9)\\n at performUnitOfWork (http://fe:3002/static/js/vendors~main.chunk.js:274606:16)\\n at beginWork$1 (http://fe:3002/static/js/vendors~main.chunk.js:275746:18)\\n at beginWork (http://fe:3002/static/js/vendors~main.chunk.js:270944:20)\\n at updateFunctionComponent (http://fe:3002/static/js/vendors~main.chunk.js:269291:24)\\n at renderWithHooks (http://fe:3002/static/js/vendors~main.chunk.js:266969:22)\\n at ? (http://fe:3002/static/js/main.chunk.js:2600:74)\\n at useGetBooksQuery (http://fe:3002/static/js/main.chunk.js:1299:65)\\n at Module.useQuery (http://fe:3002/static/js/vendors~main.chunk.js:8495:85)\\n at useBaseQuery (http://fe:3002/static/js/vendors~main.chunk.js:8656:83)\\n at useDeepMemo (http://fe:3002/static/js/vendors~main.chunk.js:8696:14)\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8657:55)\\n at QueryData.execute (http://fe:3002/static/js/vendors~main.chunk.js:7883:47)\\n at QueryData.getExecuteResult (http://fe:3002/static/js/vendors~main.chunk.js:7944:23)\\n at QueryData._this.getQueryResult (http://fe:3002/static/js/vendors~main.chunk.js:7790:19)\\n at new ApolloError (http://fe:3002/static/js/vendors~main.chunk.js:5164:24)\" traceID=abcd spanID=def context_ReactError=\"Annoying Error\" context_component=ReactErrorBoundary sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=measurement type=\"page load\" context_hello=world ttfb=14.000000 ttfcp=22.120000 ttfp=20.120000 traceID=abcd spanID=def value_ttfb=14 value_ttfcp=22.12 value_ttfp=20.12 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + lrs.AppendEmpty().Body().SetStr("timestamp=2023-11-16T10:00:55.995Z kind=event event_name=faro.performanceEntry event_domain=browser event_data_connectEnd=3656 event_data_connectStart=337 event_data_decodedBodySize=0 event_data_domainLookupEnd=590 event_data_domainLookupStart=588 event_data_duration=3371 event_data_encodedBodySize=0 event_data_entryType=resource event_data_fetchStart=331 event_data_initiatorType=other event_data_name=https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css.map event_data_nextHopProtocol=h2 event_data_redirectEnd=0 event_data_redirectStart=0 event_data_requestStart=3656 event_data_responseEnd=3702 event_data_responseStart=3690 event_data_secureConnectionStart=3638 event_data_serverTiming=[] event_data_startTime=331 event_data_transferSize=0 event_data_workerStart=0 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") return ld } @@ -333,3 +335,300 @@ func Test_parseFrameFromString(t *testing.T) { }) } } + +func Test_translateLogToFaroPayload(t *testing.T) { + testcases := []struct { + name string + lr plog.LogRecord + rl pcommon.Resource + wantPayload *faroTypes.Payload + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Malformed log record body", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("foo bar") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: nil, + wantErr: assert.Error, + }, + { + name: "Log record doesn't have body", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + return record + }(), + rl: pcommon.NewResource(), + wantPayload: nil, + wantErr: assert.Error, + }, + { + name: "Log record body has kind=log only", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("kind=log") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Logs: []faroTypes.Log{ + {}, + }, + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=log and other fields", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=log message=\"opened pricing page\" level=info context_component=AppRoot context_page=Pricing traceID=abcd spanID=def sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Logs: []faroTypes.Log{ + { + Context: map[string]string{ + "component": "AppRoot", + "page": "Pricing", + }, + Timestamp: time.Date(2021, 9, 30, 10, 46, 17, 680000000, time.UTC), + Message: "opened pricing page", + LogLevel: faroTypes.LogLevelInfo, + Trace: faroTypes.TraceContext{ + TraceID: "abcd", + SpanID: "def", + }, + }, + }, + Meta: getTestMeta(), + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=event", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("kind=event") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Events: []faroTypes.Event{ + {}, + }, + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=event and other fields", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("timestamp=2023-11-16T10:00:55.995Z kind=event event_name=faro.performanceEntry event_domain=browser event_data_connectEnd=3656 event_data_connectStart=337 event_data_decodedBodySize=0 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Events: []faroTypes.Event{ + { + Name: "faro.performanceEntry", + Domain: "browser", + Timestamp: time.Date(2023, 11, 16, 10, 0, 55, 995000000, time.UTC), + Attributes: map[string]string{ + "connectEnd": "3656", + "connectStart": "337", + "decodedBodySize": "0", + }, + }, + }, + Meta: getTestMeta(), + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=measurement", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("kind=measurement") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Measurements: []faroTypes.Measurement{ + {}, + }, + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=measurement and other fields", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=measurement type=\"page load\" context_hello=world ttfb=14.000000 ttfcp=22.120000 ttfp=20.120000 traceID=abcd spanID=def value_ttfb=14 value_ttfcp=22.12 value_ttfp=20.12 sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Measurements: []faroTypes.Measurement{ + { + Timestamp: time.Date(2021, 9, 30, 10, 46, 17, 680000000, time.UTC), + Context: map[string]string{ + "hello": "world", + }, + Type: "page load", + Trace: faroTypes.TraceContext{ + TraceID: "abcd", + SpanID: "def", + }, + Values: map[string]float64{ + "ttfb": 14, + "ttfcp": 22.12, + "ttfp": 20.12, + }, + }, + }, + Meta: getTestMeta(), + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=exception", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("kind=exception") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Exceptions: []faroTypes.Exception{ + {}, + }, + }, + wantErr: assert.NoError, + }, + { + name: "Log record body has kind=exception and other fields", + lr: func() plog.LogRecord { + record := plog.NewLogRecord() + record.Body().SetStr("timestamp=2021-09-30T10:46:17.68Z kind=exception type=Error value=\"Cannot read property 'find' of undefined\" stacktrace=\"Error: Cannot read property 'find' of undefined\\n at ? (http://fe:3002/static/js/vendors~main.chunk.js:8639:42)\" traceID=abcd spanID=def context_ReactError=\"Annoying Error\" context_component=ReactErrorBoundary sdk_name=grafana-frontend-agent sdk_version=1.3.5 app_name=testapp app_namespace=testnamespace app_release=0.8.2 app_version=abcdefg app_environment=production user_email=geralt@kaermorhen.org user_id=123 user_username=testuser user_attr_foo=bar session_id=abcd session_attr_time_elapsed=100s page_url=https://example.com/page browser_name=chrome browser_version=88.12.1 browser_os=linux browser_mobile=false view_name=foobar") + return record + }(), + rl: pcommon.NewResource(), + wantPayload: &faroTypes.Payload{ + Exceptions: []faroTypes.Exception{ + { + Timestamp: time.Date(2021, 9, 30, 10, 46, 17, 680000000, time.UTC), + Context: map[string]string{ + "ReactError": "Annoying Error", + "component": "ReactErrorBoundary", + }, + Type: "Error", + Trace: faroTypes.TraceContext{ + TraceID: "abcd", + SpanID: "def", + }, + Value: "Cannot read property 'find' of undefined", + Stacktrace: &faroTypes.Stacktrace{ + Frames: []faroTypes.Frame{ + { + Colno: 42, + Lineno: 8639, + Filename: "http://fe:3002/static/js/vendors~main.chunk.js", + Function: "?", + }, + }, + }, + }, + }, + Meta: getTestMeta(), + }, + wantErr: assert.NoError, + }, + } + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + got, err := translateLogToFaroPayload(tt.lr, tt.rl) + if !tt.wantErr(t, err, fmt.Sprintf("translateLogToFaroPayload(%v, %v)", tt.lr, tt.rl)) { + return + } + assert.Equalf(t, tt.wantPayload, got, "translateLogToFaroPayload(%v, %v)", tt.lr, tt.rl) + }) + } +} +func Test_parseIntegrationsFromString(t *testing.T) { + tests := []struct { + name string + integrationsString string + want []faroTypes.SDKIntegration + }{ + { + name: "Integrations string is empty", + want: []faroTypes.SDKIntegration{}, + }, + { + name: "Integrations string contain several integrations", + integrationsString: "foo:1.2,example:3.4.5", + want: []faroTypes.SDKIntegration{ + { + Name: "foo", + Version: "1.2", + }, + { + Name: "example", + Version: "3.4.5", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := parseIntegrationsFromString(tt.integrationsString) + assert.Equalf(t, tt.want, got, "parseIntegrationsFromString(%v)", tt.integrationsString) + }) + } +} +func getTestMeta() faroTypes.Meta { + return faroTypes.Meta{ + App: faroTypes.App{ + Name: "testapp", + Namespace: "testnamespace", + Release: "0.8.2", + Version: "abcdefg", + Environment: "production", + }, + SDK: faroTypes.SDK{ + Name: "grafana-frontend-agent", + Version: "1.3.5", + }, + User: faroTypes.User{ + ID: "123", + Username: "testuser", + Attributes: map[string]string{ + "foo": "bar", + }, + Email: "geralt@kaermorhen.org", + }, + Browser: faroTypes.Browser{ + Name: "chrome", + Version: "88.12.1", + OS: "linux", + Mobile: false, + Brands: faroTypes.Browser_Brands{}, + }, + View: faroTypes.View{ + Name: "foobar", + }, + Session: faroTypes.Session{ + ID: "abcd", + Attributes: map[string]string{ + "time_elapsed": "100s", + }, + }, + Page: faroTypes.Page{ + URL: "https://example.com/page", + }, + } +} diff --git a/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json b/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json index 129f99f..67e4da4 100644 --- a/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json +++ b/pkg/translator/faro/testdata/payload-multiple-records-same-resource.json @@ -275,7 +275,7 @@ "bundleId": "testBundleId" }, "user": { - "username": "domasx2", + "username": "testuser", "id": "123", "email": "geralt@kaermorhen.org", "attributes": { From 0fffb537e3c2330a54199dc8184cbfe4fbbb53f1 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Wed, 11 Dec 2024 14:53:08 +0000 Subject: [PATCH 4/8] faro translator: get rid of unnesessary pointers --- pkg/translator/faro/logs_to_faro.go | 183 ++++++++++------------- pkg/translator/faro/logs_to_faro_test.go | 69 ++++++++- 2 files changed, 136 insertions(+), 116 deletions(-) diff --git a/pkg/translator/faro/logs_to_faro.go b/pkg/translator/faro/logs_to_faro.go index a3159ab..b4de732 100644 --- a/pkg/translator/faro/logs_to_faro.go +++ b/pkg/translator/faro/logs_to_faro.go @@ -157,9 +157,9 @@ func convertLogKeyValToPayload(kv map[string]string, rl pcommon.Resource) (*faro return nil, err } - payload.Meta = *meta + payload.Meta = meta payload.Logs = []faroTypes.Log{ - *log, + log, } return &payload, nil @@ -178,9 +178,9 @@ func convertEventKeyValsToPayload(kv map[string]string, rl pcommon.Resource) (*f return nil, err } - payload.Meta = *meta + payload.Meta = meta payload.Events = []faroTypes.Event{ - *event, + event, } return &payload, nil @@ -196,9 +196,9 @@ func convertExceptionKeyValsToPayload(kv map[string]string, rl pcommon.Resource) if err != nil { return nil, err } - payload.Meta = *meta + payload.Meta = meta payload.Exceptions = []faroTypes.Exception{ - *exception, + exception, } return &payload, nil @@ -214,62 +214,41 @@ func convertMeasurementKeyValsToPayload(kv map[string]string, rl pcommon.Resourc if err != nil { return nil, err } - payload.Meta = *meta + payload.Meta = meta payload.Measurements = []faroTypes.Measurement{ - *measurement, + measurement, } return &payload, nil } -func extractMetaFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes.Meta, error) { +func extractMetaFromKeyVal(kv map[string]string, rl pcommon.Resource) (faroTypes.Meta, error) { var meta faroTypes.Meta - app, err := extractAppFromKeyVal(kv, rl) - if err != nil { - return nil, err - } + app := extractAppFromKeyVal(kv, rl) browser, err := extractBrowserFromKeyVal(kv) if err != nil { - return nil, err - } - geo, err := extractGeoFromKeyVal(kv) - if err != nil { - return nil, err + return meta, err } + geo := extractGeoFromKeyVal(kv) k6, err := extractK6FromKeyVal(kv) if err != nil { - return nil, err - } - page, err := extractPageFromKeyVal(kv) - if err != nil { - return nil, err - } - sdk, err := extractSDKFromKeyVal(kv) - if err != nil { - return nil, err - } - session, err := extractSessionFromKeyVal(kv) - if err != nil { - return nil, err - } - user, err := extractUserFromKeyVal(kv) - if err != nil { - return nil, err - } - view, err := extractViewFromKeyVal(kv) - if err != nil { - return nil, err + return meta, err } + page := extractPageFromKeyVal(kv) + sdk := extractSDKFromKeyVal(kv) + session := extractSessionFromKeyVal(kv) + user := extractUserFromKeyVal(kv) + view := extractViewFromKeyVal(kv) - meta.App = *app + meta.App = app meta.Browser = *browser - meta.Geo = *geo - meta.K6 = *k6 - meta.Page = *page - meta.SDK = *sdk - meta.Session = *session - meta.User = *user - meta.View = *view - return &meta, nil + meta.Geo = geo + meta.K6 = k6 + meta.Page = page + meta.SDK = sdk + meta.Session = session + meta.User = user + meta.View = view + return meta, nil } func extractTimestampFromKeyVal(kv map[string]string) (time.Time, error) { @@ -285,7 +264,7 @@ func extractTimestampFromKeyVal(kv map[string]string) (time.Time, error) { return timestamp, nil } -func extractSDKFromKeyVal(kv map[string]string) (*faroTypes.SDK, error) { +func extractSDKFromKeyVal(kv map[string]string) faroTypes.SDK { var sdk faroTypes.SDK if name, ok := kv["sdk_name"]; ok { sdk.Name = name @@ -296,7 +275,7 @@ func extractSDKFromKeyVal(kv map[string]string) (*faroTypes.SDK, error) { if integrationsStr, ok := kv["sdk_integrations"]; ok { sdk.Integrations = parseIntegrationsFromString(integrationsStr) } - return &sdk, nil + return sdk } func parseIntegrationsFromString(integrationsString string) []faroTypes.SDKIntegration { @@ -316,7 +295,7 @@ func parseIntegrationsFromString(integrationsString string) []faroTypes.SDKInteg return sdkIntegrations } -func extractAppFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes.App, error) { +func extractAppFromKeyVal(kv map[string]string, rl pcommon.Resource) faroTypes.App { var app faroTypes.App rl.Attributes().Range(func(key string, val pcommon.Value) bool { if key == string(semconv.ServiceNameKey) { @@ -372,7 +351,7 @@ func extractAppFromKeyVal(kv map[string]string, rl pcommon.Resource) (*faroTypes app.Environment = environment } } - return &app, nil + return app } func extractBrowserFromKeyVal(kv map[string]string) (*faroTypes.Browser, error) { @@ -410,17 +389,17 @@ func extractBrowserFromKeyVal(kv map[string]string) (*faroTypes.Browser, error) if err != nil { return nil, err } - browser.Brands = *browserBrands + browser.Brands = browserBrands return &browser, nil } -func extractBrowserBrandsFromKeyVal(kv map[string]string) (*faroTypes.Browser_Brands, error) { +func extractBrowserBrandsFromKeyVal(kv map[string]string) (faroTypes.Browser_Brands, error) { var brands faroTypes.Browser_Brands if brandsAsString, ok := kv["browser_brands"]; ok { if err := brands.FromBrandsString(brandsAsString); err != nil { - return nil, err + return brands, err } - return &brands, nil + return brands, nil } brandsMap := make(map[int64]faroTypes.Brand) @@ -429,7 +408,7 @@ func extractBrowserBrandsFromKeyVal(kv map[string]string) (*faroTypes.Browser_Br brandAsString := strings.Split(suffix, "_") idx, err := strconv.ParseInt(brandAsString[0], 10, 64) if err != nil { - return nil, err + return brands, err } brand, ok := brandsMap[idx] if !ok { @@ -452,13 +431,13 @@ func extractBrowserBrandsFromKeyVal(kv map[string]string) (*faroTypes.Browser_Br brandsAsArray[i] = brand } if err := brands.FromBrandsArray(brandsAsArray); err != nil { - return nil, err + return brands, err } } - return &brands, nil + return brands, nil } -func extractGeoFromKeyVal(kv map[string]string) (*faroTypes.Geo, error) { +func extractGeoFromKeyVal(kv map[string]string) faroTypes.Geo { var geo faroTypes.Geo if continentISOCode, ok := kv["geo_continent_iso"]; ok { geo.ContinentISOCode = continentISOCode @@ -479,22 +458,22 @@ func extractGeoFromKeyVal(kv map[string]string) (*faroTypes.Geo, error) { geo.Carrier = carrier } - return &geo, nil + return geo } -func extractK6FromKeyVal(kv map[string]string) (*faroTypes.K6, error) { +func extractK6FromKeyVal(kv map[string]string) (faroTypes.K6, error) { var k6 faroTypes.K6 if isK6BrowserStr, ok := kv["k6_isK6Browser"]; ok { isK6Browser, err := strconv.ParseBool(isK6BrowserStr) if err != nil { - return nil, err + return k6, err } k6.IsK6Browser = isK6Browser } - return &k6, nil + return k6, nil } -func extractPageFromKeyVal(kv map[string]string) (*faroTypes.Page, error) { +func extractPageFromKeyVal(kv map[string]string) faroTypes.Page { var page faroTypes.Page if id, ok := kv["page_id"]; ok { page.ID = id @@ -503,19 +482,19 @@ func extractPageFromKeyVal(kv map[string]string) (*faroTypes.Page, error) { page.URL = url } page.Attributes = extractAttributesWithPrefixFromKeyVal("page_attr_", kv) - return &page, nil + return page } -func extractSessionFromKeyVal(kv map[string]string) (*faroTypes.Session, error) { +func extractSessionFromKeyVal(kv map[string]string) faroTypes.Session { var session faroTypes.Session if id, ok := kv["session_id"]; ok { session.ID = id } session.Attributes = extractAttributesWithPrefixFromKeyVal("session_attr_", kv) - return &session, nil + return session } -func extractUserFromKeyVal(kv map[string]string) (*faroTypes.User, error) { +func extractUserFromKeyVal(kv map[string]string) faroTypes.User { var user faroTypes.User if email, ok := kv["user_email"]; ok { user.Email = email @@ -528,22 +507,22 @@ func extractUserFromKeyVal(kv map[string]string) (*faroTypes.User, error) { } user.Attributes = extractAttributesWithPrefixFromKeyVal("user_attr_", kv) - return &user, nil + return user } -func extractViewFromKeyVal(kv map[string]string) (*faroTypes.View, error) { +func extractViewFromKeyVal(kv map[string]string) faroTypes.View { var view faroTypes.View if name, ok := kv["view_name"]; ok { view.Name = name } - return &view, nil + return view } -func extractLogFromKeyVal(kv map[string]string) (*faroTypes.Log, error) { +func extractLogFromKeyVal(kv map[string]string) (faroTypes.Log, error) { var log faroTypes.Log timestamp, err := extractTimestampFromKeyVal(kv) if err != nil { - return nil, err + return log, err } log.Timestamp = timestamp @@ -570,12 +549,9 @@ func extractLogFromKeyVal(kv map[string]string) (*faroTypes.Log, error) { if len(logContext) > 0 { log.Context = logContext } - trace, err := extractTraceFromKeyVal(kv) - if err != nil { - return nil, err - } - log.Trace = *trace - return &log, nil + trace := extractTraceFromKeyVal(kv) + log.Trace = trace + return log, nil } func extractLogContextFromKeyVal(kv map[string]string) faroTypes.LogContext { @@ -589,7 +565,7 @@ func extractLogContextFromKeyVal(kv map[string]string) faroTypes.LogContext { return logContext } -func extractTraceFromKeyVal(kv map[string]string) (*faroTypes.TraceContext, error) { +func extractTraceFromKeyVal(kv map[string]string) faroTypes.TraceContext { var trace faroTypes.TraceContext if traceID, ok := kv["traceID"]; ok { trace.TraceID = traceID @@ -597,10 +573,10 @@ func extractTraceFromKeyVal(kv map[string]string) (*faroTypes.TraceContext, erro if spanID, ok := kv["spanID"]; ok { trace.SpanID = spanID } - return &trace, nil + return trace } -func extractEventFromKeyVal(kv map[string]string) (*faroTypes.Event, error) { +func extractEventFromKeyVal(kv map[string]string) (faroTypes.Event, error) { var event faroTypes.Event if domain, ok := kv["event_domain"]; ok { event.Domain = domain @@ -610,19 +586,16 @@ func extractEventFromKeyVal(kv map[string]string) (*faroTypes.Event, error) { } timestamp, err := extractTimestampFromKeyVal(kv) if err != nil { - return nil, err + return event, err } event.Timestamp = timestamp - trace, err := extractTraceFromKeyVal(kv) - if err != nil { - return nil, err - } - event.Trace = *trace + trace := extractTraceFromKeyVal(kv) + event.Trace = trace event.Attributes = extractAttributesWithPrefixFromKeyVal("event_data_", kv) - return &event, nil + return event, nil } -func extractExceptionFromKeyVal(kv map[string]string) (*faroTypes.Exception, error) { +func extractExceptionFromKeyVal(kv map[string]string) (faroTypes.Exception, error) { var exception faroTypes.Exception if exceptionType, ok := kv["type"]; ok { exception.Type = exceptionType @@ -636,20 +609,17 @@ func extractExceptionFromKeyVal(kv map[string]string) (*faroTypes.Exception, err } stacktrace, err := extractStacktraceFromKeyVal(kv, exception.Type, exception.Value) if err != nil { - return nil, err + return exception, err } exception.Stacktrace = stacktrace timestamp, err := extractTimestampFromKeyVal(kv) if err != nil { - return nil, err + return exception, err } exception.Timestamp = timestamp - trace, err := extractTraceFromKeyVal(kv) - if err != nil { - return nil, err - } - exception.Trace = *trace - return &exception, nil + trace := extractTraceFromKeyVal(kv) + exception.Trace = trace + return exception, nil } func extractExceptionContextFromKeyVal(kv map[string]string) faroTypes.ExceptionContext { @@ -726,7 +696,7 @@ func parseFrameFromString(frameStr string) (*faroTypes.Frame, error) { return &frame, nil } -func extractMeasurementFromKeyVal(kv map[string]string) (*faroTypes.Measurement, error) { +func extractMeasurementFromKeyVal(kv map[string]string) (faroTypes.Measurement, error) { var measurement faroTypes.Measurement if measurementType, ok := kv["type"]; ok { measurement.Type = measurementType @@ -737,20 +707,17 @@ func extractMeasurementFromKeyVal(kv map[string]string) (*faroTypes.Measurement, } timestamp, err := extractTimestampFromKeyVal(kv) if err != nil { - return nil, err + return measurement, err } measurement.Timestamp = timestamp - trace, err := extractTraceFromKeyVal(kv) - if err != nil { - return nil, err - } - measurement.Trace = *trace + trace := extractTraceFromKeyVal(kv) + measurement.Trace = trace measurementValues, err := extractMeasurementValuesFromKeyVal(kv) if err != nil { - return nil, err + return measurement, err } measurement.Values = measurementValues - return &measurement, nil + return measurement, nil } func extractMeasurementContextFromKeyVal(kv map[string]string) faroTypes.MeasurementContext { diff --git a/pkg/translator/faro/logs_to_faro_test.go b/pkg/translator/faro/logs_to_faro_test.go index 478412d..69760f3 100644 --- a/pkg/translator/faro/logs_to_faro_test.go +++ b/pkg/translator/faro/logs_to_faro_test.go @@ -178,12 +178,12 @@ func TestTranslateLogsToFaroPayload(t *testing.T) { } } -func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { +func Test_extractBrowserBrandsFromKeyVal(t *testing.T) { tests := []struct { name string kv map[string]string wantErr assert.ErrorAssertionFunc - wantBrands *faroTypes.Browser_Brands + wantBrands faroTypes.Browser_Brands }{ { name: "brands as string", @@ -191,11 +191,11 @@ func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { "browser_brands": "Chromium;Google Inc.;", }, wantErr: assert.NoError, - wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + wantBrands: func(t *testing.T) faroTypes.Browser_Brands { var brands faroTypes.Browser_Brands err := brands.FromBrandsString("Chromium;Google Inc.;") require.NoError(t, err) - return &brands + return brands }(t), }, { @@ -207,7 +207,7 @@ func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { "browser_brand_1_version": "0.2.0", }, wantErr: assert.NoError, - wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + wantBrands: func(t *testing.T) faroTypes.Browser_Brands { var brands faroTypes.Browser_Brands err := brands.FromBrandsArray(faroTypes.BrandsArray{ { @@ -220,16 +220,16 @@ func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { }, }) require.NoError(t, err) - return &brands + return brands }(t), }, { name: "brands are missing", kv: map[string]string{}, wantErr: assert.NoError, - wantBrands: func(t *testing.T) *faroTypes.Browser_Brands { + wantBrands: func(t *testing.T) faroTypes.Browser_Brands { var brands faroTypes.Browser_Brands - return &brands + return brands }(t), }, } @@ -242,6 +242,59 @@ func Test_extractBrowserBrandsFromKeyVal1(t *testing.T) { } } +func Test_extractK6FromKeyVal(t *testing.T) { + testcases := []struct { + name string + kv map[string]string + want faroTypes.K6 + wantErr assert.ErrorAssertionFunc + }{ + { + name: "k6_isK6Browser is missing in kv", + kv: map[string]string{}, + want: faroTypes.K6{}, + wantErr: assert.NoError, + }, + { + name: "k6_isK6Browser can't be parsed as boolean", + kv: map[string]string{ + "k6_isK6Browser": "foo", + }, + want: faroTypes.K6{}, + wantErr: assert.Error, + }, + { + name: "k6_isK6Browser can be parsed as true", + kv: map[string]string{ + "k6_isK6Browser": "true", + }, + want: faroTypes.K6{ + IsK6Browser: true, + }, + wantErr: assert.NoError, + }, + { + name: "k6_isK6Browser can be parsed as false", + kv: map[string]string{ + "k6_isK6Browser": "0", + }, + want: faroTypes.K6{ + IsK6Browser: false, + }, + wantErr: assert.NoError, + }, + } + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + got, err := extractK6FromKeyVal(tt.kv) + if !tt.wantErr(t, err, fmt.Sprintf("extractK6FromKeyVal(%v)", tt.kv)) { + return + } + assert.Equalf(t, tt.want, got, "extractK6FromKeyVal(%v)", tt.kv) + }) + } +} + func Test_parseFrameFromString(t *testing.T) { testcases := []struct { name string From d4adc8b3d6dd21b70ff45cbc9038f622854ea35f Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Wed, 11 Dec 2024 14:55:29 +0000 Subject: [PATCH 5/8] faro translator: remove payload-empty.json --- pkg/translator/faro/testdata/payload-empty.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 pkg/translator/faro/testdata/payload-empty.json diff --git a/pkg/translator/faro/testdata/payload-empty.json b/pkg/translator/faro/testdata/payload-empty.json deleted file mode 100644 index 0967ef4..0000000 --- a/pkg/translator/faro/testdata/payload-empty.json +++ /dev/null @@ -1 +0,0 @@ -{} From dc6389144c2f2a85e8a1cfce2ed58e6c109a2b86 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Thu, 12 Dec 2024 10:18:29 +0000 Subject: [PATCH 6/8] faro-translator: update dependencies, remove replace statements --- pkg/exporter/faro/go.mod | 44 ++++++------- pkg/exporter/faro/go.sum | 124 ++++++++++++++++++++----------------- pkg/go/go.mod | 14 ++--- pkg/go/go.sum | 34 +++++----- pkg/translator/faro/go.mod | 20 +++--- pkg/translator/faro/go.sum | 36 ++++++----- 6 files changed, 142 insertions(+), 130 deletions(-) diff --git a/pkg/exporter/faro/go.mod b/pkg/exporter/faro/go.mod index b8f4eee..4d695c4 100644 --- a/pkg/exporter/faro/go.mod +++ b/pkg/exporter/faro/go.mod @@ -3,12 +3,12 @@ module github.com/grafana/faro/pkg/exporter/faro go 1.23.3 require ( - github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d - github.com/grafana/faro/pkg/translator/faro v0.0.0-00010101000000-000000000000 - go.opentelemetry.io/collector/component v0.114.0 - go.opentelemetry.io/collector/consumer v0.114.0 - go.opentelemetry.io/collector/exporter v0.114.0 - go.opentelemetry.io/collector/pdata v1.20.0 + github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d + github.com/grafana/faro/pkg/translator/faro v0.0.0-20241209115835-ae0605ce4d8d + go.opentelemetry.io/collector/component v0.115.0 + go.opentelemetry.io/collector/consumer v1.21.0 + go.opentelemetry.io/collector/exporter v0.115.0 + go.opentelemetry.io/collector/pdata v1.21.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 ) @@ -21,30 +21,30 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/oapi-codegen/runtime v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/testify v1.9.0 // indirect - go.opentelemetry.io/collector/config/configretry v1.20.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.114.0 // indirect - go.opentelemetry.io/collector/consumer/consumererror v0.114.0 // indirect - go.opentelemetry.io/collector/extension v0.114.0 // indirect - go.opentelemetry.io/collector/extension/experimental/storage v0.114.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.114.0 // indirect - go.opentelemetry.io/collector/pipeline v0.114.0 // indirect + github.com/stretchr/testify v1.10.0 // indirect + go.opentelemetry.io/collector/config/configretry v1.21.0 // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.115.0 // indirect + go.opentelemetry.io/collector/consumer/consumererror v0.115.0 // indirect + go.opentelemetry.io/collector/extension v0.115.0 // indirect + go.opentelemetry.io/collector/extension/experimental/storage v0.115.0 // indirect + go.opentelemetry.io/collector/featuregate v1.21.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.115.0 // indirect + go.opentelemetry.io/collector/pipeline v0.115.0 // indirect go.opentelemetry.io/otel v1.32.0 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect go.opentelemetry.io/otel/sdk v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/grpc v1.68.1 // indirect + google.golang.org/protobuf v1.35.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -replace github.com/grafana/faro/pkg/translator/faro => ../../translator/faro diff --git a/pkg/exporter/faro/go.sum b/pkg/exporter/faro/go.sum index a33fe77..0025b9f 100644 --- a/pkg/exporter/faro/go.sum +++ b/pkg/exporter/faro/go.sum @@ -14,13 +14,19 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d h1:6CXkEkw8iawiV1ncovud34IkkacCw7hp+YYd9kq3T94= -github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d/go.mod h1:fJa5cS+fHDPKao/KaCRgIGplg2/2UXSP8k+evjqBcqY= +github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d h1:mvEP8F2YujhIpQtpNLPuIUyJ38o9vmmpmd6bzC+mTTw= +github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d/go.mod h1:fJa5cS+fHDPKao/KaCRgIGplg2/2UXSP8k+evjqBcqY= +github.com/grafana/faro/pkg/translator/faro v0.0.0-20241209115835-ae0605ce4d8d h1:1qKXlr2HsOu8422pHfDMr4vfI0k/PD7Q1VTwDXDCv5k= +github.com/grafana/faro/pkg/translator/faro v0.0.0-20241209115835-ae0605ce4d8d/go.mod h1:eRQBWoajXDf/pJLH01JR3Cl4Nn3YFODqjWmhc8QcjzM= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= @@ -44,52 +50,54 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/collector/component v0.114.0 h1:SVGbm5LvHGSTEDv7p92oPuBgK5tuiWR82I9+LL4TtBE= -go.opentelemetry.io/collector/component v0.114.0/go.mod h1:MLxtjZ6UVHjDxSdhGLuJfHBHvfl1iT/Y7IaQPD24Eww= -go.opentelemetry.io/collector/component/componenttest v0.114.0 h1:GM4FTTlfeXoVm6sZYBHImwlRN8ayh2oAfUhvaFj7Zo8= -go.opentelemetry.io/collector/component/componenttest v0.114.0/go.mod h1:ZZEJMtbJtoVC/3/9R1HzERq+cYQRxuMFQrPCpfZ4Xos= -go.opentelemetry.io/collector/config/configretry v1.20.0 h1:z679mrMlW2a6tOOYPGdrS/QfALxdzWLQUOpH8Uu+D5Y= -go.opentelemetry.io/collector/config/configretry v1.20.0/go.mod h1:KvQF5cfphq1rQm1dKR4eLDNQYw6iI2fY72NMZVa+0N0= -go.opentelemetry.io/collector/config/configtelemetry v0.114.0 h1:kjLeyrumge6wsX6ZIkicdNOlBXaEyW2PI2ZdVXz/rzY= -go.opentelemetry.io/collector/config/configtelemetry v0.114.0/go.mod h1:R0MBUxjSMVMIhljuDHWIygzzJWQyZHXXWIgQNxcFwhc= -go.opentelemetry.io/collector/consumer v0.114.0 h1:1zVaHvfIZowGwZRitRBRo3i+RP2StlU+GClYiofSw0Q= -go.opentelemetry.io/collector/consumer v0.114.0/go.mod h1:d+Mrzt9hsH1ub3zmwSlnQVPLeTYir4Mgo7CrWfnncN4= -go.opentelemetry.io/collector/consumer/consumererror v0.114.0 h1:r2YiELfWerb40FHD23V04gNjIkLUcjEKGxI4Vtm2iO4= -go.opentelemetry.io/collector/consumer/consumererror v0.114.0/go.mod h1:MzIrLQ5jptO2egypolhlAbZsWZr29WC4FhSxQjnxcvg= -go.opentelemetry.io/collector/consumer/consumerprofiles v0.114.0 h1:5pXYy3E6UK5Huu3aQbsYL8B6E6MyWx4fvXXDn+oXZaA= -go.opentelemetry.io/collector/consumer/consumerprofiles v0.114.0/go.mod h1:PMq3f54KcJQO4v1tue0QxQScu7REFVADlXxXSAYMiN0= -go.opentelemetry.io/collector/consumer/consumertest v0.114.0 h1:isaTwJK5DOy8Bs7GuLq23ejfgj8gLIo5dOUvkRnLF4g= -go.opentelemetry.io/collector/consumer/consumertest v0.114.0/go.mod h1:GNeLPkfRPdh06n/Rv1UKa/cAtCKjN0a7ADyHjIj4HFE= -go.opentelemetry.io/collector/exporter v0.114.0 h1:5/0BBpXuCJQSQ5SQf31g7j6T4XEKkyx9mZMcA2rS5e8= -go.opentelemetry.io/collector/exporter v0.114.0/go.mod h1:atpd0wWXgh5LAZ0REU/d/Ti/q50HDfnlBIjMjJQlKFg= -go.opentelemetry.io/collector/exporter/exporterprofiles v0.114.0 h1:/wmWOSBHcvtz3Pbv7+rWCqPPQuNvYaoidKKaOqZsLKs= -go.opentelemetry.io/collector/exporter/exporterprofiles v0.114.0/go.mod h1:epRYTkyJZTSQZBJflMGHUyUo2EdLPhsaZEyo5Qm848A= -go.opentelemetry.io/collector/exporter/exportertest v0.114.0 h1:vo0idBJT+QACSM1KpjVLm9VeiXVwO7y4UnMpGxN6EyM= -go.opentelemetry.io/collector/exporter/exportertest v0.114.0/go.mod h1:420ssFrhaphneybstbMeSIiqSRoaBARPgO71O17foaM= -go.opentelemetry.io/collector/extension v0.114.0 h1:9Qb92y8hD2WDC5aMDoj4JNQN+/5BQYJWPUPzLXX+iGw= -go.opentelemetry.io/collector/extension v0.114.0/go.mod h1:Yk2/1ptVgfTr12t+22v93nYJpioP14pURv2YercSzU0= -go.opentelemetry.io/collector/extension/experimental/storage v0.114.0 h1:hLyX9UvmY0t6iBnk3CqvyNck2U0QjPACekj7pDRx2hA= -go.opentelemetry.io/collector/extension/experimental/storage v0.114.0/go.mod h1:WqYRQVJjJLE1rm+y/ks1wPdPRGWePEvE1VO07xm2J2k= -go.opentelemetry.io/collector/extension/extensiontest v0.114.0 h1:ibXDms1qrswlvlR6b3d2BeyI8sXUXoFV11yOi9Sop8o= -go.opentelemetry.io/collector/extension/extensiontest v0.114.0/go.mod h1:/bOYmqu5yTDfI1bJZUxFqm8ZtmcodpquebiSxiQxtDY= -go.opentelemetry.io/collector/pdata v1.20.0 h1:ePcwt4bdtISP0loHaE+C9xYoU2ZkIvWv89Fob16o9SM= -go.opentelemetry.io/collector/pdata v1.20.0/go.mod h1:Ox1YVLe87cZDB/TL30i4SUz1cA5s6AM6SpFMfY61ICs= -go.opentelemetry.io/collector/pdata/pprofile v0.114.0 h1:pUNfTzsI/JUTiE+DScDM4lsrPoxnVNLI2fbTxR/oapo= -go.opentelemetry.io/collector/pdata/pprofile v0.114.0/go.mod h1:4aNcj6WM1n1uXyFSXlhVs4ibrERgNYsTbzcYI2zGhxA= -go.opentelemetry.io/collector/pdata/testdata v0.114.0 h1:+AzszWSL1i4K6meQ8rU0JDDW55SYCXa6FVqfDixhhTo= -go.opentelemetry.io/collector/pdata/testdata v0.114.0/go.mod h1:bv8XFdCTZxG2MQB5l9dKxSxf5zBrcodwO6JOy1+AxXM= -go.opentelemetry.io/collector/pipeline v0.114.0 h1:v3YOhc5z0tD6QbO5n/pnftpIeroihM2ks9Z2yKPCcwY= -go.opentelemetry.io/collector/pipeline v0.114.0/go.mod h1:4vOvjVsoYTHVGTbfFwqfnQOSV2K3RKUHofh3jNRc2Mg= -go.opentelemetry.io/collector/receiver v0.114.0 h1:90SAnXAjNq7/k52/pFmmb06Cf1YauoPYtbio4aOXafY= -go.opentelemetry.io/collector/receiver v0.114.0/go.mod h1:KUGT0/D953LXbGH/D3lLPU8yrU3HfWnUqpt4W4hSOnE= -go.opentelemetry.io/collector/receiver/receiverprofiles v0.114.0 h1:ibhEfGpvNB3yrtpl2jYFabrunMk1hurxvMYpM0b1Ck4= -go.opentelemetry.io/collector/receiver/receiverprofiles v0.114.0/go.mod h1:UZyRfaasw+NLvN10AN8IQnmj5tQ3BOUH1uP2ctpO9f0= -go.opentelemetry.io/collector/receiver/receivertest v0.114.0 h1:D+Kh9t2n4asTnM+TiSxbrKlUemLZandWntj17BJWWb0= -go.opentelemetry.io/collector/receiver/receivertest v0.114.0/go.mod h1:mNSHQ13vFmqD+VAcRzLjStFBejbcWUn2Mp0pAd7Op+U= +go.opentelemetry.io/collector/component v0.115.0 h1:iLte1oCiXzjiCnaOBKdsXacfFiECecpWxW3/LeriMoo= +go.opentelemetry.io/collector/component v0.115.0/go.mod h1:oIUFiH7w1eOimdeYhFI+gAIxYSiLDocKVJ0PTvX7d6s= +go.opentelemetry.io/collector/component/componenttest v0.115.0 h1:9URDJ9VyP6tuij+YHjp/kSSMecnZOd7oGvzu+rw9SJY= +go.opentelemetry.io/collector/component/componenttest v0.115.0/go.mod h1:PzXvNqKLCiSADZGZFKH+IOHMkaQ0GTHuzysfVbTPKYY= +go.opentelemetry.io/collector/config/configretry v1.21.0 h1:ZHoOvAkEcv5BBeaJn8IQ6rQ4GMPZWW4S+W7R4QTEbZU= +go.opentelemetry.io/collector/config/configretry v1.21.0/go.mod h1:cleBc9I0DIWpTiiHfu9v83FUaCTqcPXmebpLxjEIqro= +go.opentelemetry.io/collector/config/configtelemetry v0.115.0 h1:U07FinCDop+r2RjWQ3aP9ZWONC7r7kQIp1GkXQi6nsI= +go.opentelemetry.io/collector/config/configtelemetry v0.115.0/go.mod h1:SlBEwQg0qly75rXZ6W1Ig8jN25KBVBkFIIAUI1GiAAE= +go.opentelemetry.io/collector/consumer v1.21.0 h1:THKZ2Vbi6GkamjTBI2hFq5Dc4kINZTWGwQNa8d/Ty9g= +go.opentelemetry.io/collector/consumer v1.21.0/go.mod h1:FQcC4ThMtRYY41dv+IPNK8POLLhAFY3r1YR5fuP7iiY= +go.opentelemetry.io/collector/consumer/consumererror v0.115.0 h1:yli//xBCQMPZKXNgNlXemo4dvqhnFrAmCZ11DvQgmcY= +go.opentelemetry.io/collector/consumer/consumererror v0.115.0/go.mod h1:LwVzAvQ6ZVNG7mbOvurbAo+W/rKws0IcjOwriuZXqPE= +go.opentelemetry.io/collector/consumer/consumerprofiles v0.115.0 h1:H3fDuyQW1t2HWHkz96WMBQJKUevypOCjBqnqtaAWyoA= +go.opentelemetry.io/collector/consumer/consumerprofiles v0.115.0/go.mod h1:IzEmZ91Tp7TBxVDq8Cc9xvLsmO7H08njr6Pu9P5d9ns= +go.opentelemetry.io/collector/consumer/consumertest v0.115.0 h1:hru0I2447y0TluCdwlKYFFtgcpyCnlM+LiOK1JZyA70= +go.opentelemetry.io/collector/consumer/consumertest v0.115.0/go.mod h1:ybjALRJWR6aKNOzEMy1T1ruCULVDEjj4omtOJMrH/kU= +go.opentelemetry.io/collector/exporter v0.115.0 h1:JnxfpOnsuqhTPKJXVKJLS1Cv3BiVrVLzpHOjJEQw+xw= +go.opentelemetry.io/collector/exporter v0.115.0/go.mod h1:xof3fHQK8wADhaKLIJcQ7ChZaFLNC+haRdPN0wgl6kY= +go.opentelemetry.io/collector/exporter/exporterprofiles v0.115.0 h1:lSQEleCn/q9eFufcuK61NdFKU70ZlgI9dBjPCO/4CrE= +go.opentelemetry.io/collector/exporter/exporterprofiles v0.115.0/go.mod h1:7l5K2AecimX2kx+nZC1gKG3QkP247CO1+SodmJ4fFkQ= +go.opentelemetry.io/collector/exporter/exportertest v0.115.0 h1:P9SMTUXQOtcaq40bGtnnAe14zRmR4/yUgj/Tb2BEf/k= +go.opentelemetry.io/collector/exporter/exportertest v0.115.0/go.mod h1:1jMZ9gFGXglb8wfNrBZIgd+RvpZhSyFwdfE+Jtf9w4U= +go.opentelemetry.io/collector/extension v0.115.0 h1:/cBb8AUdD0KMWC6V3lvCC16eP9Fg0wd1Upcp5rgvuGI= +go.opentelemetry.io/collector/extension v0.115.0/go.mod h1:HI7Ak6loyi6ZrZPsQJW1OO1wbaAW8OqXLFNQlTZnreQ= +go.opentelemetry.io/collector/extension/experimental/storage v0.115.0 h1:sZXw0+77092pq24CkUoTRoHQPLQUsDq6HFRNB0g5yR4= +go.opentelemetry.io/collector/extension/experimental/storage v0.115.0/go.mod h1:qjFH7Y3QYYs88By2ZB5GMSUN5k3ul4Brrq2J6lKACA0= +go.opentelemetry.io/collector/extension/extensiontest v0.115.0 h1:GBVFxFEskR8jSdu9uaQh2qpXnN5VNXhXjpJ2UjxtE8I= +go.opentelemetry.io/collector/extension/extensiontest v0.115.0/go.mod h1:eu1ecbz5mT+cHoH2H3GmD/rOO0WsicSJD2RLrYuOmRA= +go.opentelemetry.io/collector/featuregate v1.21.0 h1:+EULHPJDLMipcwAGZVp9Nm8NriRvoBBMxp7MSiIZVMI= +go.opentelemetry.io/collector/featuregate v1.21.0/go.mod h1:3GaXqflNDVwWndNGBJ1+XJFy3Fv/XrFgjMN60N3z7yg= +go.opentelemetry.io/collector/pdata v1.21.0 h1:PG+UbiFMJ35X/WcAR7Rf/PWmWtRdW0aHlOidsR6c5MA= +go.opentelemetry.io/collector/pdata v1.21.0/go.mod h1:GKb1/zocKJMvxKbS+sl0W85lxhYBTFJ6h6I1tphVyDU= +go.opentelemetry.io/collector/pdata/pprofile v0.115.0 h1:NI89hy13vNDw7EOnQf7Jtitks4HJFO0SUWznTssmP94= +go.opentelemetry.io/collector/pdata/pprofile v0.115.0/go.mod h1:jGzdNfO0XTtfLjXCL/uCC1livg1LlfR+ix2WE/z3RpQ= +go.opentelemetry.io/collector/pdata/testdata v0.115.0 h1:Rblz+AKXdo3fG626jS+KSd0OSA4uMXcTQfpwed6P8LI= +go.opentelemetry.io/collector/pdata/testdata v0.115.0/go.mod h1:inNnRt6S2Nn260EfCBEcjesjlKOSsr0jPwkPqpBkt4s= +go.opentelemetry.io/collector/pipeline v0.115.0 h1:bmACBqb0e8U9ag+vGGHUP7kCfAO7HHROdtzIEg8ulus= +go.opentelemetry.io/collector/pipeline v0.115.0/go.mod h1:qE3DmoB05AW0C3lmPvdxZqd/H4po84NPzd5MrqgtL74= +go.opentelemetry.io/collector/receiver v0.115.0 h1:55Q3Jvj6zHCIA1psKqi/3kEMJO4OqUF5tNAEYNdB1U8= +go.opentelemetry.io/collector/receiver v0.115.0/go.mod h1:nBSCh2O/WUcfgpJ+Jpz+B0z0Hn5jHeRvF2WmLij5EIY= +go.opentelemetry.io/collector/receiver/receiverprofiles v0.115.0 h1:R9JLaj2Al93smIPUkbJshAkb/cY0H5JBOxIx+Zu0NG4= +go.opentelemetry.io/collector/receiver/receiverprofiles v0.115.0/go.mod h1:05E5hGujWeeXJmzKZwTdHyZ/+rRyrQlQB5p5Q2XY39M= +go.opentelemetry.io/collector/receiver/receivertest v0.115.0 h1:OiB684SbHQi6/Pd3ZH0cXjYvCpBS9ilQBfTQx0wVXHg= +go.opentelemetry.io/collector/receiver/receivertest v0.115.0/go.mod h1:Y8Z9U/bz9Xpyt8GI8DxZZgryw3mnnIw+AeKVLTD2cP8= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= @@ -115,20 +123,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -137,12 +145,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/go/go.mod b/pkg/go/go.mod index 7567411..c0ced5d 100644 --- a/pkg/go/go.mod +++ b/pkg/go/go.mod @@ -4,7 +4,7 @@ go 1.22.3 require ( github.com/oapi-codegen/runtime v1.1.1 - go.opentelemetry.io/collector/pdata v1.16.0 + go.opentelemetry.io/collector/pdata v1.21.0 ) require ( @@ -15,10 +15,10 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - google.golang.org/grpc v1.66.2 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/grpc v1.68.1 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) diff --git a/pkg/go/go.sum b/pkg/go/go.sum index 8eac182..eedff5f 100644 --- a/pkg/go/go.sum +++ b/pkg/go/go.sum @@ -7,6 +7,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -29,12 +31,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/collector/pdata v1.16.0 h1:g02K8jlRnmQ7TQDuXpdgVL6vIxIVqr5Gbb1qIR27rto= -go.opentelemetry.io/collector/pdata v1.16.0/go.mod h1:YZZJIt2ehxosYf/Y1pbvexjNWsIGNNrzzlCTO9jC1F4= +go.opentelemetry.io/collector/pdata v1.21.0 h1:PG+UbiFMJ35X/WcAR7Rf/PWmWtRdW0aHlOidsR6c5MA= +go.opentelemetry.io/collector/pdata v1.21.0/go.mod h1:GKb1/zocKJMvxKbS+sl0W85lxhYBTFJ6h6I1tphVyDU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -48,20 +50,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -70,11 +72,11 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/translator/faro/go.mod b/pkg/translator/faro/go.mod index 242cd02..aba59c4 100644 --- a/pkg/translator/faro/go.mod +++ b/pkg/translator/faro/go.mod @@ -4,9 +4,9 @@ go 1.23.3 require ( github.com/go-logfmt/logfmt v0.6.0 - github.com/grafana/faro/pkg/go v0.0.0-20241118134905-713b31945e4d - github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/collector/pdata v1.20.0 + github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d + github.com/stretchr/testify v1.10.0 + go.opentelemetry.io/collector/pdata v1.21.0 go.opentelemetry.io/otel v1.32.0 ) @@ -26,13 +26,11 @@ require ( go.opentelemetry.io/otel/metric v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/grpc v1.68.1 // indirect + google.golang.org/protobuf v1.35.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -replace github.com/grafana/faro/pkg/go => ../../go diff --git a/pkg/translator/faro/go.sum b/pkg/translator/faro/go.sum index cef772e..552b6a3 100644 --- a/pkg/translator/faro/go.sum +++ b/pkg/translator/faro/go.sum @@ -15,11 +15,15 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d h1:mvEP8F2YujhIpQtpNLPuIUyJ38o9vmmpmd6bzC+mTTw= +github.com/grafana/faro/pkg/go v0.0.0-20241209115835-ae0605ce4d8d/go.mod h1:fJa5cS+fHDPKao/KaCRgIGplg2/2UXSP8k+evjqBcqY= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= @@ -43,12 +47,12 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/collector/pdata v1.20.0 h1:ePcwt4bdtISP0loHaE+C9xYoU2ZkIvWv89Fob16o9SM= -go.opentelemetry.io/collector/pdata v1.20.0/go.mod h1:Ox1YVLe87cZDB/TL30i4SUz1cA5s6AM6SpFMfY61ICs= +go.opentelemetry.io/collector/pdata v1.21.0 h1:PG+UbiFMJ35X/WcAR7Rf/PWmWtRdW0aHlOidsR6c5MA= +go.opentelemetry.io/collector/pdata v1.21.0/go.mod h1:GKb1/zocKJMvxKbS+sl0W85lxhYBTFJ6h6I1tphVyDU= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= @@ -68,20 +72,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -90,12 +94,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From afbc4e9dc7103b9825b833ddc2e4be8d3190b662 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Thu, 12 Dec 2024 10:58:27 +0000 Subject: [PATCH 7/8] faro-translator: fix typo --- pkg/translator/faro/traces_to_faro_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/translator/faro/traces_to_faro_test.go b/pkg/translator/faro/traces_to_faro_test.go index 07b8cfc..ecd9557 100644 --- a/pkg/translator/faro/traces_to_faro_test.go +++ b/pkg/translator/faro/traces_to_faro_test.go @@ -180,7 +180,7 @@ func Test_extractMetaFromResourceAttributes(t *testing.T) { }, }, { - name: "Resource attributes don't attributes for meta", + name: "Resource attributes don't contain attributes for meta", resourceAttributes: pcommon.NewMap(), wantMeta: faroTypes.Meta{}, }, From 59def8ddaf7090630eb7a732454d28dfb6e88176 Mon Sep 17 00:00:00 2001 From: Irina Marchuk Date: Mon, 16 Dec 2024 10:17:43 +0000 Subject: [PATCH 8/8] rename methods for translation from logs to faro payload --- pkg/translator/faro/logs_to_faro.go | 6 +++--- pkg/translator/faro/logs_to_faro_test.go | 4 ++-- pkg/translator/faro/traces_to_faro.go | 5 +++-- pkg/translator/faro/traces_to_faro_test.go | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pkg/translator/faro/logs_to_faro.go b/pkg/translator/faro/logs_to_faro.go index b4de732..72a2b84 100644 --- a/pkg/translator/faro/logs_to_faro.go +++ b/pkg/translator/faro/logs_to_faro.go @@ -20,9 +20,9 @@ import ( "go.opentelemetry.io/collector/pdata/plog" ) -// TranslateLogsToFaroPayloads converts a Logs pipeline data into []*faro.Payload -func TranslateLogsToFaroPayloads(ctx context.Context, ld plog.Logs) ([]*faroTypes.Payload, error) { - ctx, span := otel.Tracer("").Start(ctx, "TranslateLogsToFaroPayloads") +// TranslateFromLogs converts a Logs pipeline data into []*faro.Payload +func TranslateFromLogs(ctx context.Context, ld plog.Logs) ([]*faroTypes.Payload, error) { + ctx, span := otel.Tracer("").Start(ctx, "TranslateFromLogs") defer span.End() metaMap := make(map[string]*faroTypes.Payload, 0) diff --git a/pkg/translator/faro/logs_to_faro_test.go b/pkg/translator/faro/logs_to_faro_test.go index 69760f3..dceeb0e 100644 --- a/pkg/translator/faro/logs_to_faro_test.go +++ b/pkg/translator/faro/logs_to_faro_test.go @@ -91,7 +91,7 @@ var multipleLogRecordsWithTheSameResource = func() plog.Logs { return ld } -func TestTranslateLogsToFaroPayload(t *testing.T) { +func TestTranslateFromLogs(t *testing.T) { testcases := []struct { name string ld plog.Logs @@ -171,7 +171,7 @@ func TestTranslateLogsToFaroPayload(t *testing.T) { for _, tt := range testcases { t.Run(tt.name, func(t *testing.T) { - faroPayloads, err := TranslateLogsToFaroPayloads(context.TODO(), tt.ld) + faroPayloads, err := TranslateFromLogs(context.TODO(), tt.ld) tt.wantErr(t, err) assert.ElementsMatch(t, tt.wantPayloads, faroPayloads) }) diff --git a/pkg/translator/faro/traces_to_faro.go b/pkg/translator/faro/traces_to_faro.go index 42af39e..0789735 100644 --- a/pkg/translator/faro/traces_to_faro.go +++ b/pkg/translator/faro/traces_to_faro.go @@ -13,8 +13,9 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) -func TranslateTracesToFaroPayload(ctx context.Context, td ptrace.Traces) ([]*faroTypes.Payload, error) { - ctx, span := otel.Tracer("").Start(ctx, "TranslateTracesToFaroPayload") +// TranslateFromTraces converts a Traces pipeline data into []*faro.Payload +func TranslateFromTraces(ctx context.Context, td ptrace.Traces) ([]*faroTypes.Payload, error) { + ctx, span := otel.Tracer("").Start(ctx, "TranslateFromTraces") defer span.End() resourceSpans := td.ResourceSpans() diff --git a/pkg/translator/faro/traces_to_faro_test.go b/pkg/translator/faro/traces_to_faro_test.go index ecd9557..c4cc8de 100644 --- a/pkg/translator/faro/traces_to_faro_test.go +++ b/pkg/translator/faro/traces_to_faro_test.go @@ -95,7 +95,7 @@ var generateTraceIDFromString = func(s string) ([16]byte, error) { return traceID, nil } -func TestTranslateTracesToFaroPayload(t *testing.T) { +func TestTranslateFromTraces(t *testing.T) { testcases := []struct { name string td ptrace.Traces @@ -144,7 +144,7 @@ func TestTranslateTracesToFaroPayload(t *testing.T) { for _, tt := range testcases { t.Run(tt.name, func(t *testing.T) { - payloads, err := TranslateTracesToFaroPayload(context.TODO(), tt.td) + payloads, err := TranslateFromTraces(context.TODO(), tt.td) tt.wantErr(t, err) assert.ElementsMatch(t, tt.wantPayloads, payloads) })