diff --git a/.chloggen/33288-metadata.yaml b/.chloggen/33288-metadata.yaml new file mode 100644 index 0000000000000..813bf24b9153a --- /dev/null +++ b/.chloggen/33288-metadata.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/ottl + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Added metadata access path to all OTTL contexts for accessing client request metadata + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33288] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/connector/countconnector/go.mod b/connector/countconnector/go.mod index 47233223dcf9d..23cd8c52b76b4 100644 --- a/connector/countconnector/go.mod +++ b/connector/countconnector/go.mod @@ -82,6 +82,7 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/config/configtelemetry v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/confmap/provider/envprovider v1.52.1-0.20260227062254-168030d61d7d // indirect diff --git a/connector/signaltometricsconnector/go.mod b/connector/signaltometricsconnector/go.mod index 53488376ae71e..d1a8609968a18 100644 --- a/connector/signaltometricsconnector/go.mod +++ b/connector/signaltometricsconnector/go.mod @@ -63,6 +63,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/internal/componentalias v0.146.2-0.20260227062254-168030d61d7d // indirect @@ -79,6 +80,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/connector/signaltometricsconnector/go.sum b/connector/signaltometricsconnector/go.sum index 10f2abafbcd19..9267e64097301 100644 --- a/connector/signaltometricsconnector/go.sum +++ b/connector/signaltometricsconnector/go.sum @@ -92,6 +92,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d h1:VgCLczw4cH0tSj9Jmd5BG047SdUUR6e9snoPAvpSCPA= @@ -229,6 +231,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/connector/sumconnector/go.mod b/connector/sumconnector/go.mod index 2a0fb0791ab64..af6107ab68350 100644 --- a/connector/sumconnector/go.mod +++ b/connector/sumconnector/go.mod @@ -58,6 +58,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/connector/xconnector v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect @@ -77,6 +78,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/connector/sumconnector/go.sum b/connector/sumconnector/go.sum index a76d653bd94ea..8050f92ffd86a 100644 --- a/connector/sumconnector/go.sum +++ b/connector/sumconnector/go.sum @@ -92,6 +92,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d h1:VgCLczw4cH0tSj9Jmd5BG047SdUUR6e9snoPAvpSCPA= @@ -227,6 +229,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/filter/go.mod b/internal/filter/go.mod index 05c34e503f72e..cbd2c6c5e9205 100644 --- a/internal/filter/go.mod +++ b/internal/filter/go.mod @@ -52,6 +52,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/pdata/pprofile v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect @@ -63,6 +64,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/filter/go.sum b/internal/filter/go.sum index 1ece3ecf2a6cd..6c1c8394971cb 100644 --- a/internal/filter/go.sum +++ b/internal/filter/go.sum @@ -94,12 +94,16 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d h1:VgCLczw4cH0tSj9Jmd5BG047SdUUR6e9snoPAvpSCPA= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d/go.mod h1:DnviH4iNFbGI7/timy6lu+u+pWRu//N31J5PR+vMyn8= go.opentelemetry.io/collector/confmap v1.52.1-0.20260227062254-168030d61d7d h1:0A4lGxt3kExzBSk+t8HMb95IF75/SyqESzOemRHdfI0= go.opentelemetry.io/collector/confmap v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:j0oKnokAKoLRpr9IxFL+TfO+1bS65z+BFKk5jyz++2A= +go.opentelemetry.io/collector/consumer v1.52.1-0.20260227062254-168030d61d7d h1:avxj/edyvAjZ9GBZcvuZQfvtpdDDQKugGy2ICEy0iLc= +go.opentelemetry.io/collector/consumer v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:pb+eeJInUz/rVU0ujJYqzEcOSsvkdNeLg6xpSVRRqUY= go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d h1:F4l81rGyQ253S1QASslOc8ftkAPaatTT+eCZJsuN44U= go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= go.opentelemetry.io/collector/internal/testutil v0.146.1 h1:hpemuw5sLSYIqflJdScFikLhCjHxKuJWC2Lwyh9yeCI= @@ -205,6 +209,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/ottl/contexts/internal/ctxotelcol/client.go b/pkg/ottl/contexts/internal/ctxotelcol/client.go new file mode 100644 index 0000000000000..2f999c2e02893 --- /dev/null +++ b/pkg/ottl/contexts/internal/ctxotelcol/client.go @@ -0,0 +1,215 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ctxotelcol // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" + +import ( + "context" + "errors" + "fmt" + + "go.opentelemetry.io/collector/client" + "go.opentelemetry.io/collector/pdata/pcommon" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxerror" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxutil" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/internal/ottlcommon" +) + +func accessClient[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + nextPath := path.Next() + if nextPath == nil { + return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef) + } + switch nextPath.Name() { + case "addr": + return accessClientAddr(nextPath) + case "auth": + return accessClientAuth(nextPath) + case "metadata": + return accessClientMetadata(nextPath) + default: + return nil, ctxerror.New(nextPath.Name(), nextPath.String(), Name, DocRef) + } +} + +func accessClientMetadata[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + nextPath := path.Next() + if nextPath != nil { + return nil, ctxerror.New(nextPath.Name(), nextPath.String(), Name, DocRef) + } + if path.Keys() == nil { + return accessClientMetadataKeys[K](), nil + } + return accessClientMetadataKey[K](path.Keys()), nil +} + +func accessClientAddr[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + nextPath := path.Next() + if nextPath != nil { + return nil, ctxerror.New(nextPath.Name(), nextPath.String(), Name, DocRef) + } + if path.Keys() != nil { + return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef) + } + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, _ K) (any, error) { + cl := client.FromContext(ctx) + if cl.Addr == nil { + return nil, nil + } + return cl.Addr.String(), nil + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.client.addr") + }, + }, nil +} + +func getAuthAttributeValue(authData client.AuthData, key string) (pcommon.Value, error) { + attrVal := authData.GetAttribute(key) + switch typedAttrVal := attrVal.(type) { + case string: + return pcommon.NewValueStr(typedAttrVal), nil + case []string: + value := pcommon.NewValueSlice() + slice := value.Slice() + slice.EnsureCapacity(len(typedAttrVal)) + for _, str := range typedAttrVal { + slice.AppendEmpty().SetStr(str) + } + return value, nil + default: + value := pcommon.NewValueEmpty() + err := value.FromRaw(attrVal) + if err != nil { + return pcommon.Value{}, err + } + return value, nil + } +} + +func convertAuthDataToMap(authData client.AuthData) pcommon.Map { + authMap := pcommon.NewMap() + if authData == nil { + return authMap + } + names := authData.GetAttributeNames() + authMap.EnsureCapacity(len(names)) + for _, name := range names { + newKeyValue := authMap.PutEmpty(name) + if value, err := getAuthAttributeValue(authData, name); err == nil { + value.MoveTo(newKeyValue) + } + } + return authMap +} + +func accessClientAuth[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + nextPath := path.Next() + if nextPath == nil { + return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef) + } + switch nextPath.Name() { + case "attributes": + if nextPath.Keys() == nil { + return accessClientAuthAttributesKeys[K](), nil + } + return accessClientAuthAttributesKey[K](nextPath.Keys()), nil + default: + return nil, ctxerror.New(nextPath.Name(), nextPath.String(), Name, DocRef) + } +} + +func accessClientAuthAttributesKeys[K any]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, _ K) (any, error) { + cl := client.FromContext(ctx) + return convertAuthDataToMap(cl.Auth), nil + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.client.auth.attributes") + }, + } +} + +func accessClientAuthAttributesKey[K any](keys []ottl.Key[K]) ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, tCtx K) (any, error) { + if len(keys) == 0 { + return nil, errors.New("cannot get map value without keys") + } + cl := client.FromContext(ctx) + key, err := ctxutil.GetMapKeyName(ctx, tCtx, keys[0]) + if err != nil { + return nil, err + } + if cl.Auth == nil { + return nil, nil + } + attrVal, err := getAuthAttributeValue(cl.Auth, *key) + if err != nil { + return nil, err + } + if len(keys) > 1 { + switch attrVal.Type() { + case pcommon.ValueTypeSlice: + return ctxutil.GetSliceValue[K](ctx, tCtx, attrVal.Slice(), keys[1:]) + case pcommon.ValueTypeMap: + return ctxutil.GetMapValue[K](ctx, tCtx, attrVal.Map(), keys[1:]) + default: + return nil, fmt.Errorf("attribute %q value is not indexable: %s", *key, attrVal.Type().String()) + } + } + return ottlcommon.GetValue(attrVal), nil + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.client.auth.attributes") + }, + } +} + +func convertClientMetadataToMap(md client.Metadata) pcommon.Map { + mdMap := pcommon.NewMap() + for k := range md.Keys() { + convertStringArrToValueSlice(md.Get(k)).MoveTo(mdMap.PutEmpty(k)) + } + return mdMap +} + +func accessClientMetadataKeys[K any]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, _ K) (any, error) { + cl := client.FromContext(ctx) + return convertClientMetadataToMap(cl.Metadata), nil + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.client.metadata") + }, + } +} + +func accessClientMetadataKey[K any](keys []ottl.Key[K]) ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, tCtx K) (any, error) { + if len(keys) == 0 { + return nil, errors.New("cannot get map value without keys") + } + + key, err := ctxutil.GetMapKeyName(ctx, tCtx, keys[0]) + if err != nil { + return nil, fmt.Errorf("cannot get map value: %w", err) + } + cl := client.FromContext(ctx) + mdVal := cl.Metadata.Get(*key) + if len(mdVal) == 0 { + return nil, nil + } + return getIndexableValueFromStringArr(ctx, tCtx, keys[1:], mdVal) + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.client.metadata") + }, + } +} diff --git a/pkg/ottl/contexts/internal/ctxotelcol/context.go b/pkg/ottl/contexts/internal/ctxotelcol/context.go new file mode 100644 index 0000000000000..ac27b12a50e7e --- /dev/null +++ b/pkg/ottl/contexts/internal/ctxotelcol/context.go @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ctxotelcol // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" + +const ( + readOnlyPathErrMsg = "%q is read-only and cannot be modified" + Name = "otelcol" + DocRef = "https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol" +) diff --git a/pkg/ottl/contexts/internal/ctxotelcol/grpc.go b/pkg/ottl/contexts/internal/ctxotelcol/grpc.go new file mode 100644 index 0000000000000..6d42bc8d0a181 --- /dev/null +++ b/pkg/ottl/contexts/internal/ctxotelcol/grpc.go @@ -0,0 +1,83 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ctxotelcol // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" + +import ( + "context" + "errors" + "fmt" + + "go.opentelemetry.io/collector/pdata/pcommon" + "google.golang.org/grpc/metadata" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxerror" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxutil" +) + +func accessGRPC[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + nextPath := path.Next() + if nextPath == nil { + return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef) + } + switch nextPath.Name() { + case "metadata": + if nextPath.Keys() == nil { + return accessGRPCMetadataKeys[K](), nil + } + return accessGRPCMetadataKey[K](nextPath.Keys()), nil + default: + return nil, ctxerror.New(nextPath.Name(), nextPath.String(), Name, DocRef) + } +} + +func convertGRPCMetadataToMap(md metadata.MD) pcommon.Map { + mdMap := pcommon.NewMap() + mdMap.EnsureCapacity(len(md)) + for k, v := range md { + convertStringArrToValueSlice(v).MoveTo(mdMap.PutEmpty(k)) + } + return mdMap +} + +func accessGRPCMetadataKeys[K any]() ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, _ K) (any, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return pcommon.NewMap(), nil + } + return convertGRPCMetadataToMap(md), nil + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.grpc.metadata") + }, + } +} + +func accessGRPCMetadataKey[K any](keys []ottl.Key[K]) ottl.StandardGetSetter[K] { + return ottl.StandardGetSetter[K]{ + Getter: func(ctx context.Context, tCtx K) (any, error) { + if len(keys) == 0 { + return nil, errors.New("cannot get map value without keys") + } + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil, nil + } + key, err := ctxutil.GetMapKeyName(ctx, tCtx, keys[0]) + if err != nil { + return nil, err + } + mdVal := md.Get(*key) + if len(mdVal) == 0 { + return nil, nil + } + return getIndexableValueFromStringArr(ctx, tCtx, keys[1:], mdVal) + }, + Setter: func(_ context.Context, _ K, _ any) error { + return fmt.Errorf(readOnlyPathErrMsg, "otelcol.grpc.metadata") + }, + } +} diff --git a/pkg/ottl/contexts/internal/ctxotelcol/otelcol.go b/pkg/ottl/contexts/internal/ctxotelcol/otelcol.go new file mode 100644 index 0000000000000..599a698cabbe6 --- /dev/null +++ b/pkg/ottl/contexts/internal/ctxotelcol/otelcol.go @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ctxotelcol // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" + +import ( + "context" + "errors" + + "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/pdata/pcommon" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxerror" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxutil" +) + +var ( + enableOTelColContext = featuregate.GlobalRegistry().MustRegister( + "ottl.contexts.enableOTelColContext", + featuregate.StageBeta, + featuregate.WithRegisterDescription("Enable the `otelcol` context for OTTL. This allows users using `otelcol.*` paths in their OTTL statements and conditions."), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/46437"), + featuregate.WithRegisterFromVersion("v0.147.0")) + errOTelColContextDisabled = errors.New("OTTL `otelcol` context requires the `ottl.contexts.enableOTelColContext` feature gate to be enabled") +) + +func PathGetSetter[K any](path ottl.Path[K]) (ottl.GetSetter[K], error) { + if !enableOTelColContext.IsEnabled() { + return nil, errOTelColContextDisabled + } + switch path.Name() { + case "client": + return accessClient[K](path) + case "grpc": + return accessGRPC[K](path) + default: + return nil, ctxerror.New(path.Name(), path.String(), Name, DocRef) + } +} + +func convertStringArrToValueSlice(vals []string) pcommon.Value { + val := pcommon.NewValueSlice() + sl := val.Slice() + sl.EnsureCapacity(len(vals)) + for _, v := range vals { + sl.AppendEmpty().SetStr(v) + } + return val +} + +func getIndexableValueFromStringArr[K any](ctx context.Context, tCtx K, keys []ottl.Key[K], strSlice []string) (any, error) { + if len(keys) == 0 { + slice := pcommon.NewSlice() + slice.EnsureCapacity(len(strSlice)) + for _, str := range strSlice { + slice.AppendEmpty().SetStr(str) + } + return slice, nil + } + if len(keys) > 1 { + return nil, errors.New("cannot index into string slice more than once") + } + index, err := ctxutil.GetSliceIndexFromKeys(ctx, tCtx, len(strSlice), keys) + if err != nil { + return nil, err + } + return strSlice[index], nil +} diff --git a/pkg/ottl/contexts/internal/ctxotelcol/otelcol_test.go b/pkg/ottl/contexts/internal/ctxotelcol/otelcol_test.go new file mode 100644 index 0000000000000..959644bded9cd --- /dev/null +++ b/pkg/ottl/contexts/internal/ctxotelcol/otelcol_test.go @@ -0,0 +1,515 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ctxotelcol + +import ( + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/client" + "go.opentelemetry.io/collector/featuregate" + "go.opentelemetry.io/collector/pdata/pcommon" + "google.golang.org/grpc/metadata" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/pathtest" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" +) + +func TestContextClientMetadata(t *testing.T) { + clientMDRaw := map[string][]string{ + "auth": {"Bearer token123"}, + "content-type": {"application/json"}, + "user-agent": {"test-agent/1.0"}, + "empty-key": {}, + "multi-values": {"value1", "value2"}, + } + clientMD := client.NewMetadata(clientMDRaw) + + ctx := client.NewContext(t.Context(), client.Info{ + Metadata: clientMD, + }) + + t.Run("access entire metadata", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + + result, ok := val.(pcommon.Map) + require.True(t, ok) + + auth, ok := result.Get("auth") + require.True(t, ok) + require.Equal(t, []any{"Bearer token123"}, auth.Slice().AsRaw()) + + contentType, ok := result.Get("content-type") + require.True(t, ok) + require.Equal(t, []any{"application/json"}, contentType.Slice().AsRaw()) + }) + + t.Run("access specific metadata key", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("auth"), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + result, ok := val.(pcommon.Slice) + require.True(t, ok) + assert.Equal(t, []any{"Bearer token123"}, result.AsRaw()) + }) + + t.Run("access non-existent metadata key", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("non-existent"), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Nil(t, val) + }) + + t.Run("access empty metadata key", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("empty-key"), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Nil(t, val) + }) + + t.Run("access metadata key with multiple values", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("multi-values"), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + result, ok := val.(pcommon.Slice) + require.True(t, ok) + assert.Equal(t, []any{"value1", "value2"}, result.AsRaw()) + }) + + t.Run("access metadata key with multiple values by index", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("multi-values"), + }, + &pathtest.Key[testContext]{ + I: ottltest.Intp(0), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + result, ok := val.(string) + require.True(t, ok) + assert.Equal(t, "value1", result) + }) + + t.Run("cannot set entire metadata", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + newMetadata := client.NewMetadata(map[string][]string{ + "new-key": {"new-value"}, + }) + + err = getter.Set(ctx, testContext{}, newMetadata) + require.Error(t, err) + assert.Equal(t, `"otelcol.client.metadata" is read-only and cannot be modified`, err.Error()) + }) + + t.Run("cannot set specific metadata key", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{ + S: ottltest.Strp("auth"), + }, + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + err = getter.Set(ctx, testContext{}, "new-value") + require.Error(t, err) + assert.Equal(t, `"otelcol.client.metadata" is read-only and cannot be modified`, err.Error()) + }) + + t.Run("error when accessing metadata key without keys", func(t *testing.T) { + // This should not happen through normal parser, but testing the underlying function + getter := accessClientMetadataKey[testContext]([]ottl.Key[testContext]{}) + + _, err := getter.Get(ctx, testContext{}) + require.Error(t, err) + assert.Equal(t, "cannot get map value without keys", err.Error()) + }) + + t.Run("no client in context", func(t *testing.T) { + // Test with context that has no client info + emptyCtx := t.Context() + + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(emptyCtx, testContext{}) + require.NoError(t, err) + // Should return empty pcommon.Map when no client is in context + emptyMap := pcommon.NewMap() + assert.Equal(t, emptyMap, val) + }) +} + +func TestContextClientAddr(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "addr", + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + addr := testAddr{"127.0.0.1:4317"} + ctx := client.NewContext(t.Context(), client.Info{Addr: addr}) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Equal(t, "127.0.0.1:4317", val) + + err = getter.Set(ctx, testContext{}, "ignored") + require.Error(t, err) + assert.Equal(t, `"otelcol.client.addr" is read-only and cannot be modified`, err.Error()) +} + +func TestContextClientAuthAttributes_AllAndKey(t *testing.T) { + auth := testAuth{ + attrs: map[string]any{ + "subject": "user-123", + "roles": []string{"admin", "user"}, + }, + } + ctx := client.NewContext(t.Context(), client.Info{Auth: auth}) + + t.Run("all attributes map", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "auth", + NextPath: &pathtest.Path[testContext]{ + N: "attributes", + }, + }, + } + + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + m, ok := val.(pcommon.Map) + require.True(t, ok) + user, ok := m.Get("subject") + require.True(t, ok) + assert.Equal(t, "user-123", user.AsString()) + roles, ok := m.Get("roles") + require.True(t, ok) + assert.Equal(t, "[\"admin\",\"user\"]", roles.AsString()) + + err = getter.Set(ctx, testContext{}, map[string]string{"k": "v"}) + require.Error(t, err) + assert.Equal(t, `"otelcol.client.auth.attributes" is read-only and cannot be modified`, err.Error()) + }) + + t.Run("specific attribute key present", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "auth", + NextPath: &pathtest.Path[testContext]{ + N: "attributes", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{S: ottltest.Strp("subject")}, + }, + }, + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Equal(t, "user-123", val) + }) + + t.Run("specific attribute key present with index", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "auth", + NextPath: &pathtest.Path[testContext]{ + N: "attributes", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{S: ottltest.Strp("roles")}, + &pathtest.Key[testContext]{I: ottltest.Intp(1)}, + }, + }, + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Equal(t, "user", val) + }) + + t.Run("specific attribute key missing returns empty string", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "client", + NextPath: &pathtest.Path[testContext]{ + N: "auth", + NextPath: &pathtest.Path[testContext]{ + N: "attributes", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{S: ottltest.Strp("missing")}, + }, + }, + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctx, testContext{}) + require.NoError(t, err) + assert.Empty(t, val) + }) + + t.Run("attributes key without keys error", func(t *testing.T) { + getter := accessClientAuthAttributesKey[testContext]([]ottl.Key[testContext]{}) + _, err := getter.Get(ctx, testContext{}) + require.Error(t, err) + assert.Equal(t, "cannot get map value without keys", err.Error()) + }) +} + +func TestContextGrpcMetadata(t *testing.T) { + base := t.Context() + // include client context too, to ensure coexistence + base = client.NewContext(base, client.Info{}) + + md := metadata.Pairs( + "k1", "v1", + "k1", "v2", + "single", "only", + ) + ctxWithMD := metadata.NewIncomingContext(base, md) + + t.Run("get entire grpc metadata", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "grpc", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctxWithMD, testContext{}) + require.NoError(t, err) + mdVal, ok := val.(pcommon.Map) + require.True(t, ok) + k, ok := mdVal.Get("k1") + require.True(t, ok) + assert.Equal(t, []any{"v1", "v2"}, k.Slice().AsRaw()) + + s, ok := mdVal.Get("single") + require.True(t, ok) + assert.Equal(t, []any{"only"}, s.Slice().AsRaw()) + + err = getter.Set(ctxWithMD, testContext{}, metadata.MD{}) + require.Error(t, err) + assert.Equal(t, `"otelcol.grpc.metadata" is read-only and cannot be modified`, err.Error()) + }) + + t.Run("get specific grpc metadata key values", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "grpc", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{S: ottltest.Strp("k1")}, + }, + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctxWithMD, testContext{}) + require.NoError(t, err) + sl, ok := val.(pcommon.Slice) + require.True(t, ok) + assert.Equal(t, []any{"v1", "v2"}, sl.AsRaw()) + + err = getter.Set(ctxWithMD, testContext{}, []string{"x"}) + require.Error(t, err) + assert.Equal(t, `"otelcol.grpc.metadata" is read-only and cannot be modified`, err.Error()) + }) + + t.Run("grpc metadata key missing returns nil", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "grpc", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + KeySlice: []ottl.Key[testContext]{ + &pathtest.Key[testContext]{S: ottltest.Strp("missing")}, + }, + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(ctxWithMD, testContext{}) + require.NoError(t, err) + assert.Nil(t, val) + }) + + t.Run("grpc metadata without keys error", func(t *testing.T) { + getter := accessGRPCMetadataKey[testContext]([]ottl.Key[testContext]{}) + _, err := getter.Get(ctxWithMD, testContext{}) + require.Error(t, err) + assert.Equal(t, "cannot get map value without keys", err.Error()) + }) + + t.Run("no grpc metadata in context returns Map", func(t *testing.T) { + path := &pathtest.Path[testContext]{ + N: "grpc", + NextPath: &pathtest.Path[testContext]{ + N: "metadata", + }, + } + getter, err := PathGetSetter[testContext](path) + require.NoError(t, err) + val, err := getter.Get(t.Context(), testContext{}) + require.NoError(t, err) + require.Equal(t, pcommon.NewMap(), val.(pcommon.Map)) + }) +} + +func Test_enableOTelColContextFeatureGate(t *testing.T) { + original := enableOTelColContext.IsEnabled() + defer func() { + require.NoError(t, featuregate.GlobalRegistry().Set(enableOTelColContext.ID(), original)) + }() + + require.NoError(t, featuregate.GlobalRegistry().Set(enableOTelColContext.ID(), false)) + _, err := PathGetSetter(&pathtest.Path[testContext]{}) + assert.Equal(t, errOTelColContextDisabled, err) +} + +type testContext struct{} + +func (testContext) GetTestValue() string { + return "test" +} + +type testAddr struct{ s string } + +func (testAddr) Network() string { return "tcp" } +func (a testAddr) String() string { return a.s } + +var _ net.Addr = (*testAddr)(nil) + +type testAuth struct{ attrs map[string]any } + +func (a testAuth) GetAttribute(name string) any { + return a.attrs[name] +} + +func (a testAuth) GetAttributeNames() []string { + names := make([]string, 0, len(a.attrs)) + for k := range a.attrs { + names = append(names, k) + } + return names +} diff --git a/pkg/ottl/contexts/internal/ctxutil/slice.go b/pkg/ottl/contexts/internal/ctxutil/slice.go index 5d267727ff6a4..ad19da332020a 100644 --- a/pkg/ottl/contexts/internal/ctxutil/slice.go +++ b/pkg/ottl/contexts/internal/ctxutil/slice.go @@ -23,7 +23,7 @@ var ( errMissingGetKey = errors.New("cannot get slice value without key") ) -func getSliceIndexFromKeys[K any](ctx context.Context, tCtx K, sliceLen int, keys []ottl.Key[K]) (int, error) { +func GetSliceIndexFromKeys[K any](ctx context.Context, tCtx K, sliceLen int, keys []ottl.Key[K]) (int, error) { i, err := keys[0].Int(ctx, tCtx) if err != nil { return 0, err @@ -50,7 +50,7 @@ func GetSliceValue[K any](ctx context.Context, tCtx K, s pcommon.Slice, keys []o return 0, errMissingGetKey } - idx, err := getSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) + idx, err := GetSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) if err != nil { return nil, err } @@ -63,7 +63,7 @@ func SetSliceValue[K any](ctx context.Context, tCtx K, s pcommon.Slice, keys []o return errMissingSetKey } - idx, err := getSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) + idx, err := GetSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) if err != nil { return err } @@ -92,7 +92,7 @@ func GetCommonTypedSliceValue[K, V any](ctx context.Context, tCtx K, s CommonTyp return *new(V), fmt.Errorf(typeNotIndexableError, s) } - idx, err := getSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) + idx, err := GetSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) if err != nil { return *new(V), err } @@ -110,7 +110,7 @@ func SetCommonTypedSliceValue[K, V any](ctx context.Context, tCtx K, s CommonTyp return fmt.Errorf(typeNotIndexableError, s) } - idx, err := getSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) + idx, err := GetSliceIndexFromKeys(ctx, tCtx, s.Len(), keys) if err != nil { return err } diff --git a/pkg/ottl/contexts/ottldatapoint/README.md b/pkg/ottl/contexts/ottldatapoint/README.md index 81ed8b57a14e2..7f2191f09e97c 100644 --- a/pkg/ottl/contexts/ottldatapoint/README.md +++ b/pkg/ottl/contexts/ottldatapoint/README.md @@ -49,6 +49,7 @@ The following paths are supported. | datapoint.scale | the scale of the data point being processed | int64 | | datapoint.zero_count | the zero_count of the data point being processed | int64 | | datapoint.quantile_values | the quantile_values of the data point being processed | pmetric.SummaryDataPointValueAtQuantileSlice | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottldatapoint/datapoint.go b/pkg/ottl/contexts/ottldatapoint/datapoint.go index eac3666fd5e8f..164fc7ee3801c 100644 --- a/pkg/ottl/contexts/ottldatapoint/datapoint.go +++ b/pkg/ottl/contexts/ottldatapoint/datapoint.go @@ -18,6 +18,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxdatapoint" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxmetric" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" @@ -145,6 +146,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxscope.LegacyName, ctxscope.Name, ctxmetric.Name, + ctxotelcol.Name, })(p) } } @@ -225,5 +227,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxmetric.Name: ctxmetric.PathGetSetter[*TransformContext], ctxdatapoint.Name: ctxdatapoint.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottllog/README.md b/pkg/ottl/contexts/ottllog/README.md index bb8cffb79593a..2f099f71cabb9 100644 --- a/pkg/ottl/contexts/ottllog/README.md +++ b/pkg/ottl/contexts/ottllog/README.md @@ -12,39 +12,40 @@ All TraceIDs and SpanIDs are returned as pdata [SpanID](https://github.com/open- The following paths are supported. -| path | field accessed | type | -|------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| log.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| log.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource | resource of the log being processed | pcommon.Resource | -| resource.attributes | resource attributes of the log being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the resource attribute of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource.dropped_attributes_count | number of dropped attributes of the resource of the log being processed | int64 | -| instrumentation_scope | instrumentation scope of the log being processed | pcommon.InstrumentationScope | -| instrumentation_scope.name | name of the instrumentation scope of the log being processed | string | -| instrumentation_scope.version | version of the instrumentation scope of the log being processed | string | -| instrumentation_scope.dropped_attributes_count | number of dropped attributes of the instrumentation scope of the log being processed | int64 | -| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | -| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| log.attributes | attributes of the log being processed | pcommon.Map | -| log.attributes\[""\] | the value of the attribute of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| log.event_name | the event name associated with the log being processed. | string | -| log.trace_id | a byte slice representation of the trace id | pcommon.TraceID | -| log.trace_id.string | a string representation of the trace id | string | -| log.span_id | a byte slice representation of the span id | pcommon.SpanID | -| log.span_id.string | a string representation of the span id | string | -| log.time_unix_nano | the time in unix nano of the log being processed | int64 | -| log.observed_time_unix_nano | the observed time in unix nano of the log being processed | int64 | -| log.time | the time in `time.Time` of the log being processed | `time.Time` | -| log.observed_time | the observed time in `time.Time` of the log being processed | `time.Time` | -| log.severity_number | the severity number of the log being processed | int64 | -| log.severity_text | the severity text of the log being processed | string | -| log.body | the body of the log being processed | any | -| log.body\[""\] | a value in a map body of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| log.body\[\] | a value in a slice body of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| log.body.string | the body of the log being processed represented as a string. When setting must pass a string. | string | -| log.dropped_attributes_count | the number of dropped attributes of the log being processed | int64 | -| log.flags | the flags of the log being processed | int64 | +| path | field accessed | type | +|------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| log.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| log.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource | resource of the log being processed | pcommon.Resource | +| resource.attributes | resource attributes of the log being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the resource attribute of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource.dropped_attributes_count | number of dropped attributes of the resource of the log being processed | int64 | +| instrumentation_scope | instrumentation scope of the log being processed | pcommon.InstrumentationScope | +| instrumentation_scope.name | name of the instrumentation scope of the log being processed | string | +| instrumentation_scope.version | version of the instrumentation scope of the log being processed | string | +| instrumentation_scope.dropped_attributes_count | number of dropped attributes of the instrumentation scope of the log being processed | int64 | +| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | +| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| log.attributes | attributes of the log being processed | pcommon.Map | +| log.attributes\[""\] | the value of the attribute of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| log.event_name | the event name associated with the log being processed. | string | +| log.trace_id | a byte slice representation of the trace id | pcommon.TraceID | +| log.trace_id.string | a string representation of the trace id | string | +| log.span_id | a byte slice representation of the span id | pcommon.SpanID | +| log.span_id.string | a string representation of the span id | string | +| log.time_unix_nano | the time in unix nano of the log being processed | int64 | +| log.observed_time_unix_nano | the observed time in unix nano of the log being processed | int64 | +| log.time | the time in `time.Time` of the log being processed | `time.Time` | +| log.observed_time | the observed time in `time.Time` of the log being processed | `time.Time` | +| log.severity_number | the severity number of the log being processed | int64 | +| log.severity_text | the severity text of the log being processed | string | +| log.body | the body of the log being processed | any | +| log.body\[""\] | a value in a map body of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| log.body\[\] | a value in a slice body of the log being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| log.body.string | the body of the log being processed represented as a string. When setting must pass a string. | string | +| log.dropped_attributes_count | the number of dropped attributes of the log being processed | int64 | +| log.flags | the flags of the log being processed | int64 | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottllog/log.go b/pkg/ottl/contexts/ottllog/log.go index 935435cc04048..f2d4470ae7cb7 100644 --- a/pkg/ottl/contexts/ottllog/log.go +++ b/pkg/ottl/contexts/ottllog/log.go @@ -18,6 +18,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxlog" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" @@ -140,6 +141,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxscope.LegacyName, ctxscope.Name, ctxresource.Name, + ctxotelcol.Name, })(p) } } @@ -221,5 +223,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.Name: ctxscope.PathGetSetter[*TransformContext], ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxlog.Name: ctxlog.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlmetric/README.md b/pkg/ottl/contexts/ottlmetric/README.md index 822bc86fed847..408c92d276599 100644 --- a/pkg/ottl/contexts/ottlmetric/README.md +++ b/pkg/ottl/contexts/ottlmetric/README.md @@ -10,26 +10,27 @@ In general, the Metric Context supports accessing pdata using the field names fr The following paths are supported. -| path | field accessed | type | -|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| metric.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| metric.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource | resource of the metric being processed | pcommon.Resource | -| resource.attributes | resource attributes of the metric being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the resource attribute of the metric being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| instrumentation_scope | instrumentation scope of the metric being processed | pcommon.InstrumentationScope | -| instrumentation_scope.name | name of the instrumentation scope of the metric being processed | string | -| instrumentation_scope.version | version of the instrumentation scope of the metric being processed | string | -| instrumentation_scope.attributes | instrumentation scope attributes of the metric being processed | pcommon.Map | -| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the metric being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| metric.name | the name of the metric | string | -| metric.description | the description of the metric | string | -| metric.unit | the unit of the metric | string | -| metric.type | the data type of the metric | int64 | -| metric.metadata | metadata associated with the metric | pcommon.Map | -| metric.aggregation_temporality | the aggregation temporality of the metric | int64 | -| metric.is_monotonic | the monotonicity of the metric | bool | -| metric.data_points | the data points of the metric | pmetric.NumberDataPointSlice, pmetric.HistogramDataPointSlice, pmetric.ExponentialHistogramDataPointSlice, or pmetric.SummaryDataPointSlice | +| path | field accessed | type | +|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| +| metric.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| metric.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource | resource of the metric being processed | pcommon.Resource | +| resource.attributes | resource attributes of the metric being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the resource attribute of the metric being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| instrumentation_scope | instrumentation scope of the metric being processed | pcommon.InstrumentationScope | +| instrumentation_scope.name | name of the instrumentation scope of the metric being processed | string | +| instrumentation_scope.version | version of the instrumentation scope of the metric being processed | string | +| instrumentation_scope.attributes | instrumentation scope attributes of the metric being processed | pcommon.Map | +| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the metric being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| metric.name | the name of the metric | string | +| metric.description | the description of the metric | string | +| metric.unit | the unit of the metric | string | +| metric.type | the data type of the metric | int64 | +| metric.metadata | metadata associated with the metric | pcommon.Map | +| metric.aggregation_temporality | the aggregation temporality of the metric | int64 | +| metric.is_monotonic | the monotonicity of the metric | bool | +| metric.data_points | the data points of the metric | pmetric.NumberDataPointSlice, pmetric.HistogramDataPointSlice, pmetric.ExponentialHistogramDataPointSlice, or pmetric.SummaryDataPointSlice | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottlmetric/metrics.go b/pkg/ottl/contexts/ottlmetric/metrics.go index 615dff36a25c7..ccb4d46e9b7fe 100644 --- a/pkg/ottl/contexts/ottlmetric/metrics.go +++ b/pkg/ottl/contexts/ottlmetric/metrics.go @@ -17,6 +17,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxmetric" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" @@ -124,6 +125,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxscope.LegacyName, ctxscope.Name, ctxresource.Name, + ctxotelcol.Name, })(p) } } @@ -205,5 +207,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.Name: ctxscope.PathGetSetter[*TransformContext], ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxmetric.Name: ctxmetric.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlotelcol/README.md b/pkg/ottl/contexts/ottlotelcol/README.md new file mode 100644 index 0000000000000..8857bb97f515c --- /dev/null +++ b/pkg/ottl/contexts/ottlotelcol/README.md @@ -0,0 +1,98 @@ +# OTelCol Context + +The `otelcol` context exposes data passed through the OpenTelemetry Collector by its components, including client details, request information, and incoming gRPC metadata. +Access these paths under the top-level `otelcol` segment, optionally followed by one or more sub-segments. +This data is only available inside the OpenTelemetry Collector and is not included by default in telemetry exported from the Collector. + +## Paths + +The following paths are supported. + +| path | field accessed | type | +|------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| otelcol.client.addr | the remote address string from the client info | string | +| otelcol.client.metadata | client metadata attached to the request via `go.opentelemetry.io/collector/client` | pcommon.Map | +| otelcol.client.metadata[""] | the value for a specific metadata key | string or nil | +| otelcol.client.auth.attributes | map of all auth attributes values extracted from `client.Info.Auth`. Unsupported value types are mapped as empty string | pcommon.Map | +| otelcol.client.auth.attributes[""] | the value for a specific auth attribute key | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| otelcol.grpc.metadata | incoming gRPC metadata from the context | pcommon.Map | +| otelcol.grpc.metadata[""] | values slice for a specific incoming gRPC metadata key | string or nil | + + +> [!NOTE] +This context is read-only; any attempt to set these paths returns an error. + +## Security and best practices + +The `otelcol` context exposes client and request data that often contains **sensitive information**: authentication tokens (e.g. in `otelcol.client.auth.attributes`), HTTP headers and gRPC metadata (e.g. in `otelcol.client.metadata` and `otelcol.grpc.metadata`), and client address. +OTTL can **read** these values and **write** them into span attributes, log body, resource attributes, or metric labels. +Copying such data into telemetry can expose secrets to every system that receives it. + +### Do not leak secrets into telemetry + +Avoid writing `otelcol` path values into telemetry unless you have explicitly confirmed that the key and value are non-sensitive. + +**Unsafe examples (do not do this):** + +```yaml +# BAD: Copies client metadata (e.g. Authorization header) into span attributes +- set(span.attributes["auth_header"], otelcol.client.metadata["authorization"]) + +# BAD: Copies auth attributes into resource (it may contain tokens) +- set(resource.attributes["auth"], otelcol.client.auth.attributes["token"]) + +# BAD: Copies gRPC metadata into log body (may expose API keys or tokens) +- set(log.body, otelcol.grpc.metadata["x-api-key"]) +``` + +**Safe examples:** + +```yaml +# OK: Use otelcol paths only in conditions (not written to telemetry) +- set(span.attributes["routed"], true) where otelcol.client.metadata["x-tenant-id"] != nil + +# OK: Copy only a non-sensitive, allowlisted key you control +- set(span.attributes["tenant_id"], otelcol.client.metadata["x-tenant-id"]) where IsMatch(otelcol.client.metadata["x-tenant-id"], "^[a-zA-Z0-9-]+$") +``` + +### Commonly sensitive keys + +Treat the following (and similar) keys as sensitive. Do not copy their values into attributes, body, or resource: + +| Key (typical) | Reason | +|----------------------------------|---------------------------------------| +| `authorization` | Bearer tokens, Basic auth credentials | +| `cookie` | Session and auth cookies | +| `x-api-key`, `api-key` | API keys | +| `x-auth-token`, `x-access-token` | Access tokens | +| `proxy-authorization` | Proxy credentials | + +This applies to **`otelcol.client.metadata["key"]`** and **`otelcol.grpc.metadata["key"]`**. +For **`otelcol.client.auth.attributes`**, treat the **entire** map as sensitive unless you know the auth extension only exposes non-secret attributes. +HTTP header names are often normalized to lowercase; consider that when allowlisting or blocklisting. + +### Recommended practices + +1. **Prefer using `otelcol` paths only in conditions**: Use them to decide what to do (filter, route, sample) without storing values in telemetry. +2. **Allowlist keys when copying to telemetry**: If you must copy, restrict to a small set of non-sensitive keys (e.g. `x-tenant-id`, `x-request-id`, `x-correlation-id`) and validate or sanitize values. +3. **Prefer single-key access**: Access only the key you need (e.g. `otelcol.client.metadata["x-tenant-id"]`) rather than the full map (e.g. `otelcol.client.metadata`). Passing the whole map into attributes or functions can expose all metadata, including sensitive keys you did not intend to use. +4. **Document and review**: Treat OTTL that references `otelcol` paths as security-sensitive; review and document which keys are read and whether any are written to telemetry. + +### Safe use cases + +- **Routing**: Send telemetry to different backends or pipelines based on non-sensitive metadata (e.g. `x-tenant-id`, `x-environment`). +- **Filtering**: Drop or sample based on metadata (e.g. internal vs external) without storing the value. +- **Enrichment**: Add only allowlisted, non-secret values (e.g. request ID, tenant ID) as attributes for correlation or multi-tenancy. + +| Do | Don't | +|---------------------------------------------------------|----------------------------------------------------------------------------------| +| Use `otelcol` paths in conditions for routing/filtering | Copy `authorization`, `cookie`, or API key headers into attributes/body/resource | +| Allowlist and validate keys when copying to telemetry | Copy `otelcol.client.auth.attributes` or full metadata maps into exported data | +| Document and review OTTL that uses `otelcol` context | Assume all client/metadata values are safe to store in telemetry | + + +## Feature gate + +The `otelcol` context is temporally controlled by the **`ottl.contexts.enableOTelColContext`** [feature gate](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md#collector-feature-gates). +This gate is **enabled by default**, so all components using OTTL have access to `otelcol.*` paths unless you explicitly disable it. +The feature gate is expected to be removed in a future release once the feature is stable; after that, the `otelcol` context will always be available with no opt-in. \ No newline at end of file diff --git a/pkg/ottl/contexts/ottlotelcol/otelcol.go b/pkg/ottl/contexts/ottlotelcol/otelcol.go new file mode 100644 index 0000000000000..0f16fbc94cf6e --- /dev/null +++ b/pkg/ottl/contexts/ottlotelcol/otelcol.go @@ -0,0 +1,142 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ottlotelcol // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlotelcol" +import ( + "errors" + "sync" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.uber.org/zap/zapcore" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" +) + +var tcPool = sync.Pool{ + New: func() any { + return &TransformContext{cache: pcommon.NewMap()} + }, +} + +// ContextName is the name of the context for context. +// Experimental: *NOTE* this constant is subject to change or removal in the future. +const ContextName = ctxotelcol.Name + +var _ zapcore.ObjectMarshaler = (*TransformContext)(nil) + +// TransformContext represents the data passed through the OpenTelemetry Collector by its components. +type TransformContext struct { + cache pcommon.Map +} + +// MarshalLogObject serializes the TransformContext into a zapcore.ObjectEncoder for logging. +func (tCtx *TransformContext) MarshalLogObject(encoder zapcore.ObjectEncoder) error { + err := encoder.AddObject("cache", logging.Map(tCtx.cache)) + return err +} + +// TransformContextOption represents an option for configuring a TransformContext. +type TransformContextOption func(*TransformContext) + +// NewTransformContextPtr creates a new TransformContext with the provided parameters. +func NewTransformContextPtr(options ...TransformContextOption) *TransformContext { + tc := tcPool.Get().(*TransformContext) + for _, opt := range options { + opt(tc) + } + return tc +} + +// Close the current TransformContext. +// After this function returns this instance cannot be used. +func (tCtx *TransformContext) Close() { + tCtx.cache.Clear() + tcPool.Put(tCtx) +} + +// EnablePathContextNames enables the support for path's context names on statements. +// When this option is configured, all statement's paths must have a valid context prefix, +// otherwise an error is reported. +// +// Experimental: *NOTE* this option is subject to change or removal in the future. +func EnablePathContextNames() ottl.Option[*TransformContext] { + return func(p *ottl.Parser[*TransformContext]) { + ottl.WithPathContextNames[*TransformContext]([]string{ContextName})(p) + } +} + +// StatementSequenceOption represents an option for configuring a statement sequence. +type StatementSequenceOption func(*ottl.StatementSequence[*TransformContext]) + +// WithStatementSequenceErrorMode sets the error mode for a statement sequence. +func WithStatementSequenceErrorMode(errorMode ottl.ErrorMode) StatementSequenceOption { + return func(s *ottl.StatementSequence[*TransformContext]) { + ottl.WithStatementSequenceErrorMode[*TransformContext](errorMode)(s) + } +} + +// NewStatementSequence creates a new statement sequence with the provided statements and options. +func NewStatementSequence(statements []*ottl.Statement[*TransformContext], telemetrySettings component.TelemetrySettings, options ...StatementSequenceOption) ottl.StatementSequence[*TransformContext] { + s := ottl.NewStatementSequence(statements, telemetrySettings) + for _, op := range options { + op(&s) + } + return s +} + +// ConditionSequenceOption represents an option for configuring a condition sequence. +type ConditionSequenceOption func(*ottl.ConditionSequence[*TransformContext]) + +// WithConditionSequenceErrorMode sets the error mode for a condition sequence. +func WithConditionSequenceErrorMode(errorMode ottl.ErrorMode) ConditionSequenceOption { + return func(c *ottl.ConditionSequence[*TransformContext]) { + ottl.WithConditionSequenceErrorMode[*TransformContext](errorMode)(c) + } +} + +// NewConditionSequence creates a new condition sequence with the provided conditions and options. +func NewConditionSequence(conditions []*ottl.Condition[*TransformContext], telemetrySettings component.TelemetrySettings, options ...ConditionSequenceOption) ottl.ConditionSequence[*TransformContext] { + c := ottl.NewConditionSequence(conditions, telemetrySettings) + for _, op := range options { + op(&c) + } + return c +} + +// NewParser creates a new context parser with the provided functions and options. +func NewParser( + functions map[string]ottl.Factory[*TransformContext], + telemetrySettings component.TelemetrySettings, + options ...ottl.Option[*TransformContext], +) (ottl.Parser[*TransformContext], error) { + return ctxcommon.NewParser( + functions, + telemetrySettings, + pathExpressionParser(getCache), + parseEnum, + options..., + ) +} + +func parseEnum(_ *ottl.EnumSymbol) (*ottl.Enum, error) { + return nil, errors.New("context `otelcol` does not provide Enum support") +} + +func getCache(tCtx *TransformContext) pcommon.Map { + return tCtx.cache +} + +func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.PathExpressionParser[*TransformContext] { + return ctxcommon.PathExpressionParser( + ctxotelcol.Name, + ctxotelcol.DocRef, + cacheGetter, + map[string]ottl.PathExpressionParser[*TransformContext]{ + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], + }) +} diff --git a/pkg/ottl/contexts/ottlotelcol/otelcol_test.go b/pkg/ottl/contexts/ottlotelcol/otelcol_test.go new file mode 100644 index 0000000000000..fc079883326c7 --- /dev/null +++ b/pkg/ottl/contexts/ottlotelcol/otelcol_test.go @@ -0,0 +1,190 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ottlotelcol + +import ( + "slices" + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/pcommon" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/pathtest" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottltest" +) + +func Test_newPathGetSetter(t *testing.T) { + newCache := pcommon.NewMap() + newCache.PutStr("temp", "value") + + tests := []struct { + name string + path ottl.Path[*TransformContext] + orig any + newVal any + wantErrOnSet bool + }{ + { + name: "cache", + path: &pathtest.Path[*TransformContext]{ + N: "cache", + }, + orig: pcommon.NewMap(), + newVal: newCache, + wantErrOnSet: false, + }, + { + name: "cache access", + path: &pathtest.Path[*TransformContext]{ + N: "cache", + KeySlice: []ottl.Key[*TransformContext]{ + &pathtest.Key[*TransformContext]{ + S: ottltest.Strp("temp"), + }, + }, + }, + orig: nil, + newVal: "new value", + wantErrOnSet: false, + }, + { + name: "client.addr", + path: &pathtest.Path[*TransformContext]{ + N: "client", + NextPath: &pathtest.Path[*TransformContext]{ + N: "addr", + }, + }, + orig: nil, + newVal: nil, + wantErrOnSet: true, + }, + { + name: "client.metadata", + path: &pathtest.Path[*TransformContext]{ + N: "client", + NextPath: &pathtest.Path[*TransformContext]{ + N: "metadata", + }, + }, + orig: pcommon.NewMap(), + newVal: nil, + wantErrOnSet: true, + }, + { + name: `client.metadata["key"]`, + path: &pathtest.Path[*TransformContext]{ + N: "client", + NextPath: &pathtest.Path[*TransformContext]{ + N: "metadata", + KeySlice: []ottl.Key[*TransformContext]{ + &pathtest.Key[*TransformContext]{ + S: ottltest.Strp("key"), + }, + }, + }, + }, + orig: nil, + newVal: nil, + wantErrOnSet: true, + }, + { + name: `client.auth.attributes`, + path: &pathtest.Path[*TransformContext]{ + N: "client", + NextPath: &pathtest.Path[*TransformContext]{ + N: "auth", + NextPath: &pathtest.Path[*TransformContext]{ + N: "attributes", + }, + }, + }, + orig: pcommon.NewMap(), + newVal: nil, + wantErrOnSet: true, + }, + { + name: `client.auth.attributes["key"]`, + path: &pathtest.Path[*TransformContext]{ + N: "client", + NextPath: &pathtest.Path[*TransformContext]{ + N: "auth", + NextPath: &pathtest.Path[*TransformContext]{ + N: "attributes", + KeySlice: []ottl.Key[*TransformContext]{ + &pathtest.Key[*TransformContext]{ + S: ottltest.Strp("key"), + }, + }, + }, + }, + }, + orig: nil, + newVal: nil, + wantErrOnSet: true, + }, + { + name: `grpc.metadata`, + path: &pathtest.Path[*TransformContext]{ + N: "grpc", + NextPath: &pathtest.Path[*TransformContext]{ + N: "metadata", + }, + }, + orig: pcommon.NewMap(), + newVal: nil, + wantErrOnSet: true, + }, + { + name: `grpc.metadata["key"]`, + path: &pathtest.Path[*TransformContext]{ + N: "grpc", + NextPath: &pathtest.Path[*TransformContext]{ + N: "metadata", + KeySlice: []ottl.Key[*TransformContext]{ + &pathtest.Key[*TransformContext]{ + S: ottltest.Strp("key"), + }, + }, + }, + }, + orig: nil, + newVal: nil, + wantErrOnSet: true, + }, + } + // Copy all tests cases and sets the path.Context value to the generated ones. + // It ensures all exiting field access also work when the path context is set. + for _, tt := range slices.Clone(tests) { + testWithContext := tt + testWithContext.name = "with_path_context:" + tt.name + pathWithContext := *tt.path.(*pathtest.Path[*TransformContext]) + pathWithContext.C = ContextName + testWithContext.path = ottl.Path[*TransformContext](&pathWithContext) + tests = append(tests, testWithContext) + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cacheGetter := func(tCtx *TransformContext) pcommon.Map { + return tCtx.cache + } + accessor, err := pathExpressionParser(cacheGetter)(tt.path) + assert.NoError(t, err) + + tCtx := NewTransformContextPtr() + defer tCtx.Close() + got, err := accessor.Get(t.Context(), tCtx) + assert.NoError(t, err) + assert.Equal(t, tt.orig, got) + + err = accessor.Set(t.Context(), tCtx, tt.newVal) + if tt.wantErrOnSet { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/pkg/ottl/contexts/ottlotelcol/package_test.go b/pkg/ottl/contexts/ottlotelcol/package_test.go new file mode 100644 index 0000000000000..93ebd9e1ef877 --- /dev/null +++ b/pkg/ottl/contexts/ottlotelcol/package_test.go @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package ottlotelcol + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/pkg/ottl/contexts/ottlprofile/README.md b/pkg/ottl/contexts/ottlprofile/README.md index 6d8410db2bc51..b1681e569ad01 100644 --- a/pkg/ottl/contexts/ottlprofile/README.md +++ b/pkg/ottl/contexts/ottlprofile/README.md @@ -10,35 +10,36 @@ In general, the Profile Context supports accessing pdata using the field names f The following paths are supported. -| path | field accessed | type | -|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource | resource of the profile being processed | pcommon.Resource | -| resource.attributes | resource attributes of the profile being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the resource attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| instrumentation_scope | instrumentation scope of the profile being processed | pcommon.InstrumentationScope | -| instrumentation_scope.name | name of the instrumentation scope of the profile being processed | string | -| instrumentation_scope.version | version of the instrumentation scope of the profile being processed | string | -| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | -| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profile.attributes | attributes of the profile being processed | pcommon.Map | -| profile.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profile.sample_type | the sample type of the profile being processed | pprofile.ValueType | -| profile.sample_type.type | the type associated with the `profile.sample_type` | string | -| profile.sample_type.unit | the unit associated with the `profile.sample_type` | string | -| profile.sample | the samples of the profile being processed | pprofile.SampleSlice | -| profile.time_unix_nano | the time in unix nano of the profile being processed | int64 | -| profile.time | the time in `time.Time` of the profile being processed | time.Time | -| profile.duration_unix_nano | the duration in unix nano of the profile being processed | int64 | -| profile.duration | the duration in nanoseconds of the profile being processed | int64 | -| profile.period_type | the period type of the profile being processed | pprofile.ValueType | -| profile.period_type.type | the type associated with the `profile.period_type` | string | -| profile.period_type.unit | the unit associated with the `profile.period_type` | string | -| profile.period | the period of the profile being processed | int64 | -| profile.profile_id | the profile id of the profile being processed | pprofile.ProfileID | -| profile.profile_id.string | a string representation of the profile id | string | -| profile.attribute_indices | the attribute indices of the profile being processed | []int64 | -| profile.dropped_attributes_count | the dropped attributes count of the profile being processed | int64 | -| profile.original_payload_format | the original payload format of the profile being processed | string | -| profile.original_payload | the original payload of the profile being processed | []byte | +| path | field accessed | type | +|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource | resource of the profile being processed | pcommon.Resource | +| resource.attributes | resource attributes of the profile being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the resource attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| instrumentation_scope | instrumentation scope of the profile being processed | pcommon.InstrumentationScope | +| instrumentation_scope.name | name of the instrumentation scope of the profile being processed | string | +| instrumentation_scope.version | version of the instrumentation scope of the profile being processed | string | +| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | +| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| profile.attributes | attributes of the profile being processed | pcommon.Map | +| profile.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| profile.sample_type | the sample type of the profile being processed | pprofile.ValueType | +| profile.sample_type.type | the type associated with the `profile.sample_type` | string | +| profile.sample_type.unit | the unit associated with the `profile.sample_type` | string | +| profile.sample | the samples of the profile being processed | pprofile.SampleSlice | +| profile.time_unix_nano | the time in unix nano of the profile being processed | int64 | +| profile.time | the time in `time.Time` of the profile being processed | time.Time | +| profile.duration_unix_nano | the duration in unix nano of the profile being processed | int64 | +| profile.duration | the duration in nanoseconds of the profile being processed | int64 | +| profile.period_type | the period type of the profile being processed | pprofile.ValueType | +| profile.period_type.type | the type associated with the `profile.period_type` | string | +| profile.period_type.unit | the unit associated with the `profile.period_type` | string | +| profile.period | the period of the profile being processed | int64 | +| profile.profile_id | the profile id of the profile being processed | pprofile.ProfileID | +| profile.profile_id.string | a string representation of the profile id | string | +| profile.attribute_indices | the attribute indices of the profile being processed | []int64 | +| profile.dropped_attributes_count | the dropped attributes count of the profile being processed | int64 | +| profile.original_payload_format | the original payload format of the profile being processed | string | +| profile.original_payload | the original payload of the profile being processed | []byte | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | diff --git a/pkg/ottl/contexts/ottlprofile/profile.go b/pkg/ottl/contexts/ottlprofile/profile.go index 338aa7848e9f5..90270aea7d030 100644 --- a/pkg/ottl/contexts/ottlprofile/profile.go +++ b/pkg/ottl/contexts/ottlprofile/profile.go @@ -16,6 +16,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxprofile" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" @@ -164,6 +165,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxscope.LegacyName, ctxscope.Name, ctxresource.Name, + ctxotelcol.Name, })(p) } } @@ -227,5 +229,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.Name: ctxscope.PathGetSetter[*TransformContext], ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxprofile.Name: ctxprofile.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlprofilesample/README.md b/pkg/ottl/contexts/ottlprofilesample/README.md index c9387a674cc20..3eadcb6849e3a 100644 --- a/pkg/ottl/contexts/ottlprofilesample/README.md +++ b/pkg/ottl/contexts/ottlprofilesample/README.md @@ -10,22 +10,23 @@ In general, the Profile Sample Context supports accessing pdata using the field The following paths are supported. -| path | field accessed | type | -|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource | resource of the profile being processed | pcommon.Resource | -| resource.attributes | resource attributes of the profile being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the resource attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| instrumentation_scope | instrumentation scope of the profile being processed | pcommon.InstrumentationScope | -| instrumentation_scope.name | name of the instrumentation scope of the profile being processed | string | -| instrumentation_scope.version | version of the instrumentation scope of the profile being processed | string | -| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | -| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profilesample.attributes | attributes of the profile being processed | pcommon.Map | -| profilesample.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| profilesample.values | the values of the sample being processed. | []int64 | -| profilesample.link_index | the link index into the ProfilesDictionary of the sample being processed. | int64 | -| profilesample.timestamps_unix_nano | the timestamps in unix nano associated with the sample being processed. | []int64 | -| profilesample.timestamps | the timestamps in `time.Time` associated with the sample being processed. | []time.Time | -| profilesample.attribute_indices | the attribute indices of the sample being processed. | []int64 | +| path | field accessed | type | +|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource | resource of the profile being processed | pcommon.Resource | +| resource.attributes | resource attributes of the profile being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the resource attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| instrumentation_scope | instrumentation scope of the profile being processed | pcommon.InstrumentationScope | +| instrumentation_scope.name | name of the instrumentation scope of the profile being processed | string | +| instrumentation_scope.version | version of the instrumentation scope of the profile being processed | string | +| instrumentation_scope.attributes | instrumentation scope attributes of the data point being processed | pcommon.Map | +| instrumentation_scope.attributes\[""\] | the value of the instrumentation scope attribute of the data point being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| profilesample.attributes | attributes of the profile being processed | pcommon.Map | +| profilesample.attributes\[""\] | the value of the attribute of the profile being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| profilesample.values | the values of the sample being processed. | []int64 | +| profilesample.link_index | the link index into the ProfilesDictionary of the sample being processed. | int64 | +| profilesample.timestamps_unix_nano | the timestamps in unix nano associated with the sample being processed. | []int64 | +| profilesample.timestamps | the timestamps in `time.Time` associated with the sample being processed. | []time.Time | +| profilesample.attribute_indices | the attribute indices of the sample being processed. | []int64 | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | \ No newline at end of file diff --git a/pkg/ottl/contexts/ottlprofilesample/profilesample.go b/pkg/ottl/contexts/ottlprofilesample/profilesample.go index e13cfd82e9e34..c1fcf516cce90 100644 --- a/pkg/ottl/contexts/ottlprofilesample/profilesample.go +++ b/pkg/ottl/contexts/ottlprofilesample/profilesample.go @@ -16,6 +16,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxprofile" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxprofilesample" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" @@ -175,6 +176,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxscope.LegacyName, ctxscope.Name, ctxresource.Name, + ctxotelcol.Name, })(p) } } @@ -239,5 +241,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxprofile.Name: ctxprofile.PathGetSetter[*TransformContext], ctxprofilesample.Name: ctxprofilesample.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlresource/README.md b/pkg/ottl/contexts/ottlresource/README.md index ffc15ccc34656..7e6d70e2b58ef 100644 --- a/pkg/ottl/contexts/ottlresource/README.md +++ b/pkg/ottl/contexts/ottlresource/README.md @@ -10,13 +10,14 @@ In general, the Resource Context supports accessing pdata using the field names The following paths are supported. -| path | field accessed | type | -|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| resource.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| resource.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource.attributes | attributes of the resource being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the attribute of the resource being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource.dropped_attributes_count | number of dropped attributes of the resource being processed | int64 | +| path | field accessed | type | +|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| resource.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| resource.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource.attributes | attributes of the resource being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the attribute of the resource being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource.dropped_attributes_count | number of dropped attributes of the resource being processed | int64 | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottlresource/resource.go b/pkg/ottl/contexts/ottlresource/resource.go index 6cafc6de3ff41..4ce0fc6d7c684 100644 --- a/pkg/ottl/contexts/ottlresource/resource.go +++ b/pkg/ottl/contexts/ottlresource/resource.go @@ -14,6 +14,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" ) @@ -88,7 +89,11 @@ func (tCtx *TransformContext) GetResourceSchemaURLItem() ctxcommon.SchemaURLItem // Experimental: *NOTE* this option is subject to change or removal in the future. func EnablePathContextNames() ottl.Option[*TransformContext] { return func(p *ottl.Parser[*TransformContext]) { - ottl.WithPathContextNames[*TransformContext]([]string{ContextName})(p) + ottl.WithPathContextNames[*TransformContext]([]string{ + ContextName, + ctxotelcol.Name, + }, + )(p) } } @@ -160,5 +165,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P cacheGetter, map[string]ottl.PathExpressionParser[*TransformContext]{ ctxresource.Name: ctxresource.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlscope/README.md b/pkg/ottl/contexts/ottlscope/README.md index fc646e8cf78b7..cd9371892e866 100644 --- a/pkg/ottl/contexts/ottlscope/README.md +++ b/pkg/ottl/contexts/ottlscope/README.md @@ -10,20 +10,20 @@ In general, the Instrumentation Scope Context supports accessing pdata using the The following paths are supported. -| path | field accessed | type | -|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| scope.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | -| scope.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource | resource of the instrumentation scope being processed | pcommon.Resource | -| resource.attributes | resource attributes of the instrumentation scope being processed | pcommon.Map | -| resource.attributes\[""\] | the value of the resource attribute of the instrumentation scope being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | -| resource.dropped_attributes_count | number of dropped attributes of the resource of the instrumentation scope being processed | int64 | -| scope.name | name of the instrumentation scope of the scope being processed | string | -| scope.version | version of the instrumentation scope of the scope being processed | string | -| scope.dropped_attributes_count | number of dropped attributes of the instrumentation scope of the scope being processed | int64 | -| scope.attributes | instrumentation scope attributes of the scope being processed | pcommon.Map | -| scope.attributes\[""\] | the value of the instrumentation scope attribute of the scope being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | - +| path | field accessed | type | +|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| scope.cache | the value of the current transform context's temporary cache. cache can be used as a temporary placeholder for data during complex transformations | pcommon.Map | +| scope.cache\[""\] | the value of an item in cache. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource | resource of the instrumentation scope being processed | pcommon.Resource | +| resource.attributes | resource attributes of the instrumentation scope being processed | pcommon.Map | +| resource.attributes\[""\] | the value of the resource attribute of the instrumentation scope being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| resource.dropped_attributes_count | number of dropped attributes of the resource of the instrumentation scope being processed | int64 | +| scope.name | name of the instrumentation scope of the scope being processed | string | +| scope.version | version of the instrumentation scope of the scope being processed | string | +| scope.dropped_attributes_count | number of dropped attributes of the instrumentation scope of the scope being processed | int64 | +| scope.attributes | instrumentation scope attributes of the scope being processed | pcommon.Map | +| scope.attributes\[""\] | the value of the instrumentation scope attribute of the scope being processed. Supports multiple indexes to access nested fields. | string, bool, int64, float64, pcommon.Map, pcommon.Slice, []byte or nil | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottlscope/scope.go b/pkg/ottl/contexts/ottlscope/scope.go index af9e2286f5a2c..34617f298c1e4 100644 --- a/pkg/ottl/contexts/ottlscope/scope.go +++ b/pkg/ottl/contexts/ottlscope/scope.go @@ -14,6 +14,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/logging" @@ -107,6 +108,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ottl.WithPathContextNames[*TransformContext]([]string{ ContextName, ctxresource.Name, + ctxotelcol.Name, })(p) } } @@ -181,5 +183,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxresource.Name: ctxresource.PathGetSetter[*TransformContext], ctxscope.Name: ctxscope.PathGetSetter[*TransformContext], ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlspan/README.md b/pkg/ottl/contexts/ottlspan/README.md index ba398fc25b853..9b464929584ec 100644 --- a/pkg/ottl/contexts/ottlspan/README.md +++ b/pkg/ottl/contexts/ottlspan/README.md @@ -52,7 +52,8 @@ The following paths are supported. | span.dropped_events_count | the dropped events count of the span | int64 | | span.links | the links of the span | ptrace.SpanLinkSlice | | span.dropped_links_count | the dropped links count of the span | int64 | -| span.flags | the flags of the span being processed | int64 | +| span.flags | the flags of the span being processed | int64 | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottlspan/span.go b/pkg/ottl/contexts/ottlspan/span.go index 1d32cf5327021..299b41a1da4ef 100644 --- a/pkg/ottl/contexts/ottlspan/span.go +++ b/pkg/ottl/contexts/ottlspan/span.go @@ -16,6 +16,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxspan" @@ -114,6 +115,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxresource.Name, ctxscope.LegacyName, ctxscope.Name, + ctxotelcol.Name, })(p) } } @@ -195,5 +197,6 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.Name: ctxscope.PathGetSetter[*TransformContext], ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxspan.Name: ctxspan.PathGetSetter[*TransformContext], + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/contexts/ottlspanevent/README.md b/pkg/ottl/contexts/ottlspanevent/README.md index 4bc19af1010f3..b2e713656ddb3 100644 --- a/pkg/ottl/contexts/ottlspanevent/README.md +++ b/pkg/ottl/contexts/ottlspanevent/README.md @@ -31,6 +31,7 @@ The following paths are supported. | spanevent.name | name of the span event being processed | string | | spanevent.dropped_attributes_count | dropped_attributes_count of the span event being processed | int64 | | spanevent.event_index | index of the span event within the span | int64 | +| otelcol.* | All paths exposed by the [ottlotelcol](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/contexts/ottlotelcol) context. | varies | ## Enums diff --git a/pkg/ottl/contexts/ottlspanevent/span_events.go b/pkg/ottl/contexts/ottlspanevent/span_events.go index 217015365c1b1..2dccda602f626 100644 --- a/pkg/ottl/contexts/ottlspanevent/span_events.go +++ b/pkg/ottl/contexts/ottlspanevent/span_events.go @@ -17,6 +17,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxcommon" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxotelcol" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxresource" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxscope" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/internal/ctxspan" @@ -151,6 +152,7 @@ func EnablePathContextNames() ottl.Option[*TransformContext] { ctxresource.Name, ctxscope.LegacyName, ctxscope.Name, + ctxotelcol.Name, })(p) } } @@ -233,6 +235,7 @@ func pathExpressionParser(cacheGetter ctxcache.Getter[*TransformContext]) ottl.P ctxscope.LegacyName: ctxscope.PathGetSetter[*TransformContext], ctxspan.Name: ctxspan.PathGetSetter[*TransformContext], ctxspanevent.Name: spanEventGetSetterWithIndex, + ctxotelcol.Name: ctxotelcol.PathGetSetter[*TransformContext], }) } diff --git a/pkg/ottl/go.mod b/pkg/ottl/go.mod index 007888b6d9ee1..4776e34aaee89 100644 --- a/pkg/ottl/go.mod +++ b/pkg/ottl/go.mod @@ -17,6 +17,7 @@ require ( github.com/twmb/murmur3 v1.1.8 github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 github.com/zeebo/xxh3 v1.1.0 + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d @@ -27,6 +28,7 @@ require ( go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.1 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 + google.golang.org/grpc v1.79.1 ) require ( diff --git a/pkg/ottl/go.sum b/pkg/ottl/go.sum index 2ce0d1d0bec90..bcdb24ae784e9 100644 --- a/pkg/ottl/go.sum +++ b/pkg/ottl/go.sum @@ -78,10 +78,14 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d h1:VgCLczw4cH0tSj9Jmd5BG047SdUUR6e9snoPAvpSCPA= go.opentelemetry.io/collector/component/componenttest v0.146.2-0.20260227062254-168030d61d7d/go.mod h1:DnviH4iNFbGI7/timy6lu+u+pWRu//N31J5PR+vMyn8= +go.opentelemetry.io/collector/consumer v1.52.1-0.20260227062254-168030d61d7d h1:avxj/edyvAjZ9GBZcvuZQfvtpdDDQKugGy2ICEy0iLc= +go.opentelemetry.io/collector/consumer v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:pb+eeJInUz/rVU0ujJYqzEcOSsvkdNeLg6xpSVRRqUY= go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d h1:F4l81rGyQ253S1QASslOc8ftkAPaatTT+eCZJsuN44U= go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= go.opentelemetry.io/collector/internal/testutil v0.146.1 h1:hpemuw5sLSYIqflJdScFikLhCjHxKuJWC2Lwyh9yeCI= @@ -187,6 +191,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/attributesprocessor/go.mod b/processor/attributesprocessor/go.mod index cf2523a40e66b..0788bf363a663 100644 --- a/processor/attributesprocessor/go.mod +++ b/processor/attributesprocessor/go.mod @@ -79,6 +79,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/attributesprocessor/go.sum b/processor/attributesprocessor/go.sum index d1070c68f2a2f..851b630e562fd 100644 --- a/processor/attributesprocessor/go.sum +++ b/processor/attributesprocessor/go.sum @@ -231,6 +231,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/filterprocessor/go.mod b/processor/filterprocessor/go.mod index 40b806960ac31..8d67b94b17c76 100644 --- a/processor/filterprocessor/go.mod +++ b/processor/filterprocessor/go.mod @@ -69,6 +69,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/internal/componentalias v0.146.2-0.20260227062254-168030d61d7d // indirect @@ -80,6 +81,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/filterprocessor/go.sum b/processor/filterprocessor/go.sum index fcf8571b7c0b9..37aad1d82e895 100644 --- a/processor/filterprocessor/go.sum +++ b/processor/filterprocessor/go.sum @@ -94,6 +94,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -233,6 +235,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/logdedupprocessor/go.mod b/processor/logdedupprocessor/go.mod index 3f660db5fb436..c82287523ad2d 100644 --- a/processor/logdedupprocessor/go.mod +++ b/processor/logdedupprocessor/go.mod @@ -63,6 +63,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect @@ -80,6 +81,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/processor/logdedupprocessor/go.sum b/processor/logdedupprocessor/go.sum index 5cda6fe241496..dd525519a758b 100644 --- a/processor/logdedupprocessor/go.sum +++ b/processor/logdedupprocessor/go.sum @@ -92,6 +92,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -223,6 +225,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/lookupprocessor/go.mod b/processor/lookupprocessor/go.mod index b5bdb60e1f7d5..55048f0eaff91 100644 --- a/processor/lookupprocessor/go.mod +++ b/processor/lookupprocessor/go.mod @@ -53,6 +53,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect @@ -72,6 +73,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/processor/lookupprocessor/go.sum b/processor/lookupprocessor/go.sum index c6a07932b3ec2..5ea286dddf1d2 100644 --- a/processor/lookupprocessor/go.sum +++ b/processor/lookupprocessor/go.sum @@ -90,6 +90,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -221,6 +223,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/spanprocessor/go.mod b/processor/spanprocessor/go.mod index 0c5dc65184cbd..37e2f521e6de2 100644 --- a/processor/spanprocessor/go.mod +++ b/processor/spanprocessor/go.mod @@ -57,6 +57,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/featuregate v1.52.1-0.20260227062254-168030d61d7d // indirect @@ -77,6 +78,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/spanprocessor/go.sum b/processor/spanprocessor/go.sum index 1667101b86353..11b614eeeca3e 100644 --- a/processor/spanprocessor/go.sum +++ b/processor/spanprocessor/go.sum @@ -92,6 +92,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -227,6 +229,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/tailsamplingprocessor/go.mod b/processor/tailsamplingprocessor/go.mod index 4dd9dc5215911..e2ce8cb0e199a 100644 --- a/processor/tailsamplingprocessor/go.mod +++ b/processor/tailsamplingprocessor/go.mod @@ -62,6 +62,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/consumer/xconsumer v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/internal/componentalias v0.146.2-0.20260227062254-168030d61d7d // indirect @@ -76,6 +77,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/tailsamplingprocessor/go.sum b/processor/tailsamplingprocessor/go.sum index 62bb45eeed13b..f113ab7d4d71a 100644 --- a/processor/tailsamplingprocessor/go.sum +++ b/processor/tailsamplingprocessor/go.sum @@ -92,6 +92,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -225,6 +227,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/processor/transformprocessor/go.mod b/processor/transformprocessor/go.mod index f972e445eb8b0..09d164c3f22fa 100644 --- a/processor/transformprocessor/go.mod +++ b/processor/transformprocessor/go.mod @@ -73,6 +73,7 @@ require ( github.com/ua-parser/uap-go v0.0.0-20240611065828-3a4781585db6 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/internal/componentalias v0.146.2-0.20260227062254-168030d61d7d // indirect go.opentelemetry.io/collector/pdata/testdata v0.146.2-0.20260227062254-168030d61d7d // indirect @@ -84,6 +85,7 @@ require ( golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.34.0 // indirect + google.golang.org/grpc v1.79.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/transformprocessor/go.sum b/processor/transformprocessor/go.sum index fd7929a7d649d..1298b01326f0e 100644 --- a/processor/transformprocessor/go.sum +++ b/processor/transformprocessor/go.sum @@ -94,6 +94,8 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d h1:6DFq2fMRlgALRLAzxQedB+io/3bsKZB0SpdpKAvaIxY= +go.opentelemetry.io/collector/client v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:0FcZ0RZS4IFkhfzLyqQhKV3a/L1c/WwTQ3bHDILsQ1Q= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d h1:BqAqyUXtjzAeiWngZQjzrZTCf0MEg2k5KAls0V4rgOQ= go.opentelemetry.io/collector/component v1.52.1-0.20260227062254-168030d61d7d/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78= go.opentelemetry.io/collector/component/componentstatus v0.146.2-0.20260227062254-168030d61d7d h1:GoJhnG3SyfhDgmqgNnJX5BvbssK7v1sOG/635YX4sIc= @@ -231,6 +233,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=