From f2c56a3752350c4e2b060127cb81df5e56fcce5e Mon Sep 17 00:00:00 2001 From: Daniel Jaglowski Date: Tue, 16 Jul 2024 10:21:42 -0500 Subject: [PATCH] Enhance builder to capture go module for each component type (#10599) Resolves #10570 Alternative to #10598 This implementation is more reliable that #10598 because it gets information directly from the builder manifest. It relies on additional structure in the `component.go` file, ultimately encoded in `otelcol.Factories`. An alternative would be to push the enhancements deeper, into the `.Factories` implementations, so that the module information is available directly alongside the Factory. --- .chloggen/module-info-builder.yaml | 25 ++++++++++++++ .chloggen/module-info-components.yaml | 25 ++++++++++++++ cmd/builder/internal/builder/config.go | 15 ++++++--- .../builder/templates/components.go.tmpl | 33 +++++++++++++++++++ otelcol/command_components.go | 16 ++++++--- otelcol/factories.go | 15 +++++++++ otelcol/factories_test.go | 20 +++++++++++ otelcol/testdata/components-output.yaml | 6 ++++ 8 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 .chloggen/module-info-builder.yaml create mode 100644 .chloggen/module-info-components.yaml diff --git a/.chloggen/module-info-builder.yaml b/.chloggen/module-info-builder.yaml new file mode 100644 index 00000000000..8b106cd315e --- /dev/null +++ b/.chloggen/module-info-builder.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: cmd/builder + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add go module info the builder generated code. + +# One or more tracking issues or pull requests related to the change +issues: [10570] + +# (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/.chloggen/module-info-components.yaml b/.chloggen/module-info-components.yaml new file mode 100644 index 00000000000..51ba4e1cc32 --- /dev/null +++ b/.chloggen/module-info-components.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: otelcol + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add go module to components subcommand. + +# One or more tracking issues or pull requests related to the change +issues: [10570] + +# (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/builder/internal/builder/config.go b/cmd/builder/internal/builder/config.go index 45636cd5fdf..a578694fcc3 100644 --- a/cmd/builder/internal/builder/config.go +++ b/cmd/builder/internal/builder/config.go @@ -64,6 +64,7 @@ type Distribution struct { OtelColVersion string `mapstructure:"otelcol_version"` RequireOtelColModule bool `mapstructure:"-"` // required for backwards-compatibility with builds older than 0.86.0 SupportsConfmapFactories bool `mapstructure:"-"` // Required for backwards-compatibility with builds older than 0.99.0 + SupportsComponentModules bool `mapstructure:"-"` // Required for backwards-compatibility with builds older than 0.105.0 OutputPath string `mapstructure:"output_path"` Version string `mapstructure:"version"` BuildTags string `mapstructure:"build_tags"` @@ -144,13 +145,14 @@ func (c *Config) SetGoPath() error { } func (c *Config) SetBackwardsCompatibility() error { - // check whether we need to adjust the core API module import - constraint, err := version.NewConstraint(">= 0.86.0") + // Get the version of the collector + otelColVersion, err := version.NewVersion(c.Distribution.OtelColVersion) if err != nil { return err } - otelColVersion, err := version.NewVersion(c.Distribution.OtelColVersion) + // check whether we need to adjust the core API module import + constraint, err := version.NewConstraint(">= 0.86.0") if err != nil { return err } @@ -163,12 +165,15 @@ func (c *Config) SetBackwardsCompatibility() error { return err } - otelColVersion, err = version.NewVersion(c.Distribution.OtelColVersion) + c.Distribution.SupportsConfmapFactories = constraint.Check(otelColVersion) + + // check whether go modules are recorded for components + constraint, err = version.NewConstraint(">= 0.105.0") if err != nil { return err } - c.Distribution.SupportsConfmapFactories = constraint.Check(otelColVersion) + c.Distribution.SupportsComponentModules = constraint.Check(otelColVersion) return nil } diff --git a/cmd/builder/internal/builder/templates/components.go.tmpl b/cmd/builder/internal/builder/templates/components.go.tmpl index 0c620733ebf..e39117bd431 100644 --- a/cmd/builder/internal/builder/templates/components.go.tmpl +++ b/cmd/builder/internal/builder/templates/components.go.tmpl @@ -3,6 +3,9 @@ package main import ( + {{- if .Distribution.SupportsComponentModules}} + "go.opentelemetry.io/collector/component" + {{- end}} "go.opentelemetry.io/collector/connector" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/extension" @@ -38,6 +41,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } + {{- if .Distribution.SupportsComponentModules}} + factories.ExtensionModules = make(map[component.Type]string, len(factories.Extensions)) + {{- range .Extensions}} + factories.ExtensionModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" + {{- end}} + {{- end}} factories.Receivers, err = receiver.MakeFactoryMap( {{- range .Receivers}} @@ -47,6 +56,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } + {{- if .Distribution.SupportsComponentModules}} + factories.ReceiverModules = make(map[component.Type]string, len(factories.Receivers)) + {{- range .Receivers}} + factories.ReceiverModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" + {{- end}} + {{- end}} factories.Exporters, err = exporter.MakeFactoryMap( {{- range .Exporters}} @@ -56,6 +71,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } + {{- if .Distribution.SupportsComponentModules}} + factories.ExporterModules = make(map[component.Type]string, len(factories.Exporters)) + {{- range .Exporters}} + factories.ExporterModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" + {{- end}} + {{- end}} factories.Processors, err = processor.MakeFactoryMap( {{- range .Processors}} @@ -65,6 +86,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } + {{- if .Distribution.SupportsComponentModules}} + factories.ProcessorModules = make(map[component.Type]string, len(factories.Processors)) + {{- range .Processors}} + factories.ProcessorModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" + {{- end}} + {{- end}} factories.Connectors, err = connector.MakeFactoryMap( {{- range .Connectors}} @@ -74,6 +101,12 @@ func components() (otelcol.Factories, error) { if err != nil { return otelcol.Factories{}, err } + {{- if .Distribution.SupportsComponentModules}} + factories.ConnectorModules = make(map[component.Type]string, len(factories.Connectors)) + {{- range .Connectors}} + factories.ConnectorModules[{{.Name}}.NewFactory().Type()] = "{{.GoMod}}" + {{- end}} + {{- end}} return factories, nil } diff --git a/otelcol/command_components.go b/otelcol/command_components.go index da13d6779a7..819e189c4d8 100644 --- a/otelcol/command_components.go +++ b/otelcol/command_components.go @@ -20,6 +20,7 @@ import ( type componentWithStability struct { Name component.Type + Module string Stability map[string]string } @@ -49,7 +50,8 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { components := componentsOutput{} for _, con := range sortFactoriesByType[connector.Factory](factories.Connectors) { components.Connectors = append(components.Connectors, componentWithStability{ - Name: con.Type(), + Name: con.Type(), + Module: factories.ConnectorModules[con.Type()], Stability: map[string]string{ "logs-to-logs": con.LogsToLogsStability().String(), "logs-to-metrics": con.LogsToMetricsStability().String(), @@ -67,7 +69,8 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { } for _, ext := range sortFactoriesByType[extension.Factory](factories.Extensions) { components.Extensions = append(components.Extensions, componentWithStability{ - Name: ext.Type(), + Name: ext.Type(), + Module: factories.ExtensionModules[ext.Type()], Stability: map[string]string{ "extension": ext.ExtensionStability().String(), }, @@ -75,7 +78,8 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { } for _, prs := range sortFactoriesByType[processor.Factory](factories.Processors) { components.Processors = append(components.Processors, componentWithStability{ - Name: prs.Type(), + Name: prs.Type(), + Module: factories.ProcessorModules[prs.Type()], Stability: map[string]string{ "logs": prs.LogsProcessorStability().String(), "metrics": prs.MetricsProcessorStability().String(), @@ -85,7 +89,8 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { } for _, rcv := range sortFactoriesByType[receiver.Factory](factories.Receivers) { components.Receivers = append(components.Receivers, componentWithStability{ - Name: rcv.Type(), + Name: rcv.Type(), + Module: factories.ReceiverModules[rcv.Type()], Stability: map[string]string{ "logs": rcv.LogsReceiverStability().String(), "metrics": rcv.MetricsReceiverStability().String(), @@ -95,7 +100,8 @@ func newComponentsCommand(set CollectorSettings) *cobra.Command { } for _, exp := range sortFactoriesByType[exporter.Factory](factories.Exporters) { components.Exporters = append(components.Exporters, componentWithStability{ - Name: exp.Type(), + Name: exp.Type(), + Module: factories.ExporterModules[exp.Type()], Stability: map[string]string{ "logs": exp.LogsExporterStability().String(), "metrics": exp.MetricsExporterStability().String(), diff --git a/otelcol/factories.go b/otelcol/factories.go index a61bd05060b..7528fa00666 100644 --- a/otelcol/factories.go +++ b/otelcol/factories.go @@ -29,4 +29,19 @@ type Factories struct { // Connectors maps connector type names in the config to the respective factory. Connectors map[component.Type]connector.Factory + + // ReceiverModules maps receiver types to their respective go modules. + ReceiverModules map[component.Type]string + + // ProcessorModules maps processor types to their respective go modules. + ProcessorModules map[component.Type]string + + // ExporterModules maps exporter types to their respective go modules. + ExporterModules map[component.Type]string + + // ExtensionModules maps extension types to their respective go modules. + ExtensionModules map[component.Type]string + + // ConnectorModules maps connector types to their respective go modules. + ConnectorModules map[component.Type]string } diff --git a/otelcol/factories_test.go b/otelcol/factories_test.go index 965ea91844b..19d6fe6accc 100644 --- a/otelcol/factories_test.go +++ b/otelcol/factories_test.go @@ -24,22 +24,42 @@ func nopFactories() (Factories, error) { if factories.Connectors, err = connector.MakeFactoryMap(connectortest.NewNopFactory()); err != nil { return Factories{}, err } + factories.ConnectorModules = make(map[component.Type]string, len(factories.Connectors)) + for _, con := range factories.Connectors { + factories.ConnectorModules[con.Type()] = "go.opentelemetry.io/collector/connector/connectortest v1.2.3" + } if factories.Extensions, err = extension.MakeFactoryMap(extensiontest.NewNopFactory()); err != nil { return Factories{}, err } + factories.ExtensionModules = make(map[component.Type]string, len(factories.Extensions)) + for _, ext := range factories.Extensions { + factories.ExtensionModules[ext.Type()] = "go.opentelemetry.io/collector/extension/extensiontest v1.2.3" + } if factories.Receivers, err = receiver.MakeFactoryMap(receivertest.NewNopFactory(), receivertest.NewNopFactoryForType(component.DataTypeLogs)); err != nil { return Factories{}, err } + factories.ReceiverModules = make(map[component.Type]string, len(factories.Receivers)) + for _, rec := range factories.Receivers { + factories.ReceiverModules[rec.Type()] = "go.opentelemetry.io/collector/receiver/receivertest v1.2.3" + } if factories.Exporters, err = exporter.MakeFactoryMap(exportertest.NewNopFactory()); err != nil { return Factories{}, err } + factories.ExporterModules = make(map[component.Type]string, len(factories.Exporters)) + for _, exp := range factories.Exporters { + factories.ExporterModules[exp.Type()] = "go.opentelemetry.io/collector/exporter/exportertest v1.2.3" + } if factories.Processors, err = processor.MakeFactoryMap(processortest.NewNopFactory()); err != nil { return Factories{}, err } + factories.ProcessorModules = make(map[component.Type]string, len(factories.Processors)) + for _, proc := range factories.Processors { + factories.ProcessorModules[proc.Type()] = "go.opentelemetry.io/collector/processor/processortest v1.2.3" + } return factories, err } diff --git a/otelcol/testdata/components-output.yaml b/otelcol/testdata/components-output.yaml index 929ae01945b..cbf14a619e1 100644 --- a/otelcol/testdata/components-output.yaml +++ b/otelcol/testdata/components-output.yaml @@ -4,29 +4,34 @@ buildinfo: version: latest receivers: - name: nop + module: go.opentelemetry.io/collector/receiver/receivertest v1.2.3 stability: logs: Stable metrics: Stable traces: Stable - name: nop_logs + module: go.opentelemetry.io/collector/receiver/receivertest v1.2.3 stability: logs: Stable metrics: Undefined traces: Undefined processors: - name: nop + module: go.opentelemetry.io/collector/processor/processortest v1.2.3 stability: logs: Stable metrics: Stable traces: Stable exporters: - name: nop + module: go.opentelemetry.io/collector/exporter/exportertest v1.2.3 stability: logs: Stable metrics: Stable traces: Stable connectors: - name: nop + module: go.opentelemetry.io/collector/connector/connectortest v1.2.3 stability: logs-to-logs: Development logs-to-metrics: Development @@ -39,5 +44,6 @@ connectors: traces-to-traces: Development extensions: - name: nop + module: go.opentelemetry.io/collector/extension/extensiontest v1.2.3 stability: extension: Stable