diff --git a/.chloggen/6599-resource-attributes.yaml b/.chloggen/6599-resource-attributes.yaml new file mode 100755 index 00000000000..a4222f42b93 --- /dev/null +++ b/.chloggen/6599-resource-attributes.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: service + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Adds ResourceAttributes map to telemetry settings and thus CreateSettings. + +# One or more tracking issues or pull requests related to the change +issues: [6599] + +# (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: diff --git a/component/componenttest/nop_telemetry.go b/component/componenttest/nop_telemetry.go index a20ee342058..9cd83a1de85 100644 --- a/component/componenttest/nop_telemetry.go +++ b/component/componenttest/nop_telemetry.go @@ -21,6 +21,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" + "go.opentelemetry.io/collector/pdata/pcommon" ) // NewNopTelemetrySettings returns a new nop telemetry settings for Create* functions. @@ -30,5 +31,6 @@ func NewNopTelemetrySettings() component.TelemetrySettings { TracerProvider: trace.NewNoopTracerProvider(), MeterProvider: noop.NewMeterProvider(), MetricsLevel: configtelemetry.LevelNone, + Resource: pcommon.NewResource(), } } diff --git a/component/componenttest/nop_telemetry_test.go b/component/componenttest/nop_telemetry_test.go index be03822f404..e50b442169b 100644 --- a/component/componenttest/nop_telemetry_test.go +++ b/component/componenttest/nop_telemetry_test.go @@ -34,4 +34,5 @@ func TestNewNopTelemetrySettings(t *testing.T) { nts.MeterProvider.Meter("test") }) assert.Equal(t, configtelemetry.LevelNone, nts.MetricsLevel) + assert.Equal(t, nts.Resource.Attributes().Len(), 0) } diff --git a/component/go.mod b/component/go.mod index 3897753dff5..8ebbfde4395 100644 --- a/component/go.mod +++ b/component/go.mod @@ -6,6 +6,7 @@ require ( github.com/stretchr/testify v1.8.2 go.opentelemetry.io/collector v0.76.1 go.opentelemetry.io/collector/confmap v0.76.1 + go.opentelemetry.io/collector/pdata v1.0.0-rcv0011 go.opentelemetry.io/otel/metric v0.38.1 go.opentelemetry.io/otel/trace v1.15.1 go.uber.org/multierr v1.11.0 @@ -14,6 +15,8 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/knadh/koanf v1.5.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -22,6 +25,12 @@ require ( go.opentelemetry.io/collector/featuregate v0.76.1 // indirect go.opentelemetry.io/otel v1.15.1 // indirect go.uber.org/atomic v1.10.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.54.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/component/go.sum b/component/go.sum index df347d15b3f..330e78ff465 100644 --- a/component/go.sum +++ b/component/go.sum @@ -61,6 +61,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -78,6 +79,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -294,6 +297,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -337,6 +342,7 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -344,6 +350,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -368,6 +376,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -376,6 +386,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -387,6 +399,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/component/telemetry.go b/component/telemetry.go index 22d5557fd77..b45a4242545 100644 --- a/component/telemetry.go +++ b/component/telemetry.go @@ -20,6 +20,7 @@ import ( "go.uber.org/zap" "go.opentelemetry.io/collector/config/configtelemetry" + "go.opentelemetry.io/collector/pdata/pcommon" ) type TelemetrySettings struct { @@ -36,4 +37,7 @@ type TelemetrySettings struct { // MetricsLevel controls the level of detail for metrics emitted by the collector. // Experimental: *NOTE* this field is experimental and may be changed or removed. MetricsLevel configtelemetry.Level + + // Resource contains the resource attributes for the collector's telemetry. + Resource pcommon.Resource } diff --git a/extension/ballastextension/go.mod b/extension/ballastextension/go.mod index d35faf835e9..68400cc8e79 100644 --- a/extension/ballastextension/go.mod +++ b/extension/ballastextension/go.mod @@ -13,6 +13,8 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/knadh/koanf v1.5.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -25,12 +27,18 @@ require ( github.com/tklauser/numcpus v0.6.0 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opentelemetry.io/collector/featuregate v0.76.1 // indirect + go.opentelemetry.io/collector/pdata v1.0.0-rcv0011 // indirect go.opentelemetry.io/otel v1.15.1 // indirect go.opentelemetry.io/otel/metric v0.38.1 // indirect go.opentelemetry.io/otel/trace v1.15.1 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect + golang.org/x/net v0.9.0 // indirect golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.54.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/extension/ballastextension/go.sum b/extension/ballastextension/go.sum index ec50469b190..79ef27a0067 100644 --- a/extension/ballastextension/go.sum +++ b/extension/ballastextension/go.sum @@ -63,6 +63,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -80,6 +81,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -311,6 +314,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -366,6 +371,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -390,6 +397,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -398,6 +407,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -409,6 +420,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/extension/extension_test.go b/extension/extension_test.go index fadb421cd40..01bb1bd27ee 100644 --- a/extension/extension_test.go +++ b/extension/extension_test.go @@ -28,6 +28,7 @@ import ( type nopExtension struct { component.StartFunc component.ShutdownFunc + CreateSettings } func TestNewFactory(t *testing.T) { @@ -91,7 +92,6 @@ func TestMakeFactoryMap(t *testing.T) { func TestBuilder(t *testing.T) { const typeStr = "test" defaultCfg := struct{}{} - nopExtensionInstance := new(nopExtension) testID := component.NewID(typeStr) unknownID := component.NewID("unknown") @@ -100,7 +100,7 @@ func TestBuilder(t *testing.T) { typeStr, func() component.Config { return &defaultCfg }, func(ctx context.Context, settings CreateSettings, extension component.Config) (Extension, error) { - return nopExtensionInstance, nil + return nopExtension{CreateSettings: settings}, nil }, component.StabilityLevelDevelopment), }...) @@ -113,6 +113,11 @@ func TestBuilder(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, e) + // Check that the extension has access to the resource attributes. + nop, ok := e.(nopExtension) + assert.True(t, ok) + assert.Equal(t, nop.CreateSettings.Resource.Attributes().Len(), 0) + missingType, err := b.Create(context.Background(), createSettings(unknownID)) assert.EqualError(t, err, "extension factory not available for: \"unknown\"") assert.Nil(t, missingType) diff --git a/extension/zpagesextension/go.mod b/extension/zpagesextension/go.mod index 747530b8ff5..cdc800ffb16 100644 --- a/extension/zpagesextension/go.mod +++ b/extension/zpagesextension/go.mod @@ -17,17 +17,25 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/knadh/koanf v1.5.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/collector/featuregate v0.76.1 // indirect + go.opentelemetry.io/collector/pdata v1.0.0-rcv0011 // indirect go.opentelemetry.io/otel v1.15.1 // indirect go.opentelemetry.io/otel/metric v0.38.1 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect + golang.org/x/net v0.9.0 // indirect golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.54.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/extension/zpagesextension/go.sum b/extension/zpagesextension/go.sum index 0444eadf77f..014e2d9be71 100644 --- a/extension/zpagesextension/go.sum +++ b/extension/zpagesextension/go.sum @@ -64,6 +64,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -81,6 +82,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -301,6 +304,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -352,6 +357,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -376,6 +383,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -384,6 +393,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -395,6 +406,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/service/service.go b/service/service.go index 31f21c690ea..d28bba03a06 100644 --- a/service/service.go +++ b/service/service.go @@ -19,7 +19,10 @@ import ( "fmt" "runtime" + "github.com/google/uuid" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/sdk/resource" "go.uber.org/multierr" "go.uber.org/zap" @@ -29,8 +32,10 @@ import ( "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" "go.opentelemetry.io/collector/internal/obsreportconfig" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" + semconv "go.opentelemetry.io/collector/semconv/v1.18.0" "go.opentelemetry.io/collector/service/extensions" "go.opentelemetry.io/collector/service/internal/graph" "go.opentelemetry.io/collector/service/internal/proctelemetry" @@ -100,14 +105,20 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) { if err != nil { return nil, fmt.Errorf("failed to get logger: %w", err) } + res := buildResource(set.BuildInfo, cfg.Telemetry) + pcommonRes := pdataFromSdk(res) + srv.telemetrySettings = component.TelemetrySettings{ Logger: srv.telemetry.Logger(), TracerProvider: srv.telemetry.TracerProvider(), MeterProvider: noop.NewMeterProvider(), MetricsLevel: cfg.Telemetry.Metrics.Level, + + // Construct telemetry attributes from build info and config's resource attributes. + Resource: pcommonRes, } - if err = srv.telemetryInitializer.init(set.BuildInfo, srv.telemetrySettings.Logger, cfg.Telemetry, set.AsyncErrorChannel); err != nil { + if err = srv.telemetryInitializer.init(res, srv.telemetrySettings, cfg.Telemetry, set.AsyncErrorChannel); err != nil { return nil, fmt.Errorf("failed to initialize telemetry: %w", err) } srv.telemetrySettings.MeterProvider = srv.telemetryInitializer.mp @@ -237,3 +248,44 @@ func getBallastSize(host component.Host) uint64 { } return 0 } + +func buildResource(buildInfo component.BuildInfo, cfg telemetry.Config) *resource.Resource { + var telAttrs []attribute.KeyValue + + for k, v := range cfg.Resource { + // nil value indicates that the attribute should not be included in the telemetry. + if v != nil { + telAttrs = append(telAttrs, attribute.String(k, *v)) + } + } + + if _, ok := cfg.Resource[semconv.AttributeServiceName]; !ok { + // AttributeServiceName is not specified in the config. Use the default service name. + telAttrs = append(telAttrs, attribute.String(semconv.AttributeServiceName, buildInfo.Command)) + } + + if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok { + // AttributeServiceInstanceID is not specified in the config. Auto-generate one. + instanceUUID, _ := uuid.NewRandom() + instanceID := instanceUUID.String() + telAttrs = append(telAttrs, attribute.String(semconv.AttributeServiceInstanceID, instanceID)) + } + + if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok { + // AttributeServiceVersion is not specified in the config. Use the actual + // build version. + telAttrs = append(telAttrs, attribute.String(semconv.AttributeServiceVersion, buildInfo.Version)) + } + return resource.NewWithAttributes(semconv.SchemaURL, telAttrs...) +} + +func pdataFromSdk(res *resource.Resource) pcommon.Resource { + // pcommon.NewResource is the best way to generate a new resource currently and is safe to use outside of tests. + // Because the resource is signal agnostic, and we need a net new resource, not an existing one, this is the only + // method of creating it without exposing internal packages. + pcommonRes := pcommon.NewResource() + for _, keyValue := range res.Attributes() { + pcommonRes.Attributes().PutStr(string(keyValue.Key), keyValue.Value.AsString()) + } + return pcommonRes +} diff --git a/service/service_test.go b/service/service_test.go index a68b734a638..be59ab20963 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -38,6 +38,7 @@ import ( "go.opentelemetry.io/collector/extension/extensiontest" "go.opentelemetry.io/collector/extension/zpagesextension" "go.opentelemetry.io/collector/internal/testutil" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor/processortest" "go.opentelemetry.io/collector/receiver/receivertest" "go.opentelemetry.io/collector/service/telemetry" @@ -65,8 +66,18 @@ type ownMetricsTestCase struct { var testResourceAttrValue = "resource_attr_test_value" var testInstanceID = "test_instance_id" var testServiceVersion = "2022-05-20" +var testServiceName = "test name" + +// prometheusToOtelConv is used to check that the expected resource labels exist as +// part of the otel resource attributes. +var prometheusToOtelConv = map[string]string{ + "service_instance_id": "service.instance.id", + "service_name": "service.name", + "service_version": "service.version", +} const metricsVersion = "test version" +const otelCommand = "otelcoltest" func ownMetricsTestCases() []ownMetricsTestCase { return []ownMetricsTestCase{{ @@ -80,6 +91,7 @@ func ownMetricsTestCases() []ownMetricsTestCase { // monitor the Collector in production deployments. expectedLabels: map[string]labelValue{ "service_instance_id": {state: labelAnyValue}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {label: metricsVersion, state: labelSpecificValue}, }, }, @@ -90,10 +102,33 @@ func ownMetricsTestCases() []ownMetricsTestCase { }, expectedLabels: map[string]labelValue{ "service_instance_id": {state: labelAnyValue}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {label: metricsVersion, state: labelSpecificValue}, "custom_resource_attr": {label: "resource_attr_test_value", state: labelSpecificValue}, }, }, + { + name: "override service.name", + userDefinedResource: map[string]*string{ + "service.name": &testServiceName, + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_name": {label: testServiceName, state: labelSpecificValue}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + }, + }, + { + name: "suppress service.name", + userDefinedResource: map[string]*string{ + "service.name": nil, + }, + expectedLabels: map[string]labelValue{ + "service_instance_id": {state: labelAnyValue}, + "service_name": {state: labelNotPresent}, + "service_version": {label: metricsVersion, state: labelSpecificValue}, + }, + }, { name: "override service.instance.id", userDefinedResource: map[string]*string{ @@ -101,6 +136,7 @@ func ownMetricsTestCases() []ownMetricsTestCase { }, expectedLabels: map[string]labelValue{ "service_instance_id": {label: "test_instance_id", state: labelSpecificValue}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {label: metricsVersion, state: labelSpecificValue}, }, }, @@ -111,6 +147,7 @@ func ownMetricsTestCases() []ownMetricsTestCase { }, expectedLabels: map[string]labelValue{ "service_instance_id": {state: labelNotPresent}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {label: metricsVersion, state: labelSpecificValue}, }, }, @@ -121,6 +158,7 @@ func ownMetricsTestCases() []ownMetricsTestCase { }, expectedLabels: map[string]labelValue{ "service_instance_id": {state: labelAnyValue}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {label: "2022-05-20", state: labelSpecificValue}, }, }, @@ -131,6 +169,7 @@ func ownMetricsTestCases() []ownMetricsTestCase { }, expectedLabels: map[string]labelValue{ "service_instance_id": {state: labelAnyValue}, + "service_name": {label: otelCommand, state: labelSpecificValue}, "service_version": {state: labelNotPresent}, }, }} @@ -244,7 +283,7 @@ func testCollectorStartHelper(t *testing.T, useOtel bool, tc ownMetricsTestCase) zpagesAddr := testutil.GetAvailableLocalAddress(t) set := newNopSettings() - set.BuildInfo = component.BuildInfo{Version: "test version"} + set.BuildInfo = component.BuildInfo{Version: "test version", Command: otelCommand} set.Extensions = extension.NewBuilder( map[component.ID]component.Config{component.NewID("zpages"): &zpagesextension.Config{TCPAddr: confignet.TCPAddr{Endpoint: zpagesAddr}}}, map[component.Type]extension.Factory{"zpages": zpagesextension.NewFactory()}) @@ -269,6 +308,8 @@ func testCollectorStartHelper(t *testing.T, useOtel bool, tc ownMetricsTestCase) // Sleep for 1 second to ensure the http server is started. time.Sleep(1 * time.Second) assert.True(t, loggingHookCalled) + + assertResourceLabels(t, srv.telemetrySettings.Resource, tc.expectedLabels) if !useOtel { assertMetrics(t, metricsAddr, tc.expectedLabels) } @@ -317,6 +358,24 @@ func TestServiceTelemetryRestart(t *testing.T) { require.NoError(t, srvTwo.Shutdown(context.Background())) } +func assertResourceLabels(t *testing.T, res pcommon.Resource, expectedLabels map[string]labelValue) { + for key, labelValue := range expectedLabels { + lookupKey, ok := prometheusToOtelConv[key] + if !ok { + lookupKey = key + } + value, ok := res.Attributes().Get(lookupKey) + switch labelValue.state { + case labelNotPresent: + assert.False(t, ok) + case labelAnyValue: + assert.True(t, ok) + default: + assert.Equal(t, labelValue.label, value.AsString()) + } + } +} + func assertMetrics(t *testing.T, metricsAddr string, expectedLabels map[string]labelValue) { client := &http.Client{} resp, err := client.Get("http://" + metricsAddr + "/metrics") diff --git a/service/telemetry.go b/service/telemetry.go index 13dcda5a551..98149ea0ff1 100644 --- a/service/telemetry.go +++ b/service/telemetry.go @@ -15,7 +15,6 @@ package service // import "go.opentelemetry.io/collector/service" import ( - "context" "errors" "fmt" "net/http" @@ -23,7 +22,6 @@ import ( "unicode" ocprom "contrib.go.opencensus.io/exporter/prometheus" - "github.com/google/uuid" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ocmetric "go.opencensus.io/metric" @@ -102,9 +100,9 @@ func newColTelemetry(useOtel bool, disableHighCardinality bool) *telemetryInitia } } -func (tel *telemetryInitializer) init(buildInfo component.BuildInfo, logger *zap.Logger, cfg telemetry.Config, asyncErrorChannel chan error) error { +func (tel *telemetryInitializer) init(res *resource.Resource, settings component.TelemetrySettings, cfg telemetry.Config, asyncErrorChannel chan error) error { if cfg.Metrics.Level == configtelemetry.LevelNone || cfg.Metrics.Address == "" { - logger.Info( + settings.Logger.Info( "Skipping telemetry setup.", zap.String(zapKeyTelemetryAddress, cfg.Metrics.Address), zap.String(zapKeyTelemetryLevel, cfg.Metrics.Level.String()), @@ -112,10 +110,7 @@ func (tel *telemetryInitializer) init(buildInfo component.BuildInfo, logger *zap return nil } - logger.Info("Setting up own telemetry...") - - // Construct telemetry attributes from build info and config's resource attributes. - telAttrs := buildTelAttrs(buildInfo, cfg) + settings.Logger.Info("Setting up own telemetry...") if tp, err := textMapPropagatorFromConfig(cfg.Traces.Propagators); err == nil { otel.SetTextMapPropagator(tp) @@ -123,48 +118,17 @@ func (tel *telemetryInitializer) init(buildInfo component.BuildInfo, logger *zap return err } - return tel.initPrometheus(logger, cfg.Metrics.Address, cfg.Metrics.Level, telAttrs, asyncErrorChannel) -} - -func buildTelAttrs(buildInfo component.BuildInfo, cfg telemetry.Config) map[string]string { - telAttrs := map[string]string{} - - for k, v := range cfg.Resource { - // nil value indicates that the attribute should not be included in the telemetry. - if v != nil { - telAttrs[k] = *v - } - } - - if _, ok := cfg.Resource[semconv.AttributeServiceName]; !ok { - // AttributeServiceName is not specified in the config. Use the default service name. - telAttrs[semconv.AttributeServiceName] = buildInfo.Command - } - - if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok { - // AttributeServiceInstanceID is not specified in the config. Auto-generate one. - instanceUUID, _ := uuid.NewRandom() - instanceID := instanceUUID.String() - telAttrs[semconv.AttributeServiceInstanceID] = instanceID - } - - if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok { - // AttributeServiceVersion is not specified in the config. Use the actual - // build version. - telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version - } - - return telAttrs + return tel.initPrometheus(res, settings.Logger, cfg.Metrics.Address, cfg.Metrics.Level, asyncErrorChannel) } -func (tel *telemetryInitializer) initPrometheus(logger *zap.Logger, address string, level configtelemetry.Level, telAttrs map[string]string, asyncErrorChannel chan error) error { +func (tel *telemetryInitializer) initPrometheus(res *resource.Resource, logger *zap.Logger, address string, level configtelemetry.Level, asyncErrorChannel chan error) error { promRegistry := prometheus.NewRegistry() if tel.useOtel { - if err := tel.initOpenTelemetry(telAttrs, promRegistry); err != nil { + if err := tel.initOpenTelemetry(res, promRegistry); err != nil { return err } } else { - if err := tel.initOpenCensus(level, telAttrs, promRegistry); err != nil { + if err := tel.initOpenCensus(level, res, promRegistry); err != nil { return err } } @@ -190,7 +154,7 @@ func (tel *telemetryInitializer) initPrometheus(logger *zap.Logger, address stri return nil } -func (tel *telemetryInitializer) initOpenCensus(level configtelemetry.Level, telAttrs map[string]string, promRegistry *prometheus.Registry) error { +func (tel *telemetryInitializer) initOpenCensus(level configtelemetry.Level, res *resource.Resource, promRegistry *prometheus.Registry) error { tel.ocRegistry = ocmetric.NewRegistry() metricproducer.GlobalManager().AddProducer(tel.ocRegistry) @@ -206,9 +170,8 @@ func (tel *telemetryInitializer) initOpenCensus(level configtelemetry.Level, tel } opts.ConstLabels = make(map[string]string) - - for k, v := range telAttrs { - opts.ConstLabels[sanitizePrometheusKey(k)] = v + for _, keyValue := range res.Attributes() { + opts.ConstLabels[sanitizePrometheusKey(string(keyValue.Key))] = keyValue.Value.AsString() } pe, err := ocprom.NewExporter(opts) @@ -220,21 +183,11 @@ func (tel *telemetryInitializer) initOpenCensus(level configtelemetry.Level, tel return nil } -func (tel *telemetryInitializer) initOpenTelemetry(attrs map[string]string, promRegistry *prometheus.Registry) error { +func (tel *telemetryInitializer) initOpenTelemetry(res *resource.Resource, promRegistry *prometheus.Registry) error { // Initialize the ocRegistry, still used by the process metrics. tel.ocRegistry = ocmetric.NewRegistry() metricproducer.GlobalManager().AddProducer(tel.ocRegistry) - var resAttrs []attribute.KeyValue - for k, v := range attrs { - resAttrs = append(resAttrs, attribute.String(k, v)) - } - - res, err := resource.New(context.Background(), resource.WithAttributes(resAttrs...)) - if err != nil { - return fmt.Errorf("error creating otel resources: %w", err) - } - wrappedRegisterer := prometheus.WrapRegistererWithPrefix("otelcol_", promRegistry) // We can remove `otelprom.WithoutUnits()` when the otel-go start exposing prometheus metrics using the OpenMetrics format // which includes metric units that prometheusreceiver uses to trim unit's suffixes from metric names. @@ -247,6 +200,7 @@ func (tel *telemetryInitializer) initOpenTelemetry(attrs map[string]string, prom if err != nil { return fmt.Errorf("error creating otel prometheus exporter: %w", err) } + exporter.RegisterProducer(opencensus.NewMetricProducer()) views := batchViews() if tel.disableHighCardinality { diff --git a/service/telemetry_test.go b/service/telemetry_test.go index 7c7670748cd..e84313993df 100644 --- a/service/telemetry_test.go +++ b/service/telemetry_test.go @@ -45,19 +45,24 @@ const ( counterName = "test_counter" ) -func TestBuildTelAttrs(t *testing.T) { +func TestBuildResource(t *testing.T) { buildInfo := component.NewDefaultBuildInfo() // Check default config cfg := telemetry.Config{} - telAttrs := buildTelAttrs(buildInfo, cfg) + otelRes := buildResource(buildInfo, cfg) + res := pdataFromSdk(otelRes) - assert.Len(t, telAttrs, 3) - assert.Equal(t, buildInfo.Command, telAttrs[semconv.AttributeServiceName]) - assert.Equal(t, buildInfo.Version, telAttrs[semconv.AttributeServiceVersion]) + assert.Equal(t, res.Attributes().Len(), 3) + value, ok := res.Attributes().Get(semconv.AttributeServiceName) + assert.True(t, ok) + assert.Equal(t, buildInfo.Command, value.AsString()) + value, ok = res.Attributes().Get(semconv.AttributeServiceVersion) + assert.True(t, ok) + assert.Equal(t, buildInfo.Version, value.AsString()) - _, exists := telAttrs[semconv.AttributeServiceInstanceID] - assert.True(t, exists) + _, ok = res.Attributes().Get(semconv.AttributeServiceInstanceID) + assert.True(t, ok) // Check override by nil cfg = telemetry.Config{ @@ -67,10 +72,11 @@ func TestBuildTelAttrs(t *testing.T) { semconv.AttributeServiceInstanceID: nil, }, } - telAttrs = buildTelAttrs(buildInfo, cfg) + otelRes = buildResource(buildInfo, cfg) + res = pdataFromSdk(otelRes) // Attributes should not exist since we nil-ified all. - assert.Len(t, telAttrs, 0) + assert.Equal(t, res.Attributes().Len(), 0) // Check override values strPtr := func(v string) *string { return &v } @@ -81,12 +87,19 @@ func TestBuildTelAttrs(t *testing.T) { semconv.AttributeServiceInstanceID: strPtr("c"), }, } - telAttrs = buildTelAttrs(buildInfo, cfg) - - assert.Len(t, telAttrs, 3) - assert.Equal(t, "a", telAttrs[semconv.AttributeServiceName]) - assert.Equal(t, "b", telAttrs[semconv.AttributeServiceVersion]) - assert.Equal(t, "c", telAttrs[semconv.AttributeServiceInstanceID]) + otelRes = buildResource(buildInfo, cfg) + res = pdataFromSdk(otelRes) + + assert.Equal(t, res.Attributes().Len(), 3) + value, ok = res.Attributes().Get(semconv.AttributeServiceName) + assert.True(t, ok) + assert.Equal(t, "a", value.AsString()) + value, ok = res.Attributes().Get(semconv.AttributeServiceVersion) + assert.True(t, ok) + assert.Equal(t, "b", value.AsString()) + value, ok = res.Attributes().Get(semconv.AttributeServiceInstanceID) + assert.True(t, ok) + assert.Equal(t, "c", value.AsString()) } func TestTelemetryInit(t *testing.T) { @@ -196,8 +209,13 @@ func TestTelemetryInit(t *testing.T) { Address: testutil.GetAvailableLocalAddress(t), }, } - - err := tel.init(buildInfo, zap.NewNop(), cfg, make(chan error)) + otelRes := buildResource(buildInfo, cfg) + res := pdataFromSdk(otelRes) + settings := component.TelemetrySettings{ + Logger: zap.NewNop(), + Resource: res, + } + err := tel.init(otelRes, settings, cfg, make(chan error)) require.NoError(t, err) defer func() { require.NoError(t, tel.shutdown())