diff --git a/.chloggen/codeboten_update-config-dependency.yaml b/.chloggen/codeboten_update-config-dependency.yaml new file mode 100644 index 00000000000..96c42b8d6cd --- /dev/null +++ b/.chloggen/codeboten_update-config-dependency.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: service + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: remove custom code and instead use config package to instantiate meter provider. + +# One or more tracking issues or pull requests related to the change +issues: [11611] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/cmd/otelcorecol/go.mod b/cmd/otelcorecol/go.mod index 1bffa80864b..4b19ce41b9d 100644 --- a/cmd/otelcorecol/go.mod +++ b/cmd/otelcorecol/go.mod @@ -49,7 +49,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -121,7 +121,7 @@ require ( go.opentelemetry.io/collector/semconv v0.113.0 // indirect go.opentelemetry.io/collector/service v0.113.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 // indirect - go.opentelemetry.io/contrib/config v0.10.0 // indirect + go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.31.0 // indirect @@ -150,8 +150,8 @@ require ( golang.org/x/net v0.30.0 // indirect golang.org/x/text v0.19.0 // indirect gonum.org/v1/gonum v0.15.1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/cmd/otelcorecol/go.sum b/cmd/otelcorecol/go.sum index b692d59aad7..bc1080397fb 100644 --- a/cmd/otelcorecol/go.sum +++ b/cmd/otelcorecol/go.sum @@ -33,8 +33,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -111,8 +111,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 h1:j8icMXyyqNf6HGuwlYhniPnVsbJIq7n+WirDu3VAJdQ= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0/go.mod h1:evIOZpl+kAlU5IsaYX2Siw+IbpacAZvXemVsgt70uvw= -go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c= -go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 h1:rQWXkXrPMz35C3yNXpLIdwGJ7FQ+956isvltZ5w0Ow4= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642/go.mod h1:5mhiZrDtaZNxGVkF4Ez8eC9wVgmkptLag+g9MUPQFHI= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= @@ -202,10 +202,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/internal/e2e/go.mod b/internal/e2e/go.mod index 1393fe0659b..0e726eba77e 100644 --- a/internal/e2e/go.mod +++ b/internal/e2e/go.mod @@ -50,7 +50,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect @@ -100,7 +100,7 @@ require ( go.opentelemetry.io/collector/receiver/receiverprofiles v0.113.0 // indirect go.opentelemetry.io/collector/semconv v0.113.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 // indirect - go.opentelemetry.io/contrib/config v0.10.0 // indirect + go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.31.0 // indirect @@ -127,8 +127,8 @@ require ( golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect gonum.org/v1/gonum v0.15.1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/internal/e2e/go.sum b/internal/e2e/go.sum index 540202ea2cc..a26dce311df 100644 --- a/internal/e2e/go.sum +++ b/internal/e2e/go.sum @@ -32,8 +32,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -103,8 +103,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 h1:j8icMXyyqNf6HGuwlYhniPnVsbJIq7n+WirDu3VAJdQ= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0/go.mod h1:evIOZpl+kAlU5IsaYX2Siw+IbpacAZvXemVsgt70uvw= -go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c= -go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 h1:rQWXkXrPMz35C3yNXpLIdwGJ7FQ+956isvltZ5w0Ow4= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642/go.mod h1:5mhiZrDtaZNxGVkF4Ez8eC9wVgmkptLag+g9MUPQFHI= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= @@ -194,10 +194,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/otelcol/config_test.go b/otelcol/config_test.go index e0455330bda..ff6c02c3b64 100644 --- a/otelcol/config_test.go +++ b/otelcol/config_test.go @@ -279,7 +279,7 @@ func generateConfig() *Config { Level: configtelemetry.LevelNormal, Readers: []config.MetricReader{ { - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{ Prometheus: &config.Prometheus{ Host: newPtr("localhost"), Port: newPtr(8080), diff --git a/otelcol/go.mod b/otelcol/go.mod index 290430da9f0..90d7655e8cc 100644 --- a/otelcol/go.mod +++ b/otelcol/go.mod @@ -21,7 +21,7 @@ require ( go.opentelemetry.io/collector/receiver v0.113.0 go.opentelemetry.io/collector/receiver/receivertest v0.113.0 go.opentelemetry.io/collector/service v0.113.0 - go.opentelemetry.io/contrib/config v0.10.0 + go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 @@ -43,7 +43,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -106,8 +106,8 @@ require ( golang.org/x/net v0.30.0 // indirect golang.org/x/text v0.19.0 // indirect gonum.org/v1/gonum v0.15.1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/protobuf v1.35.1 // indirect ) diff --git a/otelcol/go.sum b/otelcol/go.sum index 1828a5dc585..a988f001973 100644 --- a/otelcol/go.sum +++ b/otelcol/go.sum @@ -33,8 +33,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -109,8 +109,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 h1:j8icMXyyqNf6HGuwlYhniPnVsbJIq7n+WirDu3VAJdQ= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0/go.mod h1:evIOZpl+kAlU5IsaYX2Siw+IbpacAZvXemVsgt70uvw= -go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c= -go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 h1:rQWXkXrPMz35C3yNXpLIdwGJ7FQ+956isvltZ5w0Ow4= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642/go.mod h1:5mhiZrDtaZNxGVkF4Ez8eC9wVgmkptLag+g9MUPQFHI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/propagators/b3 v1.31.0 h1:PQPXYscmwbCp76QDvO4hMngF2j8Bx/OTV86laEl8uqo= @@ -198,10 +198,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/otelcol/otelcoltest/go.mod b/otelcol/otelcoltest/go.mod index d5cc098985b..d869b179e05 100644 --- a/otelcol/otelcoltest/go.mod +++ b/otelcol/otelcoltest/go.mod @@ -37,7 +37,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -82,7 +82,7 @@ require ( go.opentelemetry.io/collector/receiver/receiverprofiles v0.113.0 // indirect go.opentelemetry.io/collector/semconv v0.113.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 // indirect - go.opentelemetry.io/contrib/config v0.10.0 // indirect + go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.31.0 // indirect go.opentelemetry.io/otel v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.7.0 // indirect @@ -109,8 +109,8 @@ require ( golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect gonum.org/v1/gonum v0.15.1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/otelcol/otelcoltest/go.sum b/otelcol/otelcoltest/go.sum index 1828a5dc585..a988f001973 100644 --- a/otelcol/otelcoltest/go.sum +++ b/otelcol/otelcoltest/go.sum @@ -33,8 +33,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -109,8 +109,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 h1:j8icMXyyqNf6HGuwlYhniPnVsbJIq7n+WirDu3VAJdQ= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0/go.mod h1:evIOZpl+kAlU5IsaYX2Siw+IbpacAZvXemVsgt70uvw= -go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c= -go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 h1:rQWXkXrPMz35C3yNXpLIdwGJ7FQ+956isvltZ5w0Ow4= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642/go.mod h1:5mhiZrDtaZNxGVkF4Ez8eC9wVgmkptLag+g9MUPQFHI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/propagators/b3 v1.31.0 h1:PQPXYscmwbCp76QDvO4hMngF2j8Bx/OTV86laEl8uqo= @@ -198,10 +198,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/service/attributes.go b/service/attributes.go index 056ea2a0453..f05605af26d 100644 --- a/service/attributes.go +++ b/service/attributes.go @@ -4,24 +4,31 @@ package service // import "go.opentelemetry.io/collector/service" import ( + "go.opentelemetry.io/contrib/config" sdkresource "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/collector/service/telemetry" ) -func attributes(res *sdkresource.Resource, cfg telemetry.Config) map[string]interface{} { - attrs := map[string]interface{}{} +func attributes(res *sdkresource.Resource, cfg telemetry.Config) []config.AttributeNameValue { + attrsMap := map[string]interface{}{} for _, r := range res.Attributes() { - attrs[string(r.Key)] = r.Value.AsString() + attrsMap[string(r.Key)] = r.Value.AsString() } for k, v := range cfg.Resource { if v != nil { - attrs[k] = *v + attrsMap[k] = *v } else { // the new value is nil, delete the existing key - delete(attrs, k) + delete(attrsMap, k) } } + + var attrs []config.AttributeNameValue + for k, v := range attrsMap { + attrs = append(attrs, config.AttributeNameValue{Name: k, Value: v}) + } + return attrs } diff --git a/service/attributes_test.go b/service/attributes_test.go index f876663e7ed..f50d7e54371 100644 --- a/service/attributes_test.go +++ b/service/attributes_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "go.opentelemetry.io/contrib/config" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/service/internal/resource" @@ -18,46 +19,50 @@ func TestAttributes(t *testing.T) { name string cfg telemetry.Config buildInfo component.BuildInfo - wantAttributes map[string]interface{} + wantAttributes []config.AttributeNameValue }{ { name: "no build info and no resource config", cfg: telemetry.Config{}, - wantAttributes: map[string]interface{}{"service.name": "", "service.version": "", "service.instance.id": ""}, + wantAttributes: []config.AttributeNameValue{{Name: "service.name", Value: ""}, {Name: "service.version", Value: ""}, {Name: "service.instance.id", Value: ""}}, }, { name: "build info and no resource config", cfg: telemetry.Config{}, buildInfo: component.BuildInfo{Command: "otelcoltest", Version: "0.0.0-test"}, - wantAttributes: map[string]interface{}{"service.name": "otelcoltest", "service.version": "0.0.0-test", "service.instance.id": ""}, + wantAttributes: []config.AttributeNameValue{{Name: "service.name", Value: "otelcoltest"}, {Name: "service.version", Value: "0.0.0-test"}, {Name: "service.instance.id", Value: ""}}, }, { name: "no build info and resource config", - cfg: telemetry.Config{Resource: map[string]*string{"service.name": newPtr("resource.name"), "service.version": newPtr("resource.version"), "test": newPtr("test")}}, - wantAttributes: map[string]interface{}{"service.name": "resource.name", "service.version": "resource.version", "test": "test", "service.instance.id": ""}, + cfg: telemetry.Config{Resource: map[string]*string{"service.name": ptr("resource.name"), "service.version": ptr("resource.version"), "test": ptr("test")}}, + wantAttributes: []config.AttributeNameValue{{Name: "service.name", Value: "resource.name"}, {Name: "service.version", Value: "resource.version"}, {Name: "test", Value: "test"}, {Name: "service.instance.id", Value: ""}}, }, { name: "build info and resource config", buildInfo: component.BuildInfo{Command: "otelcoltest", Version: "0.0.0-test"}, - cfg: telemetry.Config{Resource: map[string]*string{"service.name": newPtr("resource.name"), "service.version": newPtr("resource.version"), "test": newPtr("test")}}, - wantAttributes: map[string]interface{}{"service.name": "resource.name", "service.version": "resource.version", "test": "test", "service.instance.id": ""}, + cfg: telemetry.Config{Resource: map[string]*string{"service.name": ptr("resource.name"), "service.version": ptr("resource.version"), "test": ptr("test")}}, + wantAttributes: []config.AttributeNameValue{{Name: "service.name", Value: "resource.name"}, {Name: "service.version", Value: "resource.version"}, {Name: "test", Value: "test"}, {Name: "service.instance.id", Value: ""}}, }, { name: "deleting a nil value", buildInfo: component.BuildInfo{Command: "otelcoltest", Version: "0.0.0-test"}, - cfg: telemetry.Config{Resource: map[string]*string{"service.name": nil, "service.version": newPtr("resource.version"), "test": newPtr("test")}}, - wantAttributes: map[string]interface{}{"service.version": "resource.version", "test": "test", "service.instance.id": ""}, + cfg: telemetry.Config{Resource: map[string]*string{"service.name": nil, "service.version": ptr("resource.version"), "test": ptr("test")}}, + wantAttributes: []config.AttributeNameValue{{Name: "service.version", Value: "resource.version"}, {Name: "test", Value: "test"}, {Name: "service.instance.id", Value: ""}}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { attrs := attributes(resource.New(tt.buildInfo, tt.cfg.Resource), tt.cfg) require.Len(t, attrs, len(tt.wantAttributes)) - for k, v := range tt.wantAttributes { - if k == "service.instance.id" { - require.NotNil(t, attrs[k]) + gotMap := map[string]any{} + for _, v := range attrs { + gotMap[v.Name] = v.Value + } + for _, v := range tt.wantAttributes { + if v.Name == "service.instance.id" { + require.NotNil(t, gotMap[v.Name]) } else { - require.Equal(t, v, attrs[k]) + require.Equal(t, v.Value, gotMap[v.Name]) } } }) diff --git a/service/config_test.go b/service/config_test.go index 09567436cfa..37466c129f4 100644 --- a/service/config_test.go +++ b/service/config_test.go @@ -99,7 +99,7 @@ func generateConfig() *Config { Metrics: telemetry.MetricsConfig{ Level: configtelemetry.LevelNormal, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: newPtr("localhost"), Port: newPtr(8080), }}}}, diff --git a/service/go.mod b/service/go.mod index cb593cb4949..0ef98a04bd9 100644 --- a/service/go.mod +++ b/service/go.mod @@ -42,13 +42,10 @@ require ( go.opentelemetry.io/collector/receiver/receivertest v0.113.0 go.opentelemetry.io/collector/semconv v0.113.0 go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 - go.opentelemetry.io/contrib/config v0.10.0 + go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 go.opentelemetry.io/contrib/propagators/b3 v1.31.0 go.opentelemetry.io/otel v1.31.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 go.opentelemetry.io/otel/exporters/prometheus v0.53.0 - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.31.0 go.opentelemetry.io/otel/log v0.7.0 go.opentelemetry.io/otel/metric v1.31.0 go.opentelemetry.io/otel/sdk v1.31.0 @@ -74,7 +71,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect @@ -106,18 +103,21 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect go.opentelemetry.io/contrib/zpages v0.56.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.7.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.31.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 // indirect go.opentelemetry.io/otel/sdk/log v0.7.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/service/go.sum b/service/go.sum index 7bbf30c768a..9205c352979 100644 --- a/service/go.sum +++ b/service/go.sum @@ -32,8 +32,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -101,8 +101,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0 h1:j8icMXyyqNf6HGuwlYhniPnVsbJIq7n+WirDu3VAJdQ= go.opentelemetry.io/contrib/bridges/otelzap v0.6.0/go.mod h1:evIOZpl+kAlU5IsaYX2Siw+IbpacAZvXemVsgt70uvw= -go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SWfhfV6Xd6c= -go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642 h1:rQWXkXrPMz35C3yNXpLIdwGJ7FQ+956isvltZ5w0Ow4= +go.opentelemetry.io/contrib/config v0.11.1-0.20241105122513-488f482ce642/go.mod h1:5mhiZrDtaZNxGVkF4Ez8eC9wVgmkptLag+g9MUPQFHI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/propagators/b3 v1.31.0 h1:PQPXYscmwbCp76QDvO4hMngF2j8Bx/OTV86laEl8uqo= @@ -190,10 +190,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/service/internal/promtest/server_util.go b/service/internal/promtest/server_util.go index b0122d9f71e..32a7bec9090 100644 --- a/service/internal/promtest/server_util.go +++ b/service/internal/promtest/server_util.go @@ -23,6 +23,9 @@ func GetAvailableLocalAddressPrometheus(t testing.TB) *config.Prometheus { func addrToPrometheus(address string) *config.Prometheus { host, port, err := net.SplitHostPort(address) + if host == "::1" { + host = "[::1]" + } if err != nil { return nil } @@ -31,7 +34,17 @@ func addrToPrometheus(address string) *config.Prometheus { return nil } return &config.Prometheus{ - Host: &host, - Port: &portInt, + Host: &host, + Port: &portInt, + WithoutScopeInfo: ptr(true), + WithoutUnits: ptr(true), + WithoutTypeSuffix: ptr(true), + WithResourceConstantLabels: &config.IncludeExclude{ + Included: []string{}, + }, } } + +func ptr[T any](v T) *T { + return &v +} diff --git a/service/service.go b/service/service.go index b5e9f8e2384..28c4197fa6b 100644 --- a/service/service.go +++ b/service/service.go @@ -29,6 +29,7 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" + semconv118 "go.opentelemetry.io/collector/semconv/v1.18.0" semconv "go.opentelemetry.io/collector/semconv/v1.26.0" "go.opentelemetry.io/collector/service/extensions" "go.opentelemetry.io/collector/service/internal/builders" @@ -48,6 +49,14 @@ var _ = featuregate.GlobalRegistry().MustRegister( featuregate.WithRegisterDescription("controls whether the collector supports extended OpenTelemetry"+ "configuration for internal telemetry")) +// disableHighCardinalityMetricsFeatureGate is the feature gate that controls whether the collector should enable +// potentially high cardinality metrics. The gate will be removed when the collector allows for view configuration. +var disableHighCardinalityMetricsFeatureGate = featuregate.GlobalRegistry().MustRegister( + "telemetry.disableHighCardinalityMetrics", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("controls whether the collector should enable potentially high"+ + "cardinality metrics. The gate will be removed when the collector allows for view configuration.")) + // Settings holds configuration for building a new Service. type Settings struct { // BuildInfo provides collector start information. @@ -126,6 +135,13 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) { Attributes: attributes(res, cfg.Telemetry), } + views := disableHighCardinalityMetrics() + + readers := cfg.Telemetry.Metrics.Readers + if cfg.Telemetry.Metrics.Level == configtelemetry.LevelNone { + readers = []config.MetricReader{} + } + sdk, err := config.NewSDK( config.WithContext(ctx), config.WithOpenTelemetryConfiguration( @@ -133,6 +149,10 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) { LoggerProvider: &config.LoggerProvider{ Processors: cfg.Telemetry.Logs.Processors, }, + MeterProvider: &config.MeterProvider{ + Readers: readers, + Views: views, + }, TracerProvider: &config.TracerProvider{ Processors: cfg.Telemetry.Traces.Processors, }, @@ -154,12 +174,14 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) { logger, lp, err := telFactory.CreateLogger(ctx, telset, &cfg.Telemetry) if err != nil { + err = multierr.Append(err, sdk.Shutdown(ctx)) return nil, fmt.Errorf("failed to create logger: %w", err) } srv.loggerProvider = lp tracerProvider, err := telFactory.CreateTracerProvider(ctx, telset, &cfg.Telemetry) if err != nil { + err = multierr.Append(err, sdk.Shutdown(ctx)) return nil, fmt.Errorf("failed to create tracer provider: %w", err) } @@ -167,6 +189,7 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) { mp, err := telFactory.CreateMeterProvider(ctx, telset, &cfg.Telemetry) if err != nil { + err = multierr.Append(err, sdk.Shutdown(ctx)) return nil, fmt.Errorf("failed to create meter provider: %w", err) } @@ -370,3 +393,43 @@ func pdataFromSdk(res *sdkresource.Resource) pcommon.Resource { } return pcommonRes } + +func disableHighCardinalityMetrics() []config.View { + var views []config.View + if disableHighCardinalityMetricsFeatureGate.IsEnabled() { + return views + } + return []config.View{ + { + Selector: &config.ViewSelector{ + MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"), + }, + Stream: &config.ViewStream{ + AttributeKeys: &config.IncludeExclude{ + Excluded: []string{ + semconv118.AttributeNetSockPeerAddr, + semconv118.AttributeNetSockPeerPort, + semconv118.AttributeNetSockPeerName, + }, + }, + }, + }, + { + Selector: &config.ViewSelector{ + MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"), + }, + Stream: &config.ViewStream{ + AttributeKeys: &config.IncludeExclude{ + Excluded: []string{ + semconv118.AttributeNetHostName, + semconv118.AttributeNetHostPort, + }, + }, + }, + }, + } +} + +func ptr[T any](v T) *T { + return &v +} diff --git a/service/service_test.go b/service/service_test.go index fb30d7a8fcb..9427839e405 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -312,7 +312,7 @@ func testCollectorStartHelperWithReaders(t *testing.T, tc ownMetricsTestCase, ne cfg.Telemetry.Metrics.Readers = []config.MetricReader{ { Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ + Exporter: config.PullMetricExporter{ Prometheus: metricsAddr, }, }, @@ -491,7 +491,7 @@ func TestServiceInvalidTelemetryConfiguration(t *testing.T) { }, }, }, - wantErr: errors.New("unsupported protocol \"\""), + wantErr: errors.New("no valid log exporter"), }, } for _, tt := range tests { @@ -550,12 +550,16 @@ func assertMetrics(t *testing.T, metricsAddr string, expectedLabels map[string]l "otelcol_process_runtime_heap_alloc_bytes": false, "otelcol_process_runtime_total_alloc_bytes": false, "otelcol_process_uptime": false, + "promhttp_metric_handler_errors_total": false, } for metricName, metricFamily := range parsed { if _, ok := expectedMetrics[metricName]; !ok { require.True(t, ok, "unexpected metric: %s", metricName) } expectedMetrics[metricName] = true + if metricName == "promhttp_metric_handler_errors_total" { + continue + } if metricName != "target_info" { // require is used here so test fails with a single message. require.True( @@ -684,7 +688,7 @@ func newNopConfigPipelineConfigs(pipelineCfgs pipelines.Config) Config { Metrics: telemetry.MetricsConfig{ Level: configtelemetry.LevelBasic, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: newPtr("localhost"), Port: newPtr(8888), }}}}, diff --git a/service/telemetry/config.go b/service/telemetry/config.go index e6d80dbd16c..68f76a2441c 100644 --- a/service/telemetry/config.go +++ b/service/telemetry/config.go @@ -189,7 +189,7 @@ func (c *Config) Unmarshal(conf *confmap.Conf) error { c.Metrics.Readers = append(c.Metrics.Readers, config.MetricReader{ Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ + Exporter: config.PullMetricExporter{ Prometheus: &config.Prometheus{ Host: &host, Port: &portInt, diff --git a/service/telemetry/config_test.go b/service/telemetry/config_test.go index 9f8f9da1efd..e012ac0efa2 100644 --- a/service/telemetry/config_test.go +++ b/service/telemetry/config_test.go @@ -118,7 +118,7 @@ func TestConfigValidate(t *testing.T) { Metrics: MetricsConfig{ Level: configtelemetry.LevelBasic, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: newPtr("127.0.0.1"), Port: newPtr(3333), }}}}, diff --git a/service/telemetry/factory.go b/service/telemetry/factory.go index 6fbc155de79..ba3def5370f 100644 --- a/service/telemetry/factory.go +++ b/service/telemetry/factory.go @@ -17,7 +17,6 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/featuregate" - "go.opentelemetry.io/collector/service/internal/resource" ) var useLocalHostAsDefaultMetricsAddressFeatureGate = featuregate.GlobalRegistry().MustRegister( @@ -27,14 +26,6 @@ var useLocalHostAsDefaultMetricsAddressFeatureGate = featuregate.GlobalRegistry( featuregate.WithRegisterDescription("controls whether default Prometheus metrics server use localhost as the default host for their endpoints"), ) -// disableHighCardinalityMetricsFeatureGate is the feature gate that controls whether the collector should enable -// potentially high cardinality metrics. The gate will be removed when the collector allows for view configuration. -var disableHighCardinalityMetricsFeatureGate = featuregate.GlobalRegistry().MustRegister( - "telemetry.disableHighCardinalityMetrics", - featuregate.StageAlpha, - featuregate.WithRegisterDescription("controls whether the collector should enable potentially high"+ - "cardinality metrics. The gate will be removed when the collector allows for view configuration.")) - // Settings holds configuration for building Telemetry. type Settings struct { BuildInfo component.BuildInfo @@ -77,15 +68,7 @@ func NewFactory() Factory { }), withMeterProvider(func(_ context.Context, set Settings, cfg component.Config) (metric.MeterProvider, error) { c := *cfg.(*Config) - disableHighCard := disableHighCardinalityMetricsFeatureGate.IsEnabled() - return newMeterProvider( - meterProviderSettings{ - res: resource.New(set.BuildInfo, c.Resource), - cfg: c.Metrics, - asyncErrorChannel: set.AsyncErrorChannel, - }, - disableHighCard, - ) + return newMeterProvider(set, c) }), ) } @@ -116,7 +99,7 @@ func createDefaultConfig() component.Config { Metrics: MetricsConfig{ Level: configtelemetry.LevelNormal, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: &metricsHost, Port: newPtr(8888), }}}}, diff --git a/service/telemetry/factory_test.go b/service/telemetry/factory_test.go index 09cda6b7861..5262a1fdeea 100644 --- a/service/telemetry/factory_test.go +++ b/service/telemetry/factory_test.go @@ -66,7 +66,7 @@ func TestTelemetryConfiguration(t *testing.T) { Metrics: MetricsConfig{ Level: configtelemetry.LevelBasic, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: newPtr("127.0.0.1"), Port: newPtr(3333), }}}}, @@ -84,7 +84,7 @@ func TestTelemetryConfiguration(t *testing.T) { Metrics: MetricsConfig{ Level: configtelemetry.LevelBasic, Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: &config.Prometheus{ + Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{ Host: newPtr("127.0.0.1"), Port: newPtr(3333), }}}}, diff --git a/service/telemetry/internal/otelinit/config.go b/service/telemetry/internal/otelinit/config.go deleted file mode 100644 index 402090675ac..00000000000 --- a/service/telemetry/internal/otelinit/config.go +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package otelinit // import "go.opentelemetry.io/collector/service/telemetry/internal/otelinit" - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promhttp" - "go.opentelemetry.io/contrib/config" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" - otelprom "go.opentelemetry.io/otel/exporters/prometheus" - "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" - "go.opentelemetry.io/otel/sdk/instrumentation" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" - "go.opentelemetry.io/otel/sdk/resource" - - semconv "go.opentelemetry.io/collector/semconv/v1.18.0" -) - -const ( - - // gRPC Instrumentation Name - GRPCInstrumentation = "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - - // http Instrumentation Name - HTTPInstrumentation = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - - // supported protocols - protocolProtobufHTTP = "http/protobuf" - protocolProtobufGRPC = "grpc/protobuf" - defaultReadHeaderTimeout = 10 * time.Second -) - -var ( - // GRPCUnacceptableKeyValues is a list of high cardinality grpc attributes that should be filtered out. - GRPCUnacceptableKeyValues = attribute.NewSet( - attribute.String(semconv.AttributeNetSockPeerAddr, ""), - attribute.String(semconv.AttributeNetSockPeerPort, ""), - attribute.String(semconv.AttributeNetSockPeerName, ""), - ) - - // HTTPUnacceptableKeyValues is a list of high cardinality http attributes that should be filtered out. - HTTPUnacceptableKeyValues = attribute.NewSet( - attribute.String(semconv.AttributeNetHostName, ""), - attribute.String(semconv.AttributeNetHostPort, ""), - ) - - errNoValidMetricExporter = errors.New("no valid metric exporter") -) - -func InitMetricReader(ctx context.Context, reader config.MetricReader, asyncErrorChannel chan error, serverWG *sync.WaitGroup) (sdkmetric.Reader, *http.Server, error) { - if reader.Pull != nil { - return initPullExporter(reader.Pull.Exporter, asyncErrorChannel, serverWG) - } - if reader.Periodic != nil { - var opts []sdkmetric.PeriodicReaderOption - if reader.Periodic.Interval != nil { - opts = append(opts, sdkmetric.WithInterval(time.Duration(*reader.Periodic.Interval)*time.Millisecond)) - } - - if reader.Periodic.Timeout != nil { - opts = append(opts, sdkmetric.WithTimeout(time.Duration(*reader.Periodic.Timeout)*time.Millisecond)) - } - return initPeriodicExporter(ctx, reader.Periodic.Exporter, opts...) - } - return nil, nil, fmt.Errorf("unsupported metric reader type %v", reader) -} - -func InitOpenTelemetry(res *resource.Resource, options []sdkmetric.Option, disableHighCardinality bool) (*sdkmetric.MeterProvider, error) { - opts := []sdkmetric.Option{ - sdkmetric.WithResource(res), - sdkmetric.WithView(disableHighCardinalityViews(disableHighCardinality)...), - } - - opts = append(opts, options...) - return sdkmetric.NewMeterProvider( - opts..., - ), nil -} - -func InitPrometheusServer(registry *prometheus.Registry, address string, asyncErrorChannel chan error, serverWG *sync.WaitGroup) *http.Server { - mux := http.NewServeMux() - mux.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{})) - server := &http.Server{ - Addr: address, - Handler: mux, - ReadHeaderTimeout: defaultReadHeaderTimeout, - } - - serverWG.Add(1) - go func() { - defer serverWG.Done() - if serveErr := server.ListenAndServe(); serveErr != nil && !errors.Is(serveErr, http.ErrServerClosed) { - select { - case asyncErrorChannel <- serveErr: - case <-time.After(1 * time.Second): - } - } - }() - return server -} - -func disableHighCardinalityViews(disableHighCardinality bool) []sdkmetric.View { - if !disableHighCardinality { - return nil - } - return []sdkmetric.View{ - sdkmetric.NewView( - sdkmetric.Instrument{Scope: instrumentation.Scope{Name: GRPCInstrumentation}}, - sdkmetric.Stream{ - AttributeFilter: cardinalityFilter(GRPCUnacceptableKeyValues), - }), - sdkmetric.NewView( - sdkmetric.Instrument{Scope: instrumentation.Scope{Name: HTTPInstrumentation}}, - sdkmetric.Stream{ - AttributeFilter: cardinalityFilter(HTTPUnacceptableKeyValues), - }), - } -} - -func cardinalityFilter(filter attribute.Set) attribute.Filter { - return func(kv attribute.KeyValue) bool { - return !filter.HasValue(kv.Key) - } -} - -func initPrometheusExporter(prometheusConfig *config.Prometheus, asyncErrorChannel chan error, serverWG *sync.WaitGroup) (sdkmetric.Reader, *http.Server, error) { - promRegistry := prometheus.NewRegistry() - if prometheusConfig.Host == nil { - return nil, nil, errors.New("host must be specified") - } - if prometheusConfig.Port == nil { - return nil, nil, errors.New("port must be specified") - } - - opts := []otelprom.Option{ - otelprom.WithRegisterer(promRegistry), - // https://github.com/open-telemetry/opentelemetry-collector/issues/8043 - otelprom.WithoutUnits(), - // Disabled for the moment until this becomes stable, and we are ready to break backwards compatibility. - otelprom.WithoutScopeInfo(), - // This allows us to produce metrics that are backwards compatible w/ opencensus - otelprom.WithoutCounterSuffixes(), - otelprom.WithResourceAsConstantLabels(attribute.NewDenyKeysFilter()), - } - exporter, err := otelprom.New(opts...) - if err != nil { - return nil, nil, fmt.Errorf("error creating otel prometheus exporter: %w", err) - } - - return exporter, InitPrometheusServer(promRegistry, net.JoinHostPort(*prometheusConfig.Host, strconv.Itoa(*prometheusConfig.Port)), asyncErrorChannel, serverWG), nil -} - -func initPullExporter(exporter config.MetricExporter, asyncErrorChannel chan error, serverWG *sync.WaitGroup) (sdkmetric.Reader, *http.Server, error) { - if exporter.Prometheus != nil { - return initPrometheusExporter(exporter.Prometheus, asyncErrorChannel, serverWG) - } - return nil, nil, errNoValidMetricExporter -} - -func initPeriodicExporter(ctx context.Context, exporter config.MetricExporter, opts ...sdkmetric.PeriodicReaderOption) (sdkmetric.Reader, *http.Server, error) { - if exporter.Console != nil { - enc := json.NewEncoder(os.Stdout) - enc.SetIndent("", " ") - - exp, err := stdoutmetric.New( - stdoutmetric.WithEncoder(enc), - ) - if err != nil { - return nil, nil, err - } - return sdkmetric.NewPeriodicReader(exp, opts...), nil, nil - } - if exporter.OTLP != nil { - var err error - var exp sdkmetric.Exporter - switch exporter.OTLP.Protocol { - case protocolProtobufHTTP: - exp, err = initOTLPHTTPExporter(ctx, exporter.OTLP) - case protocolProtobufGRPC: - exp, err = initOTLPgRPCExporter(ctx, exporter.OTLP) - default: - return nil, nil, fmt.Errorf("unsupported protocol %s", exporter.OTLP.Protocol) - } - if err != nil { - return nil, nil, err - } - return sdkmetric.NewPeriodicReader(exp, opts...), nil, nil - } - return nil, nil, errNoValidMetricExporter -} - -func normalizeEndpoint(endpoint string) string { - if !strings.HasPrefix(endpoint, "https://") && !strings.HasPrefix(endpoint, "http://") { - return "http://" + endpoint - } - return endpoint -} - -func initOTLPgRPCExporter(ctx context.Context, otlpConfig *config.OTLPMetric) (sdkmetric.Exporter, error) { - opts := []otlpmetricgrpc.Option{} - - if len(otlpConfig.Endpoint) > 0 { - u, err := url.ParseRequestURI(normalizeEndpoint(otlpConfig.Endpoint)) - if err != nil { - return nil, err - } - opts = append(opts, otlpmetricgrpc.WithEndpoint(u.Host)) - if u.Scheme == "http" { - opts = append(opts, otlpmetricgrpc.WithInsecure()) - } - } - - if otlpConfig.Compression != nil { - switch *otlpConfig.Compression { - case "gzip": - opts = append(opts, otlpmetricgrpc.WithCompressor(*otlpConfig.Compression)) - case "none": - break - default: - return nil, fmt.Errorf("unsupported compression %q", *otlpConfig.Compression) - } - } - if otlpConfig.Timeout != nil { - opts = append(opts, otlpmetricgrpc.WithTimeout(time.Millisecond*time.Duration(*otlpConfig.Timeout))) - } - if len(otlpConfig.Headers) > 0 { - opts = append(opts, otlpmetricgrpc.WithHeaders(otlpConfig.Headers)) - } - if otlpConfig.TemporalityPreference != nil { - switch *otlpConfig.TemporalityPreference { - case "delta": - opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(temporalityPreferenceDelta)) - case "cumulative": - opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(temporalityPreferenceCumulative)) - case "lowmemory": - opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(temporalityPreferenceLowMemory)) - default: - return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference) - } - } - - return otlpmetricgrpc.New(ctx, opts...) -} - -func initOTLPHTTPExporter(ctx context.Context, otlpConfig *config.OTLPMetric) (sdkmetric.Exporter, error) { - opts := []otlpmetrichttp.Option{} - - if len(otlpConfig.Endpoint) > 0 { - u, err := url.ParseRequestURI(normalizeEndpoint(otlpConfig.Endpoint)) - if err != nil { - return nil, err - } - opts = append(opts, otlpmetrichttp.WithEndpoint(u.Host)) - - if u.Scheme == "http" { - opts = append(opts, otlpmetrichttp.WithInsecure()) - } - if len(u.Path) > 0 { - opts = append(opts, otlpmetrichttp.WithURLPath(u.Path)) - } - } - if otlpConfig.Compression != nil { - switch *otlpConfig.Compression { - case "gzip": - opts = append(opts, otlpmetrichttp.WithCompression(otlpmetrichttp.GzipCompression)) - case "none": - opts = append(opts, otlpmetrichttp.WithCompression(otlpmetrichttp.NoCompression)) - default: - return nil, fmt.Errorf("unsupported compression %q", *otlpConfig.Compression) - } - } - if otlpConfig.Timeout != nil { - opts = append(opts, otlpmetrichttp.WithTimeout(time.Millisecond*time.Duration(*otlpConfig.Timeout))) - } - if len(otlpConfig.Headers) > 0 { - opts = append(opts, otlpmetrichttp.WithHeaders(otlpConfig.Headers)) - } - if otlpConfig.TemporalityPreference != nil { - switch *otlpConfig.TemporalityPreference { - case "delta": - opts = append(opts, otlpmetrichttp.WithTemporalitySelector(temporalityPreferenceDelta)) - case "cumulative": - opts = append(opts, otlpmetrichttp.WithTemporalitySelector(temporalityPreferenceCumulative)) - case "lowmemory": - opts = append(opts, otlpmetrichttp.WithTemporalitySelector(temporalityPreferenceLowMemory)) - default: - return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference) - } - } - - return otlpmetrichttp.New(ctx, opts...) -} - -func temporalityPreferenceCumulative(_ sdkmetric.InstrumentKind) metricdata.Temporality { - return metricdata.CumulativeTemporality -} - -func temporalityPreferenceDelta(ik sdkmetric.InstrumentKind) metricdata.Temporality { - switch ik { - case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindObservableCounter, sdkmetric.InstrumentKindHistogram: - return metricdata.DeltaTemporality - case sdkmetric.InstrumentKindObservableUpDownCounter, sdkmetric.InstrumentKindUpDownCounter: - return metricdata.CumulativeTemporality - default: - return metricdata.DeltaTemporality - } -} - -func temporalityPreferenceLowMemory(ik sdkmetric.InstrumentKind) metricdata.Temporality { - switch ik { - case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindHistogram: - return metricdata.DeltaTemporality - case sdkmetric.InstrumentKindObservableCounter, sdkmetric.InstrumentKindObservableUpDownCounter, sdkmetric.InstrumentKindUpDownCounter: - return metricdata.CumulativeTemporality - default: - return metricdata.DeltaTemporality - } -} diff --git a/service/telemetry/internal/otelinit/config_test.go b/service/telemetry/internal/otelinit/config_test.go deleted file mode 100644 index 02974fa11e4..00000000000 --- a/service/telemetry/internal/otelinit/config_test.go +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package otelinit - -import ( - "context" - "errors" - "net/url" - "reflect" - "sync" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/contrib/config" - "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" - "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" - otelprom "go.opentelemetry.io/otel/exporters/prometheus" - "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" -) - -func strPtr(s string) *string { - return &s -} - -func intPtr(i int) *int { - return &i -} - -func TestMetricReader(t *testing.T) { - consoleExporter, err := stdoutmetric.New( - stdoutmetric.WithPrettyPrint(), - ) - require.NoError(t, err) - ctx := context.Background() - otlpGRPCExporter, err := otlpmetricgrpc.New(ctx) - require.NoError(t, err) - otlpHTTPExporter, err := otlpmetrichttp.New(ctx) - require.NoError(t, err) - promExporter, err := otelprom.New() - require.NoError(t, err) - - testCases := []struct { - name string - reader config.MetricReader - args any - wantErr error - wantReader sdkmetric.Reader - }{ - { - name: "noreader", - wantErr: errors.New("unsupported metric reader type { }"), - }, - { - name: "pull prometheus invalid exporter", - reader: config.MetricReader{ - Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{}, - }, - }, - }, - wantErr: errNoValidMetricExporter, - }, - { - name: "pull/prometheus-invalid-config-no-host", - reader: config.MetricReader{ - Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ - Prometheus: &config.Prometheus{}, - }, - }, - }, - wantErr: errors.New("host must be specified"), - }, - { - name: "pull/prometheus-invalid-config-no-port", - reader: config.MetricReader{ - Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ - Prometheus: &config.Prometheus{ - Host: strPtr("localhost"), - }, - }, - }, - }, - wantErr: errors.New("port must be specified"), - }, - { - name: "pull/prometheus-valid", - reader: config.MetricReader{ - Pull: &config.PullMetricReader{ - Exporter: config.MetricExporter{ - Prometheus: &config.Prometheus{ - Host: strPtr("localhost"), - Port: intPtr(8080), - }, - }, - }, - }, - wantReader: promExporter, - }, - { - name: "periodic/invalid-exporter", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - Prometheus: &config.Prometheus{ - Host: strPtr("localhost"), - Port: intPtr(8080), - }, - }, - }, - }, - wantErr: errNoValidMetricExporter, - }, - { - name: "periodic/no-exporter", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{}, - }, - wantErr: errNoValidMetricExporter, - }, - { - name: "periodic/console-exporter", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - Console: config.Console{}, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(consoleExporter), - }, - { - name: "periodic/console-exporter-with-timeout-interval", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Interval: intPtr(10), - Timeout: intPtr(5), - Exporter: config.MetricExporter{ - Console: config.Console{}, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(consoleExporter), - }, - { - name: "periodic/otlp-exporter-invalid-protocol", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: *strPtr("http/invalid"), - }, - }, - }, - }, - wantErr: errors.New("unsupported protocol http/invalid"), - }, - { - name: "periodic/otlp-grpc-exporter-no-endpoint", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-exporter", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "http://localhost:4317", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-exporter-no-scheme", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4317", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-invalid-endpoint", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: " ", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantErr: &url.Error{Op: "parse", URL: "http:// ", Err: url.InvalidHostError(" ")}, - }, - { - name: "periodic/otlp-grpc-invalid-compression", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4317", - Compression: strPtr("invalid"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantErr: errors.New("unsupported compression \"invalid\""), - }, - { - name: "periodic/otlp-grpc-delta-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("delta"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-cumulative-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("cumulative"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-lowmemory-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("lowmemory"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter), - }, - { - name: "periodic/otlp-grpc-invalid-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "grpc/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("invalid"), - }, - }, - }, - }, - wantErr: errors.New("unsupported temporality preference \"invalid\""), - }, - { - name: "periodic/otlp-http-exporter", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "http://localhost:4318", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-exporter-with-path", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "http://localhost:4318/path/123", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-exporter-no-endpoint", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-exporter-no-scheme", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-invalid-endpoint", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: " ", - Compression: strPtr("gzip"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantErr: &url.Error{Op: "parse", URL: "http:// ", Err: url.InvalidHostError(" ")}, - }, - { - name: "periodic/otlp-http-invalid-compression", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("invalid"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - }, - }, - }, - }, - wantErr: errors.New("unsupported compression \"invalid\""), - }, - { - name: "periodic/otlp-http-cumulative-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("cumulative"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-lowmemory-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("lowmemory"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-delta-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("delta"), - }, - }, - }, - }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), - }, - { - name: "periodic/otlp-http-invalid-temporality", - reader: config.MetricReader{ - Periodic: &config.PeriodicMetricReader{ - Exporter: config.MetricExporter{ - OTLP: &config.OTLPMetric{ - Protocol: "http/protobuf", - Endpoint: "localhost:4318", - Compression: strPtr("none"), - Timeout: intPtr(1000), - Headers: map[string]string{ - "test": "test1", - }, - TemporalityPreference: strPtr("invalid"), - }, - }, - }, - }, - wantErr: errors.New("unsupported temporality preference \"invalid\""), - }, - } - for _, tt := range testCases { - t.Run(tt.name, func(t *testing.T) { - gotReader, server, err := InitMetricReader(context.Background(), tt.reader, make(chan error), &sync.WaitGroup{}) - - defer func() { - if gotReader != nil { - require.NoError(t, gotReader.Shutdown(context.Background())) - } - if server != nil { - assert.NoError(t, server.Shutdown(context.Background())) - } - }() - - assert.Equal(t, tt.wantErr, err) - - if tt.wantReader == nil { - assert.Nil(t, gotReader) - } else { - assert.Equal(t, reflect.TypeOf(tt.wantReader), reflect.TypeOf(gotReader)) - - if reflect.TypeOf(tt.wantReader).String() == "*metric.PeriodicReader" { - wantExporterType := reflect.Indirect(reflect.ValueOf(tt.wantReader)).FieldByName("exporter").Elem().Type() - gotExporterType := reflect.Indirect(reflect.ValueOf(gotReader)).FieldByName("exporter").Elem().Type() - assert.Equal(t, wantExporterType, gotExporterType) - } - } - }) - } -} diff --git a/service/telemetry/metrics.go b/service/telemetry/metrics.go index 0b2690c0af1..c8087afaffe 100644 --- a/service/telemetry/metrics.go +++ b/service/telemetry/metrics.go @@ -4,88 +4,22 @@ package telemetry // import "go.opentelemetry.io/collector/service/telemetry" import ( - "context" - "net/http" - "sync" + "errors" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/noop" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/resource" - "go.uber.org/multierr" - "go.uber.org/zap" "go.opentelemetry.io/collector/config/configtelemetry" - "go.opentelemetry.io/collector/service/telemetry/internal/otelinit" ) -const ( - zapKeyTelemetryAddress = "address" - zapKeyTelemetryLevel = "metrics level" -) - -type meterProvider struct { - *sdkmetric.MeterProvider - servers []*http.Server - serverWG sync.WaitGroup -} - -type meterProviderSettings struct { - res *resource.Resource - cfg MetricsConfig - asyncErrorChannel chan error -} - // newMeterProvider creates a new MeterProvider from Config. -func newMeterProvider(set meterProviderSettings, disableHighCardinality bool) (metric.MeterProvider, error) { - if set.cfg.Level == configtelemetry.LevelNone || len(set.cfg.Readers) == 0 { +func newMeterProvider(set Settings, cfg Config) (metric.MeterProvider, error) { + if cfg.Metrics.Level == configtelemetry.LevelNone || len(cfg.Metrics.Readers) == 0 { return noop.NewMeterProvider(), nil } - mp := &meterProvider{} - var opts []sdkmetric.Option - for _, reader := range set.cfg.Readers { - // https://github.com/open-telemetry/opentelemetry-collector/issues/8045 - r, server, err := otelinit.InitMetricReader(context.Background(), reader, set.asyncErrorChannel, &mp.serverWG) - if err != nil { - return nil, err - } - if server != nil { - mp.servers = append(mp.servers, server) - } - opts = append(opts, sdkmetric.WithReader(r)) - } - - var err error - mp.MeterProvider, err = otelinit.InitOpenTelemetry(set.res, opts, disableHighCardinality) - if err != nil { - return nil, err + if set.SDK != nil { + return set.SDK.MeterProvider(), nil } - return mp, nil -} - -// LogAboutServers logs about the servers that are serving metrics. -func (mp *meterProvider) LogAboutServers(logger *zap.Logger, cfg MetricsConfig) { - for _, server := range mp.servers { - logger.Info( - "Serving metrics", - zap.String(zapKeyTelemetryAddress, server.Addr), - zap.Stringer(zapKeyTelemetryLevel, cfg.Level), - ) - } -} - -// Shutdown the meter provider and all the associated resources. -// The type signature of this method matches that of the sdkmetric.MeterProvider. -func (mp *meterProvider) Shutdown(ctx context.Context) error { - var errs error - for _, server := range mp.servers { - if server != nil { - errs = multierr.Append(errs, server.Close()) - } - } - errs = multierr.Append(errs, mp.MeterProvider.Shutdown(ctx)) - mp.serverWG.Wait() - - return errs + return nil, errors.New("no sdk set") } diff --git a/service/telemetry/metrics_test.go b/service/telemetry/metrics_test.go index 09ee8616471..20456eed717 100644 --- a/service/telemetry/metrics_test.go +++ b/service/telemetry/metrics_test.go @@ -13,14 +13,12 @@ import ( "github.com/prometheus/common/expfmt" "github.com/stretchr/testify/require" "go.opentelemetry.io/contrib/config" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" semconv "go.opentelemetry.io/collector/semconv/v1.18.0" "go.opentelemetry.io/collector/service/internal/promtest" - "go.opentelemetry.io/collector/service/internal/resource" - "go.opentelemetry.io/collector/service/telemetry/internal/otelinit" ) const ( @@ -41,7 +39,6 @@ func TestTelemetryInit(t *testing.T) { for _, tt := range []struct { name string - disableHighCard bool expectedMetrics map[string]metricValue }{ { @@ -84,42 +81,10 @@ func TestTelemetryInit(t *testing.T) { "service_instance_id": testInstanceID, }, }, - }, - }, - { - name: "DisableHighCardinalityWithOtel", - disableHighCard: true, - expectedMetrics: map[string]metricValue{ - metricPrefix + otelPrefix + counterName: { - value: 13, - labels: map[string]string{ - "service_name": "otelcol", - "service_version": "latest", - "service_instance_id": testInstanceID, - }, - }, - metricPrefix + grpcPrefix + counterName: { - value: 11, - labels: map[string]string{ - "service_name": "otelcol", - "service_version": "latest", - "service_instance_id": testInstanceID, - }, - }, - metricPrefix + httpPrefix + counterName: { - value: 10, - labels: map[string]string{ - "service_name": "otelcol", - "service_version": "latest", - "service_instance_id": testInstanceID, - }, - }, - "target_info": { + "promhttp_metric_handler_errors_total": { value: 0, labels: map[string]string{ - "service_name": "otelcol", - "service_version": "latest", - "service_instance_id": testInstanceID, + "cause": "encoding", }, }, }, @@ -127,35 +92,36 @@ func TestTelemetryInit(t *testing.T) { } { prom := promtest.GetAvailableLocalAddressPrometheus(t) endpoint := fmt.Sprintf("http://%s:%d/metrics", *prom.Host, *prom.Port) + cfg := Config{ + Metrics: MetricsConfig{ + Level: configtelemetry.LevelDetailed, + Readers: []config.MetricReader{{ + Pull: &config.PullMetricReader{ + Exporter: config.PullMetricExporter{Prometheus: prom}, + }, + }}, + }, + } t.Run(tt.name, func(t *testing.T) { - cfg := &Config{ - Metrics: MetricsConfig{ - Level: configtelemetry.LevelDetailed, - Readers: []config.MetricReader{{ - Pull: &config.PullMetricReader{Exporter: config.MetricExporter{Prometheus: prom}}, - }}, - }, - Traces: TracesConfig{ - Processors: []config.SpanProcessor{ - { - Batch: &config.BatchSpanProcessor{ - Exporter: config.SpanExporter{ - Console: config.Console{}, - }, - }, + sdk, err := config.NewSDK( + config.WithContext(context.Background()), + config.WithOpenTelemetryConfiguration(config.OpenTelemetryConfiguration{ + MeterProvider: &config.MeterProvider{ + Readers: cfg.Metrics.Readers, + }, + Resource: &config.Resource{ + SchemaUrl: ptr(""), + Attributes: []config.AttributeNameValue{ + {Name: semconv.AttributeServiceInstanceID, Value: testInstanceID}, + {Name: semconv.AttributeServiceName, Value: "otelcol"}, + {Name: semconv.AttributeServiceVersion, Value: "latest"}, }, }, - }, - Resource: map[string]*string{ - semconv.AttributeServiceInstanceID: &testInstanceID, - }, - } - set := meterProviderSettings{ - res: resource.New(component.NewDefaultBuildInfo(), cfg.Resource), - cfg: cfg.Metrics, - asyncErrorChannel: make(chan error), - } - mp, err := newMeterProvider(set, tt.disableHighCard) + }), + ) + require.NoError(t, err) + + mp, err := newMeterProvider(Settings{SDK: &sdk}, cfg) require.NoError(t, err) defer func() { if prov, ok := mp.(interface{ Shutdown(context.Context) error }); ok { @@ -166,11 +132,14 @@ func TestTelemetryInit(t *testing.T) { createTestMetrics(t, mp) metrics := getMetricsFromPrometheus(t, endpoint) - require.Equal(t, len(tt.expectedMetrics), len(metrics)) + require.Len(t, metrics, len(tt.expectedMetrics)) for metricName, metricValue := range tt.expectedMetrics { mf, present := metrics[metricName] require.True(t, present, "expected metric %q was not present", metricName) + if metricName == "promhttp_metric_handler_errors_total" { + continue + } require.Len(t, mf.Metric, 1, "only one measure should exist for metric %q", metricName) labels := make(map[string]string) @@ -191,13 +160,20 @@ func createTestMetrics(t *testing.T, mp metric.MeterProvider) { require.NoError(t, err) counter.Add(context.Background(), 13) - grpcExampleCounter, err := mp.Meter(otelinit.GRPCInstrumentation).Int64Counter(metricPrefix + grpcPrefix + counterName) + grpcExampleCounter, err := mp.Meter("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc").Int64Counter(metricPrefix + grpcPrefix + counterName) require.NoError(t, err) - grpcExampleCounter.Add(context.Background(), 11, metric.WithAttributeSet(otelinit.GRPCUnacceptableKeyValues)) + grpcExampleCounter.Add(context.Background(), 11, metric.WithAttributeSet(attribute.NewSet( + attribute.String(semconv.AttributeNetSockPeerAddr, ""), + attribute.String(semconv.AttributeNetSockPeerPort, ""), + attribute.String(semconv.AttributeNetSockPeerName, ""), + ))) - httpExampleCounter, err := mp.Meter(otelinit.HTTPInstrumentation).Int64Counter(metricPrefix + httpPrefix + counterName) + httpExampleCounter, err := mp.Meter("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp").Int64Counter(metricPrefix + httpPrefix + counterName) require.NoError(t, err) - httpExampleCounter.Add(context.Background(), 10, metric.WithAttributeSet(otelinit.HTTPUnacceptableKeyValues)) + httpExampleCounter.Add(context.Background(), 10, metric.WithAttributeSet(attribute.NewSet( + attribute.String(semconv.AttributeNetHostName, ""), + attribute.String(semconv.AttributeNetHostPort, ""), + ))) } func getMetricsFromPrometheus(t *testing.T, endpoint string) map[string]*io_prometheus_client.MetricFamily { @@ -213,3 +189,7 @@ func getMetricsFromPrometheus(t *testing.T, endpoint string) map[string]*io_prom return parsed } + +func ptr[T any](v T) *T { + return &v +}