From dab92d48071fe4a1d9356533ed41be323ecfa955 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Tue, 19 Sep 2023 20:11:01 +0100 Subject: [PATCH] Enable Collector Otel metrics in Flow (#5045) --- CHANGELOG.md | 5 ++ cmd/internal/flowmode/cmd_run.go | 4 ++ component/otelcol/auth/auth.go | 2 - component/otelcol/auth/basic/basic.go | 8 ++- component/otelcol/auth/bearer/bearer.go | 8 ++- component/otelcol/auth/headers/headers.go | 8 ++- component/otelcol/auth/oauth2/oauth2.go | 8 ++- component/otelcol/auth/sigv4/sigv4.go | 8 ++- component/otelcol/connector/connector.go | 2 - .../connector/servicegraph/servicegraph.go | 8 ++- .../connector/spanmetrics/spanmetrics.go | 8 ++- component/otelcol/exporter/exporter.go | 2 - component/otelcol/exporter/jaeger/jaeger.go | 8 ++- .../exporter/loadbalancing/loadbalancing.go | 8 ++- component/otelcol/exporter/logging/logging.go | 8 ++- component/otelcol/exporter/otlp/otlp.go | 8 ++- .../otelcol/exporter/otlphttp/otlphttp.go | 8 ++- component/otelcol/extension/extension.go | 2 - .../otelcol/internal/featuregate/install.go | 38 ----------- .../internal/featuregate/install_test.go | 13 ---- .../processor/attributes/attributes.go | 8 ++- component/otelcol/processor/batch/batch.go | 8 ++- .../processor/memorylimiter/memorylimiter.go | 8 ++- .../probabilistic_sampler.go | 8 ++- component/otelcol/processor/processor.go | 2 - component/otelcol/processor/span/span.go | 8 ++- .../processor/tail_sampling/tail_sampling.go | 8 ++- component/otelcol/receiver/jaeger/jaeger.go | 6 +- component/otelcol/receiver/kafka/kafka.go | 6 +- .../otelcol/receiver/opencensus/opencensus.go | 6 +- component/otelcol/receiver/otlp/otlp.go | 6 +- .../otelcol/receiver/prometheus/prometheus.go | 8 ++- component/otelcol/receiver/receiver.go | 2 - component/otelcol/receiver/zipkin/zipkin.go | 6 +- .../components/otelcol.exporter.otlp.md | 5 ++ .../components/otelcol.processor.batch.md | 6 ++ .../components/otelcol.receiver.otlp.md | 6 ++ pkg/traces/instance.go | 32 +-------- pkg/util/otel_feature_gate.go | 67 +++++++++++++++++++ pkg/util/otel_feature_gate_test.go | 44 ++++++++++++ service/otel/otel.go | 54 +++++++++++++++ 41 files changed, 307 insertions(+), 161 deletions(-) delete mode 100644 component/otelcol/internal/featuregate/install.go delete mode 100644 component/otelcol/internal/featuregate/install_test.go create mode 100644 pkg/util/otel_feature_gate.go create mode 100644 pkg/util/otel_feature_gate_test.go create mode 100644 service/otel/otel.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad6e4e0214e..6c3924085c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,11 @@ Main (unreleased) - Add `openstack` config converter to convert OpenStack yaml config (static mode) to river config (flow mode). (@wildum) +- Some `otelcol` components will now display their debug metrics via the + Agent's `/metrics` endpoint. Those components include `otelcol.receiver.otlp`, + `otelcol.exporter.otlp` and `otelcol.processor.batch`. There may also be metrics + from other components which are not documented yet. (@ptodev) + ### Other changes - Use Go 1.21.1 for builds. (@rfratto) diff --git a/cmd/internal/flowmode/cmd_run.go b/cmd/internal/flowmode/cmd_run.go index 0c4611d10846..d739ac84a504 100644 --- a/cmd/internal/flowmode/cmd_run.go +++ b/cmd/internal/flowmode/cmd_run.go @@ -26,6 +26,7 @@ import ( "github.com/grafana/agent/service" "github.com/grafana/agent/service/cluster" httpservice "github.com/grafana/agent/service/http" + otel_service "github.com/grafana/agent/service/otel" uiservice "github.com/grafana/agent/service/ui" "github.com/grafana/ckit/advertise" "github.com/grafana/ckit/peer" @@ -233,6 +234,8 @@ func (fr *flowRun) Run(configFile string) error { Cluster: clusterService.Data().(cluster.Cluster), }) + otelService := otel_service.New() + f := flow.New(flow.Options{ Logger: l, Tracer: t, @@ -242,6 +245,7 @@ func (fr *flowRun) Run(configFile string) error { httpService, uiService, clusterService, + otelService, }, }) diff --git a/component/otelcol/auth/auth.go b/component/otelcol/auth/auth.go index 5ac0b57a6fa1..4e5f6f668d83 100644 --- a/component/otelcol/auth/auth.go +++ b/component/otelcol/auth/auth.go @@ -20,8 +20,6 @@ import ( otelextension "go.opentelemetry.io/collector/extension" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) // Arguments is an extension of component.Arguments which contains necessary diff --git a/component/otelcol/auth/basic/basic.go b/component/otelcol/auth/basic/basic.go index ceae037d7f40..b82209e388a3 100644 --- a/component/otelcol/auth/basic/basic.go +++ b/component/otelcol/auth/basic/basic.go @@ -4,6 +4,7 @@ package basic import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol/auth" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river/rivertypes" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/basicauthextension" otelcomponent "go.opentelemetry.io/collector/component" @@ -13,9 +14,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.auth.basic", - Args: Arguments{}, - Exports: auth.Exports{}, + Name: "otelcol.auth.basic", + Args: Arguments{}, + Exports: auth.Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := basicauthextension.NewFactory() diff --git a/component/otelcol/auth/bearer/bearer.go b/component/otelcol/auth/bearer/bearer.go index d99ea1b7cee9..bfcb40e6b55d 100644 --- a/component/otelcol/auth/bearer/bearer.go +++ b/component/otelcol/auth/bearer/bearer.go @@ -4,6 +4,7 @@ package bearer import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol/auth" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river/rivertypes" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/bearertokenauthextension" otelcomponent "go.opentelemetry.io/collector/component" @@ -13,9 +14,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.auth.bearer", - Args: Arguments{}, - Exports: auth.Exports{}, + Name: "otelcol.auth.bearer", + Args: Arguments{}, + Exports: auth.Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := bearertokenauthextension.NewFactory() diff --git a/component/otelcol/auth/headers/headers.go b/component/otelcol/auth/headers/headers.go index b0530639b8b4..56156759cac4 100644 --- a/component/otelcol/auth/headers/headers.go +++ b/component/otelcol/auth/headers/headers.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol/auth" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river" "github.com/grafana/river/rivertypes" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/headerssetterextension" @@ -17,9 +18,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.auth.headers", - Args: Arguments{}, - Exports: auth.Exports{}, + Name: "otelcol.auth.headers", + Args: Arguments{}, + Exports: auth.Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := headerssetterextension.NewFactory() diff --git a/component/otelcol/auth/oauth2/oauth2.go b/component/otelcol/auth/oauth2/oauth2.go index 47e2c102fff6..917ec12997ac 100644 --- a/component/otelcol/auth/oauth2/oauth2.go +++ b/component/otelcol/auth/oauth2/oauth2.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/auth" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/oauth2clientauthextension" otelcomponent "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configopaque" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.auth.oauth2", - Args: Arguments{}, - Exports: auth.Exports{}, + Name: "otelcol.auth.oauth2", + Args: Arguments{}, + Exports: auth.Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := oauth2clientauthextension.NewFactory() diff --git a/component/otelcol/auth/sigv4/sigv4.go b/component/otelcol/auth/sigv4/sigv4.go index 0a3db55c546b..81336757fb6b 100644 --- a/component/otelcol/auth/sigv4/sigv4.go +++ b/component/otelcol/auth/sigv4/sigv4.go @@ -3,6 +3,7 @@ package sigv4 import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol/auth" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/sigv4authextension" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" @@ -10,9 +11,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.auth.sigv4", - Args: Arguments{}, - Exports: auth.Exports{}, + Name: "otelcol.auth.sigv4", + Args: Arguments{}, + Exports: auth.Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := sigv4authextension.NewFactory() diff --git a/component/otelcol/connector/connector.go b/component/otelcol/connector/connector.go index 2080c52030f5..ae43cb67b5fb 100644 --- a/component/otelcol/connector/connector.go +++ b/component/otelcol/connector/connector.go @@ -21,8 +21,6 @@ import ( otelextension "go.opentelemetry.io/collector/extension" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) const ( diff --git a/component/otelcol/connector/servicegraph/servicegraph.go b/component/otelcol/connector/servicegraph/servicegraph.go index e5370d89f620..ce171700569f 100644 --- a/component/otelcol/connector/servicegraph/servicegraph.go +++ b/component/otelcol/connector/servicegraph/servicegraph.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/connector" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river" "github.com/open-telemetry/opentelemetry-collector-contrib/connector/servicegraphconnector" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/servicegraphprocessor" @@ -16,9 +17,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.connector.servicegraph", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.connector.servicegraph", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := servicegraphconnector.NewFactory() diff --git a/component/otelcol/connector/spanmetrics/spanmetrics.go b/component/otelcol/connector/spanmetrics/spanmetrics.go index 87deb20623f2..583292c74e76 100644 --- a/component/otelcol/connector/spanmetrics/spanmetrics.go +++ b/component/otelcol/connector/spanmetrics/spanmetrics.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/connector" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river" "github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector" otelcomponent "go.opentelemetry.io/collector/component" @@ -16,9 +17,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.connector.spanmetrics", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.connector.spanmetrics", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := spanmetricsconnector.NewFactory() diff --git a/component/otelcol/exporter/exporter.go b/component/otelcol/exporter/exporter.go index 8333836cda16..bcd74aee60cc 100644 --- a/component/otelcol/exporter/exporter.go +++ b/component/otelcol/exporter/exporter.go @@ -21,8 +21,6 @@ import ( otelextension "go.opentelemetry.io/collector/extension" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) // Arguments is an extension of component.Arguments which contains necessary diff --git a/component/otelcol/exporter/jaeger/jaeger.go b/component/otelcol/exporter/jaeger/jaeger.go index dc64a2c54172..ca4cf1b84e57 100644 --- a/component/otelcol/exporter/jaeger/jaeger.go +++ b/component/otelcol/exporter/jaeger/jaeger.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/exporter" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/jaegerexporter" otelcomponent "go.opentelemetry.io/collector/component" otelpexporterhelper "go.opentelemetry.io/collector/exporter/exporterhelper" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.exporter.jaeger", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.exporter.jaeger", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := jaegerexporter.NewFactory() diff --git a/component/otelcol/exporter/loadbalancing/loadbalancing.go b/component/otelcol/exporter/loadbalancing/loadbalancing.go index 64a53b9d550f..d186c39b2091 100644 --- a/component/otelcol/exporter/loadbalancing/loadbalancing.go +++ b/component/otelcol/exporter/loadbalancing/loadbalancing.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/auth" "github.com/grafana/agent/component/otelcol/exporter" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river" "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter" otelcomponent "go.opentelemetry.io/collector/component" @@ -22,9 +23,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.exporter.loadbalancing", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.exporter.loadbalancing", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := loadbalancingexporter.NewFactory() diff --git a/component/otelcol/exporter/logging/logging.go b/component/otelcol/exporter/logging/logging.go index 23faa7cb69ec..9976c28b6209 100644 --- a/component/otelcol/exporter/logging/logging.go +++ b/component/otelcol/exporter/logging/logging.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/exporter" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" loggingexporter "go.opentelemetry.io/collector/exporter/loggingexporter" @@ -13,9 +14,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.exporter.logging", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.exporter.logging", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := loggingexporter.NewFactory() diff --git a/component/otelcol/exporter/otlp/otlp.go b/component/otelcol/exporter/otlp/otlp.go index 09c6aa332f8d..aea6fd02b4bb 100644 --- a/component/otelcol/exporter/otlp/otlp.go +++ b/component/otelcol/exporter/otlp/otlp.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/exporter" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" otelpexporterhelper "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/otlpexporter" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.exporter.otlp", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.exporter.otlp", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := otlpexporter.NewFactory() diff --git a/component/otelcol/exporter/otlphttp/otlphttp.go b/component/otelcol/exporter/otlphttp/otlphttp.go index 60d523394545..bf142960f6a9 100644 --- a/component/otelcol/exporter/otlphttp/otlphttp.go +++ b/component/otelcol/exporter/otlphttp/otlphttp.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/exporter" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/exporter/otlphttpexporter" otelextension "go.opentelemetry.io/collector/extension" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.exporter.otlphttp", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.exporter.otlphttp", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := otlphttpexporter.NewFactory() diff --git a/component/otelcol/extension/extension.go b/component/otelcol/extension/extension.go index e9f2d7fad99c..7997efde76bc 100644 --- a/component/otelcol/extension/extension.go +++ b/component/otelcol/extension/extension.go @@ -19,8 +19,6 @@ import ( otelextension "go.opentelemetry.io/collector/extension" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) // Arguments is an extension of component.Arguments which contains necessary diff --git a/component/otelcol/internal/featuregate/install.go b/component/otelcol/internal/featuregate/install.go deleted file mode 100644 index f2d1fdb79545..000000000000 --- a/component/otelcol/internal/featuregate/install.go +++ /dev/null @@ -1,38 +0,0 @@ -// Package featuregate automatically enables upstream feature gates that -// otelcol components require. The package must be imported for the feature -// gates to be enabled. -package featuregate - -import ( - "os" - - "go.opentelemetry.io/collector/featuregate" - - _ "go.opentelemetry.io/collector/obsreport" // telemetry.useOtelForInternalMetrics -) - -// TODO(rfratto): this package should be updated occasionally to remove feature -// gates which no longer exist. -// -// Once all feature gates are removed, this package can be removed as well. - -func init() { - _ = enableFeatureGates(featuregate.GlobalRegistry()) -} - -func enableFeatureGates(reg *featuregate.Registry) error { - // TODO(marctc): temporary workaround to fix issue with traces' metrics not - // being collected even flow is not enabled. - return reg.Set("telemetry.useOtelForInternalMetrics", isFlowRunning()) -} - -func isFlowRunning() bool { - key, _ := os.LookupEnv("AGENT_MODE") - - switch key { - case "flow": - return true - default: - return false - } -} diff --git a/component/otelcol/internal/featuregate/install_test.go b/component/otelcol/internal/featuregate/install_test.go deleted file mode 100644 index 9a5f22853587..000000000000 --- a/component/otelcol/internal/featuregate/install_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package featuregate - -import ( - "testing" - - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/featuregate" -) - -func Test_enableFeatureGates(t *testing.T) { - err := enableFeatureGates(featuregate.GlobalRegistry()) - require.NoError(t, err, "enableFeatureGates should not have a failed. Did a feature gate get removed from upstream?") -} diff --git a/component/otelcol/processor/attributes/attributes.go b/component/otelcol/processor/attributes/attributes.go index 93f774e54b55..c71eec8e1415 100644 --- a/component/otelcol/processor/attributes/attributes.go +++ b/component/otelcol/processor/attributes/attributes.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" "github.com/mitchellh/mapstructure" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor" otelcomponent "go.opentelemetry.io/collector/component" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.attributes", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.attributes", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := attributesprocessor.NewFactory() diff --git a/component/otelcol/processor/batch/batch.go b/component/otelcol/processor/batch/batch.go index 3c205a0e4320..6cc54fa5f333 100644 --- a/component/otelcol/processor/batch/batch.go +++ b/component/otelcol/processor/batch/batch.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" "go.opentelemetry.io/collector/processor/batchprocessor" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.batch", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.batch", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := batchprocessor.NewFactory() diff --git a/component/otelcol/processor/memorylimiter/memorylimiter.go b/component/otelcol/processor/memorylimiter/memorylimiter.go index edf3bb1016d0..0321d41cb5c4 100644 --- a/component/otelcol/processor/memorylimiter/memorylimiter.go +++ b/component/otelcol/processor/memorylimiter/memorylimiter.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" "go.opentelemetry.io/collector/processor/memorylimiterprocessor" @@ -16,9 +17,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.memory_limiter", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.memory_limiter", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := memorylimiterprocessor.NewFactory() diff --git a/component/otelcol/processor/probabilistic_sampler/probabilistic_sampler.go b/component/otelcol/processor/probabilistic_sampler/probabilistic_sampler.go index 13321e6af49e..72b8430de5e1 100644 --- a/component/otelcol/processor/probabilistic_sampler/probabilistic_sampler.go +++ b/component/otelcol/processor/probabilistic_sampler/probabilistic_sampler.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor" otelcomponent "go.opentelemetry.io/collector/component" @@ -13,9 +14,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.probabilistic_sampler", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.probabilistic_sampler", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := probabilisticsamplerprocessor.NewFactory() diff --git a/component/otelcol/processor/processor.go b/component/otelcol/processor/processor.go index 32dec14352fb..b6601651826b 100644 --- a/component/otelcol/processor/processor.go +++ b/component/otelcol/processor/processor.go @@ -21,8 +21,6 @@ import ( otelprocessor "go.opentelemetry.io/collector/processor" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) // Arguments is an extension of component.Arguments which contains necessary diff --git a/component/otelcol/processor/span/span.go b/component/otelcol/processor/span/span.go index 833a899d2c25..c62e8e108527 100644 --- a/component/otelcol/processor/span/span.go +++ b/component/otelcol/processor/span/span.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" "github.com/mitchellh/mapstructure" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/spanprocessor" otelcomponent "go.opentelemetry.io/collector/component" @@ -16,9 +17,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.span", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.span", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := spanprocessor.NewFactory() diff --git a/component/otelcol/processor/tail_sampling/tail_sampling.go b/component/otelcol/processor/tail_sampling/tail_sampling.go index dc2f33bb661d..0a17a49bd3da 100644 --- a/component/otelcol/processor/tail_sampling/tail_sampling.go +++ b/component/otelcol/processor/tail_sampling/tail_sampling.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/processor" + otel_service "github.com/grafana/agent/service/otel" tsp "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" @@ -15,9 +16,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.processor.tail_sampling", - Args: Arguments{}, - Exports: otelcol.ConsumerExports{}, + Name: "otelcol.processor.tail_sampling", + Args: Arguments{}, + Exports: otelcol.ConsumerExports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := tsp.NewFactory() diff --git a/component/otelcol/receiver/jaeger/jaeger.go b/component/otelcol/receiver/jaeger/jaeger.go index 2cebb37b9114..1858f7a909ba 100644 --- a/component/otelcol/receiver/jaeger/jaeger.go +++ b/component/otelcol/receiver/jaeger/jaeger.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/receiver" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver" otelcomponent "go.opentelemetry.io/collector/component" otelconfiggrpc "go.opentelemetry.io/collector/config/configgrpc" @@ -17,8 +18,9 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.jaeger", - Args: Arguments{}, + Name: "otelcol.receiver.jaeger", + Args: Arguments{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := jaegerreceiver.NewFactory() diff --git a/component/otelcol/receiver/kafka/kafka.go b/component/otelcol/receiver/kafka/kafka.go index f440cb8bb6f0..1e243fa9fc9b 100644 --- a/component/otelcol/receiver/kafka/kafka.go +++ b/component/otelcol/receiver/kafka/kafka.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/receiver" + otel_service "github.com/grafana/agent/service/otel" "github.com/grafana/river/rivertypes" "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/kafkaexporter" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kafkareceiver" @@ -16,8 +17,9 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.kafka", - Args: Arguments{}, + Name: "otelcol.receiver.kafka", + Args: Arguments{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := kafkareceiver.NewFactory() diff --git a/component/otelcol/receiver/opencensus/opencensus.go b/component/otelcol/receiver/opencensus/opencensus.go index 7f4c64ee0ace..63df3da32118 100644 --- a/component/otelcol/receiver/opencensus/opencensus.go +++ b/component/otelcol/receiver/opencensus/opencensus.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/receiver" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/opencensusreceiver" otelcomponent "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/extension" @@ -13,8 +14,9 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.opencensus", - Args: Arguments{}, + Name: "otelcol.receiver.opencensus", + Args: Arguments{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := opencensusreceiver.NewFactory() diff --git a/component/otelcol/receiver/otlp/otlp.go b/component/otelcol/receiver/otlp/otlp.go index 4fa33c18202d..8d7b7defdd25 100644 --- a/component/otelcol/receiver/otlp/otlp.go +++ b/component/otelcol/receiver/otlp/otlp.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/receiver" + otel_service "github.com/grafana/agent/service/otel" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" "go.opentelemetry.io/collector/receiver/otlpreceiver" @@ -13,8 +14,9 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.otlp", - Args: Arguments{}, + Name: "otelcol.receiver.otlp", + Args: Arguments{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := otlpreceiver.NewFactory() diff --git a/component/otelcol/receiver/prometheus/prometheus.go b/component/otelcol/receiver/prometheus/prometheus.go index 68c046a900db..4594e6192e36 100644 --- a/component/otelcol/receiver/prometheus/prometheus.go +++ b/component/otelcol/receiver/prometheus/prometheus.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/agent/component/otelcol/receiver/prometheus/internal" "github.com/grafana/agent/pkg/build" "github.com/grafana/agent/pkg/util/zapadapter" + otel_service "github.com/grafana/agent/service/otel" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/storage" otelcomponent "go.opentelemetry.io/collector/component" @@ -25,9 +26,10 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.prometheus", - Args: Arguments{}, - Exports: Exports{}, + Name: "otelcol.receiver.prometheus", + Args: Arguments{}, + Exports: Exports{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(o component.Options, a component.Arguments) (component.Component, error) { return New(o, a.(Arguments)) diff --git a/component/otelcol/receiver/receiver.go b/component/otelcol/receiver/receiver.go index 399c771c25fd..6e76c1591e89 100644 --- a/component/otelcol/receiver/receiver.go +++ b/component/otelcol/receiver/receiver.go @@ -21,8 +21,6 @@ import ( otelreceiver "go.opentelemetry.io/collector/receiver" sdkprometheus "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" - - _ "github.com/grafana/agent/component/otelcol/internal/featuregate" // Enable needed feature gates ) // Arguments is an extension of component.Arguments which contains necessary diff --git a/component/otelcol/receiver/zipkin/zipkin.go b/component/otelcol/receiver/zipkin/zipkin.go index 1727d38a0d05..50ac8fb23cb7 100644 --- a/component/otelcol/receiver/zipkin/zipkin.go +++ b/component/otelcol/receiver/zipkin/zipkin.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/agent/component" "github.com/grafana/agent/component/otelcol" "github.com/grafana/agent/component/otelcol/receiver" + otel_service "github.com/grafana/agent/service/otel" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver" otelcomponent "go.opentelemetry.io/collector/component" otelextension "go.opentelemetry.io/collector/extension" @@ -12,8 +13,9 @@ import ( func init() { component.Register(component.Registration{ - Name: "otelcol.receiver.zipkin", - Args: Arguments{}, + Name: "otelcol.receiver.zipkin", + Args: Arguments{}, + NeedsServices: []string{otel_service.ServiceName}, Build: func(opts component.Options, args component.Arguments) (component.Component, error) { fact := zipkinreceiver.NewFactory() diff --git a/docs/sources/flow/reference/components/otelcol.exporter.otlp.md b/docs/sources/flow/reference/components/otelcol.exporter.otlp.md index 04500a8a1cd0..1328fcf9dc99 100644 --- a/docs/sources/flow/reference/components/otelcol.exporter.otlp.md +++ b/docs/sources/flow/reference/components/otelcol.exporter.otlp.md @@ -168,6 +168,11 @@ configuration. `otelcol.exporter.otlp` does not expose any component-specific debug information. +## Debug metrics + +* `exporter_sent_spans_ratio_total` (counter): Number of spans successfully sent to destination. +* `exporter_send_failed_spans_ratio_total` (counter): Number of spans in failed attempts to send to destination. + ## Examples The following examples show you how to create an exporter to send data to different destinations. diff --git a/docs/sources/flow/reference/components/otelcol.processor.batch.md b/docs/sources/flow/reference/components/otelcol.processor.batch.md index 4ae6f5ae57ae..e4544393910b 100644 --- a/docs/sources/flow/reference/components/otelcol.processor.batch.md +++ b/docs/sources/flow/reference/components/otelcol.processor.batch.md @@ -119,6 +119,12 @@ configuration. `otelcol.processor.batch` does not expose any component-specific debug information. +## Debug metrics + +* `processor_batch_batch_send_size_ratio` (histogram): Number of units in the batch. +* `processor_batch_metadata_cardinality_ratio` (gauge): Number of distinct metadata value combinations being processed. +* `processor_batch_timeout_trigger_send_ratio_total` (counter): Number of times the batch was sent due to a timeout trigger. + ## Examples ### Basic usage diff --git a/docs/sources/flow/reference/components/otelcol.receiver.otlp.md b/docs/sources/flow/reference/components/otelcol.receiver.otlp.md index b50683bdd392..8d06b1a9ce9e 100644 --- a/docs/sources/flow/reference/components/otelcol.receiver.otlp.md +++ b/docs/sources/flow/reference/components/otelcol.receiver.otlp.md @@ -197,6 +197,12 @@ configuration. `otelcol.receiver.otlp` does not expose any component-specific debug information. +## Debug metrics + +* `receiver_accepted_spans_ratio_total` (counter): Number of spans successfully pushed into the pipeline. +* `receiver_refused_spans_ratio_total` (counter): Number of spans that could not be pushed into the pipeline. +* `rpc_server_duration_milliseconds` (histogram): Duration of RPC requests from a gRPC server. + ## Example This example forwards received telemetry data through a batch processor before diff --git a/pkg/traces/instance.go b/pkg/traces/instance.go index dbab2df3aa4b..855b5b81a133 100644 --- a/pkg/traces/instance.go +++ b/pkg/traces/instance.go @@ -10,7 +10,6 @@ import ( "go.opentelemetry.io/collector/connector" otelexporter "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" - "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/receiver" @@ -133,23 +132,7 @@ func (i *Instance) buildAndStartPipeline(ctx context.Context, cfg InstanceConfig Version: build.Version, } - // useOtelForInternalMetrics is required so that the Collector service configures Collector components using the Otel SDK - // instead of OpenCensus. If this is not specified, then the OtelMetricViews and OtelMetricReader parameters which we - // pass to service.New() below will not be taken into account. This would mean that metrics from custom components such as - // the one in pkg/traces/servicegraphprocessor would not work. - // - // disableHighCardinalityMetrics is required so that we don't include labels containing ports and IP addresses in gRPC metrics. - // Example metric with high cardinality... - // rpc_server_duration_bucket{net_sock_peer_addr="127.0.0.1",net_sock_peer_port="59947",rpc_grpc_status_code="0",rpc_method="Export",rpc_service="opentelemetry.proto.collector.trace.v1.TraceService",rpc_system="grpc",traces_config="default",le="7500"} 294 - // ... the same metric when disableHighCardinalityMetrics is switched on looks like this: - // rpc_server_duration_bucket{rpc_grpc_status_code="0",rpc_method="Export",rpc_service="opentelemetry.proto.collector.trace.v1.TraceService",rpc_system="grpc",traces_config="default",le="7500"} 32 - // For more context: - // https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/rpc-metrics/ - // https://github.com/open-telemetry/opentelemetry-go-contrib/pull/2700 - // https://github.com/open-telemetry/opentelemetry-collector/pull/6788/files - err = enableOtelFeatureGates( - "telemetry.useOtelForInternalMetrics", - "telemetry.disableHighCardinalityMetrics") + err = util.SetupStaticModeOtelFeatureGates() if err != nil { return err } @@ -190,19 +173,6 @@ func (i *Instance) buildAndStartPipeline(ctx context.Context, cfg InstanceConfig return err } -func enableOtelFeatureGates(fgNames ...string) error { - fgReg := featuregate.GlobalRegistry() - - for _, fg := range fgNames { - err := fgReg.Set(fg, true) - if err != nil { - return fmt.Errorf("error setting Otel feature gate: %w", err) - } - } - - return nil -} - // ReportFatalError implements component.Host func (i *Instance) ReportFatalError(err error) { i.logger.Error("fatal error reported", zap.Error(err)) diff --git a/pkg/util/otel_feature_gate.go b/pkg/util/otel_feature_gate.go new file mode 100644 index 000000000000..d2f4797668e7 --- /dev/null +++ b/pkg/util/otel_feature_gate.go @@ -0,0 +1,67 @@ +package util + +import ( + "fmt" + + "go.opentelemetry.io/collector/featuregate" + _ "go.opentelemetry.io/collector/obsreport" +) + +// Enables a set of feature gates in Otel's Global Feature Gate Registry. +func EnableOtelFeatureGates(fgNames ...string) error { + fgReg := featuregate.GlobalRegistry() + + for _, fg := range fgNames { + err := fgReg.Set(fg, true) + if err != nil { + return fmt.Errorf("error setting Otel feature gate: %w", err) + } + } + + return nil +} + +var ( + // useOtelForInternalMetrics is required so that the Collector service configures Collector components using the Otel SDK + // instead of OpenCensus. If this is not specified, then the OtelMetricViews and OtelMetricReader parameters which we + // pass to service.New() below will not be taken into account. This would mean that metrics from custom components such as + // the one in pkg/traces/servicegraphprocessor would not work. + // + // disableHighCardinalityMetrics is required so that we don't include labels containing ports and IP addresses in gRPC metrics. + // Example metric with high cardinality... + // rpc_server_duration_bucket{net_sock_peer_addr="127.0.0.1",net_sock_peer_port="59947",rpc_grpc_status_code="0",rpc_method="Export",rpc_service="opentelemetry.proto.collector.trace.v1.TraceService",rpc_system="grpc",traces_config="default",le="7500"} 294 + // ... the same metric when disableHighCardinalityMetrics is switched on looks like this: + // rpc_server_duration_bucket{rpc_grpc_status_code="0",rpc_method="Export",rpc_service="opentelemetry.proto.collector.trace.v1.TraceService",rpc_system="grpc",traces_config="default",le="7500"} 32 + // For more context: + // https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/rpc-metrics/ + // https://github.com/open-telemetry/opentelemetry-go-contrib/pull/2700 + // https://github.com/open-telemetry/opentelemetry-collector/pull/6788/files + // + // TODO: Remove "telemetry.useOtelForInternalMetrics" when Collector components + // use OpenTelemetry metrics by default. + staticModeOtelFeatureGates = []string{ + "telemetry.useOtelForInternalMetrics", + "telemetry.disableHighCardinalityMetrics", + } + + // Enable the "telemetry.useOtelForInternalMetrics" Collector feature gate. + // Currently, Collector components uses OpenCensus metrics by default. + // Those metrics cannot be integrated with Agent Flow, + // so we need to always use OpenTelemetry metrics. + // + // TODO: Remove "telemetry.useOtelForInternalMetrics" when Collector components + // use OpenTelemetry metrics by default. + flowModeOtelFeatureGates = []string{ + "telemetry.useOtelForInternalMetrics", + } +) + +// Enables a set of feature gates which should always be enabled for Static mode. +func SetupStaticModeOtelFeatureGates() error { + return EnableOtelFeatureGates(staticModeOtelFeatureGates...) +} + +// Enables a set of feature gates which should always be enabled for Flow mode. +func SetupFlowModeOtelFeatureGates() error { + return EnableOtelFeatureGates(flowModeOtelFeatureGates...) +} diff --git a/pkg/util/otel_feature_gate_test.go b/pkg/util/otel_feature_gate_test.go new file mode 100644 index 000000000000..76fd8ef1f72f --- /dev/null +++ b/pkg/util/otel_feature_gate_test.go @@ -0,0 +1,44 @@ +package util + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/featuregate" +) + +func Test_FeatureGates(t *testing.T) { + reg := featuregate.GlobalRegistry() + + fgSet := make(map[string]struct{}) + + for _, fg := range staticModeOtelFeatureGates { + fgSet[fg] = struct{}{} + } + for _, fg := range flowModeOtelFeatureGates { + fgSet[fg] = struct{}{} + } + + reg.VisitAll(func(g *featuregate.Gate) { + if _, ok := fgSet[g.ID()]; !ok { + return + } + // Make sure that the feature gate is disabled before touching it. + // There is no point in the Agent enabling a feature gate + // if it's already enabled in the Collector. + // This "require" check will fail if the Collector was upgraded and + // a feature gate was promoted from alpha to beta. + require.Falsef(t, g.IsEnabled(), "feature gate %s is enabled - should it be removed from the Agent?", g.ID()) + }) + + require.NoError(t, SetupStaticModeOtelFeatureGates()) + require.NoError(t, SetupFlowModeOtelFeatureGates()) + + reg.VisitAll(func(g *featuregate.Gate) { + if _, ok := fgSet[g.ID()]; !ok { + return + } + // Make sure that the Agent enabled the gate. + require.True(t, g.IsEnabled()) + }) +} diff --git a/service/otel/otel.go b/service/otel/otel.go new file mode 100644 index 000000000000..c33de5f7c98e --- /dev/null +++ b/service/otel/otel.go @@ -0,0 +1,54 @@ +// Package otel implements the otel service for Flow. +// This service registers feature gates will be used by the otelcol components +// based on upstream Collector components. +package otel + +import ( + "context" + "fmt" + + "github.com/grafana/agent/pkg/util" + "github.com/grafana/agent/service" +) + +// ServiceName defines the name used for the otel service. +const ServiceName = "otel" + +type Service struct{} + +var _ service.Service = (*Service)(nil) + +func New() *Service { + return &Service{} +} + +// Data implements service.Service. It returns nil, as the otel service does +// not have any runtime data. +func (*Service) Data() any { + return nil +} + +// Definition implements service.Service. +func (*Service) Definition() service.Definition { + return service.Definition{ + Name: ServiceName, + ConfigType: nil, // otel does not accept configuration + DependsOn: []string{}, + } +} + +// Run implements service.Service. +func (*Service) Run(ctx context.Context, host service.Host) error { + err := util.SetupFlowModeOtelFeatureGates() + if err != nil { + return err + } + + <-ctx.Done() + return nil +} + +// Update implements service.Service. +func (*Service) Update(newConfig any) error { + return fmt.Errorf("otel service does not support configuration") +}