diff --git a/cmd/builder/internal/builder/main_test.go b/cmd/builder/internal/builder/main_test.go index e666622a3fb..e0820813dae 100644 --- a/cmd/builder/internal/builder/main_test.go +++ b/cmd/builder/internal/builder/main_test.go @@ -67,6 +67,7 @@ var ( "/connector/connectorprofiles", "/exporter", "/exporter/debugexporter", + "/exporter/exporterprofiles", "/exporter/nopexporter", "/exporter/otlpexporter", "/exporter/otlphttpexporter", diff --git a/cmd/otelcorecol/builder-config.yaml b/cmd/otelcorecol/builder-config.yaml index 01a71eee715..027817dc370 100644 --- a/cmd/otelcorecol/builder-config.yaml +++ b/cmd/otelcorecol/builder-config.yaml @@ -71,6 +71,7 @@ replaces: - go.opentelemetry.io/collector/connector/forwardconnector => ../../connector/forwardconnector - go.opentelemetry.io/collector/exporter => ../../exporter - go.opentelemetry.io/collector/exporter/debugexporter => ../../exporter/debugexporter + - go.opentelemetry.io/collector/exporter/exporterprofiles => ../../exporter/exporterprofiles - go.opentelemetry.io/collector/exporter/loggingexporter => ../../exporter/loggingexporter - go.opentelemetry.io/collector/exporter/nopexporter => ../../exporter/nopexporter - go.opentelemetry.io/collector/exporter/otlpexporter => ../../exporter/otlpexporter diff --git a/cmd/otelcorecol/go.mod b/cmd/otelcorecol/go.mod index af1a1ad1f6c..016b72f8be0 100644 --- a/cmd/otelcorecol/go.mod +++ b/cmd/otelcorecol/go.mod @@ -98,6 +98,7 @@ require ( go.opentelemetry.io/collector/consumer v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect go.opentelemetry.io/collector/featuregate v1.14.1 // indirect go.opentelemetry.io/collector/internal/globalgates v0.108.1 // indirect @@ -206,6 +207,8 @@ replace go.opentelemetry.io/collector/exporter => ../../exporter replace go.opentelemetry.io/collector/exporter/debugexporter => ../../exporter/debugexporter +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../../exporter/exporterprofiles + replace go.opentelemetry.io/collector/exporter/loggingexporter => ../../exporter/loggingexporter replace go.opentelemetry.io/collector/exporter/nopexporter => ../../exporter/nopexporter diff --git a/exporter/debugexporter/go.mod b/exporter/debugexporter/go.mod index 090f19e6707..7f3d9e9ff9f 100644 --- a/exporter/debugexporter/go.mod +++ b/exporter/debugexporter/go.mod @@ -44,6 +44,7 @@ require ( go.opentelemetry.io/collector/config/configretry v1.14.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect go.opentelemetry.io/collector/receiver v0.108.1 // indirect @@ -97,3 +98,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporterprofiles diff --git a/exporter/exportertest/nop_exporter.go b/exporter/exportertest/nop_exporter.go index 73abe305df8..806f879bfab 100644 --- a/exporter/exportertest/nop_exporter.go +++ b/exporter/exportertest/nop_exporter.go @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterprofiles" ) var nopType = component.MustNewType("nop") @@ -33,6 +34,7 @@ func NewNopFactory() exporter.Factory { exporter.WithTraces(createTracesExporter, component.StabilityLevelStable), exporter.WithMetrics(createMetricsExporter, component.StabilityLevelStable), exporter.WithLogs(createLogsExporter, component.StabilityLevelStable), + exporterprofiles.WithProfiles(createProfilesExporter, component.StabilityLevelAlpha), ) } @@ -48,13 +50,17 @@ func createLogsExporter(context.Context, exporter.Settings, component.Config) (e return nopInstance, nil } +func createProfilesExporter(context.Context, exporter.Settings, component.Config) (exporterprofiles.Profiles, error) { + return nopInstance, nil +} + type nopConfig struct{} var nopInstance = &nopExporter{ Consumer: consumertest.NewNop(), } -// nopExporter stores consumed traces and metrics for testing purposes. +// nopExporter stores consumed traces, metrics, logs and profiles for testing purposes. type nopExporter struct { component.StartFunc component.ShutdownFunc diff --git a/exporter/exportertest/nop_exporter_test.go b/exporter/exportertest/nop_exporter_test.go index 43a7f74d61b..456d7c89c48 100644 --- a/exporter/exportertest/nop_exporter_test.go +++ b/exporter/exportertest/nop_exporter_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/pdata/ptrace" ) @@ -41,6 +42,12 @@ func TestNewNopFactory(t *testing.T) { assert.NoError(t, logs.Start(context.Background(), componenttest.NewNopHost())) assert.NoError(t, logs.ConsumeLogs(context.Background(), plog.NewLogs())) assert.NoError(t, logs.Shutdown(context.Background())) + + profiles, err := factory.CreateProfilesExporter(context.Background(), NewNopSettings(), cfg) + require.NoError(t, err) + assert.NoError(t, profiles.Start(context.Background(), componenttest.NewNopHost())) + assert.NoError(t, profiles.ConsumeProfiles(context.Background(), pprofile.NewProfiles())) + assert.NoError(t, profiles.Shutdown(context.Background())) } func TestNewNopBuilder(t *testing.T) { diff --git a/exporter/go.mod b/exporter/go.mod index 02090415e1a..1c34fa9654f 100644 --- a/exporter/go.mod +++ b/exporter/go.mod @@ -13,8 +13,10 @@ require ( go.opentelemetry.io/collector/consumer v0.108.1 go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 go.opentelemetry.io/collector/consumer/consumertest v0.108.1 + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 go.opentelemetry.io/collector/extension v0.108.1 go.opentelemetry.io/collector/pdata v1.14.1 + go.opentelemetry.io/collector/pdata/pprofile v0.108.1 go.opentelemetry.io/collector/pdata/testdata v0.108.1 go.opentelemetry.io/collector/receiver v0.108.1 go.opentelemetry.io/otel v1.29.0 @@ -54,7 +56,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/collector/component/componentstatus v0.108.1 // indirect go.opentelemetry.io/collector/confmap v1.14.1 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect go.opentelemetry.io/collector/receiver/receiverprofiles v0.108.1 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.51.0 // indirect golang.org/x/net v0.28.0 // indirect @@ -97,3 +98,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../consumer/consu replace go.opentelemetry.io/collector/component/componentstatus => ../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ./exporterprofiles diff --git a/exporter/loggingexporter/go.mod b/exporter/loggingexporter/go.mod index c824b396da8..9c76c8dcf5d 100644 --- a/exporter/loggingexporter/go.mod +++ b/exporter/loggingexporter/go.mod @@ -44,6 +44,7 @@ require ( go.opentelemetry.io/collector/consumer v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect go.opentelemetry.io/collector/receiver v0.108.1 // indirect @@ -102,3 +103,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporterprofiles diff --git a/exporter/nopexporter/go.mod b/exporter/nopexporter/go.mod index aa8cb2cd619..45071c14648 100644 --- a/exporter/nopexporter/go.mod +++ b/exporter/nopexporter/go.mod @@ -39,6 +39,7 @@ require ( go.opentelemetry.io/collector/config/configtelemetry v0.108.1 // indirect go.opentelemetry.io/collector/consumer v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect go.opentelemetry.io/collector/receiver v0.108.1 // indirect go.opentelemetry.io/collector/receiver/receiverprofiles v0.108.1 // indirect @@ -92,3 +93,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporterprofiles diff --git a/exporter/otlpexporter/go.mod b/exporter/otlpexporter/go.mod index 109767ca780..67c16070450 100644 --- a/exporter/otlpexporter/go.mod +++ b/exporter/otlpexporter/go.mod @@ -60,6 +60,7 @@ require ( go.opentelemetry.io/collector/config/internal v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect go.opentelemetry.io/collector/featuregate v1.14.1 // indirect @@ -150,3 +151,5 @@ replace go.opentelemetry.io/collector/consumer/consumertest => ../../consumer/co replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporterprofiles diff --git a/exporter/otlphttpexporter/go.mod b/exporter/otlphttpexporter/go.mod index dfedaa452b9..5daf82e89bb 100644 --- a/exporter/otlphttpexporter/go.mod +++ b/exporter/otlphttpexporter/go.mod @@ -59,6 +59,7 @@ require ( go.opentelemetry.io/collector/config/internal v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect go.opentelemetry.io/collector/featuregate v1.14.1 // indirect @@ -147,3 +148,5 @@ replace go.opentelemetry.io/collector/client => ../../client replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receiver/receiverprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporterprofiles diff --git a/internal/e2e/go.mod b/internal/e2e/go.mod index 174e7cf4342..bd619093a07 100644 --- a/internal/e2e/go.mod +++ b/internal/e2e/go.mod @@ -78,6 +78,7 @@ require ( go.opentelemetry.io/collector/config/internal v0.108.1 // indirect go.opentelemetry.io/collector/connector/connectorprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect go.opentelemetry.io/collector/featuregate v1.14.1 // indirect go.opentelemetry.io/collector/internal/globalgates v0.108.1 // indirect @@ -197,3 +198,5 @@ replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receive replace go.opentelemetry.io/collector/processor/processorprofiles => ../../processor/processorprofiles replace go.opentelemetry.io/collector/connector/connectorprofiles => ../../connector/connectorprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../../exporter/exporterprofiles diff --git a/otelcol/go.mod b/otelcol/go.mod index d820379ef8b..f84b3a9afb7 100644 --- a/otelcol/go.mod +++ b/otelcol/go.mod @@ -68,6 +68,7 @@ require ( go.opentelemetry.io/collector/consumer v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/internal/globalgates v0.108.1 // indirect go.opentelemetry.io/collector/pdata v1.14.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect @@ -170,3 +171,5 @@ replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../receiver/r replace go.opentelemetry.io/collector/processor/processorprofiles => ../processor/processorprofiles replace go.opentelemetry.io/collector/connector/connectorprofiles => ../connector/connectorprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporter/exporterprofiles diff --git a/otelcol/otelcoltest/go.mod b/otelcol/otelcoltest/go.mod index 6cb780e89ba..6059780b440 100644 --- a/otelcol/otelcoltest/go.mod +++ b/otelcol/otelcoltest/go.mod @@ -66,6 +66,7 @@ require ( go.opentelemetry.io/collector/consumer v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/consumer/consumertest v0.108.1 // indirect + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 // indirect go.opentelemetry.io/collector/featuregate v1.14.1 // indirect go.opentelemetry.io/collector/internal/globalgates v0.108.1 // indirect go.opentelemetry.io/collector/pdata v1.14.1 // indirect @@ -185,3 +186,5 @@ replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receive replace go.opentelemetry.io/collector/processor/processorprofiles => ../../processor/processorprofiles replace go.opentelemetry.io/collector/connector/connectorprofiles => ../../connector/connectorprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../../exporter/exporterprofiles diff --git a/service/go.mod b/service/go.mod index 2885216dcb0..983f285bb36 100644 --- a/service/go.mod +++ b/service/go.mod @@ -22,6 +22,7 @@ require ( go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 go.opentelemetry.io/collector/consumer/consumertest v0.108.1 go.opentelemetry.io/collector/exporter v0.108.1 + go.opentelemetry.io/collector/exporter/exporterprofiles v0.108.1 go.opentelemetry.io/collector/extension v0.108.1 go.opentelemetry.io/collector/extension/zpagesextension v0.108.1 go.opentelemetry.io/collector/featuregate v1.14.1 @@ -178,3 +179,5 @@ replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../receiver/r replace go.opentelemetry.io/collector/processor/processorprofiles => ../processor/processorprofiles replace go.opentelemetry.io/collector/connector/connectorprofiles => ../connector/connectorprofiles + +replace go.opentelemetry.io/collector/exporter/exporterprofiles => ../exporter/exporterprofiles diff --git a/service/internal/builders/exporter.go b/service/internal/builders/exporter.go index 84c698ef070..385311e8e6d 100644 --- a/service/internal/builders/exporter.go +++ b/service/internal/builders/exporter.go @@ -9,6 +9,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterprofiles" "go.opentelemetry.io/collector/exporter/exportertest" ) @@ -80,6 +81,22 @@ func (b *ExporterBuilder) CreateLogs(ctx context.Context, set exporter.Settings) return f.CreateLogsExporter(ctx, set, cfg) } +// CreateProfiles creates a Profiles exporter based on the settings and config. +func (b *ExporterBuilder) CreateProfiles(ctx context.Context, set exporter.Settings) (exporterprofiles.Profiles, error) { + cfg, existsCfg := b.cfgs[set.ID] + if !existsCfg { + return nil, fmt.Errorf("exporter %q is not configured", set.ID) + } + + f, existsFactory := b.factories[set.ID.Type()] + if !existsFactory { + return nil, fmt.Errorf("exporter factory not available for: %q", set.ID) + } + + logStabilityLevel(set.Logger, f.ProfilesExporterStability()) + return f.CreateProfilesExporter(ctx, set, cfg) +} + func (b *ExporterBuilder) Factory(componentType component.Type) component.Factory { return b.factories[componentType] } diff --git a/service/internal/builders/exporter_test.go b/service/internal/builders/exporter_test.go index a8dd7e71382..e4a3cdd19ca 100644 --- a/service/internal/builders/exporter_test.go +++ b/service/internal/builders/exporter_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterprofiles" "go.opentelemetry.io/collector/exporter/exportertest" ) @@ -27,6 +28,7 @@ func TestExporterBuilder(t *testing.T) { exporter.WithTraces(createExporterTraces, component.StabilityLevelDevelopment), exporter.WithMetrics(createExporterMetrics, component.StabilityLevelAlpha), exporter.WithLogs(createExporterLogs, component.StabilityLevelDeprecated), + exporterprofiles.WithProfiles(createExporterProfiles, component.StabilityLevelDevelopment), ), }...) require.NoError(t, err) @@ -87,6 +89,15 @@ func TestExporterBuilder(t *testing.T) { assert.NoError(t, err) assert.Equal(t, nopExporterInstance, le) } + + pe, err := b.CreateProfiles(context.Background(), createExporterSettings(tt.id)) + if tt.err != "" { + assert.EqualError(t, err, tt.err) + assert.Nil(t, pe) + } else { + assert.NoError(t, err) + assert.Equal(t, nopExporterInstance, pe) + } }) } } @@ -100,6 +111,7 @@ func TestExporterBuilderMissingConfig(t *testing.T) { exporter.WithTraces(createExporterTraces, component.StabilityLevelDevelopment), exporter.WithMetrics(createExporterMetrics, component.StabilityLevelAlpha), exporter.WithLogs(createExporterLogs, component.StabilityLevelDeprecated), + exporterprofiles.WithProfiles(createExporterProfiles, component.StabilityLevelDevelopment), ), }...) @@ -119,6 +131,10 @@ func TestExporterBuilderMissingConfig(t *testing.T) { le, err := bErr.CreateLogs(context.Background(), createExporterSettings(missingID)) assert.EqualError(t, err, "exporter \"all/missing\" is not configured") assert.Nil(t, le) + + pe, err := bErr.CreateProfiles(context.Background(), createExporterSettings(missingID)) + assert.EqualError(t, err, "exporter \"all/missing\" is not configured") + assert.Nil(t, pe) } func TestExporterBuilderFactory(t *testing.T) { @@ -159,13 +175,19 @@ func TestNewNopExporterConfigsAndFactories(t *testing.T) { bLogs, err := builder.CreateLogs(context.Background(), set) require.NoError(t, err) assert.IsType(t, logs, bLogs) + + profiles, err := factory.CreateProfilesExporter(context.Background(), set, cfg) + require.NoError(t, err) + bProfiles, err := builder.CreateProfiles(context.Background(), set) + require.NoError(t, err) + assert.IsType(t, profiles, bProfiles) } var nopExporterInstance = &nopExporter{ Consumer: consumertest.NewNop(), } -// nopExporter stores consumed traces and metrics for testing purposes. +// nopExporter stores consumed traces, metrics, logs and profiles for testing purposes. type nopExporter struct { component.StartFunc component.ShutdownFunc @@ -184,6 +206,10 @@ func createExporterLogs(context.Context, exporter.Settings, component.Config) (e return nopExporterInstance, nil } +func createExporterProfiles(context.Context, exporter.Settings, component.Config) (exporterprofiles.Profiles, error) { + return nopExporterInstance, nil +} + func createExporterSettings(id component.ID) exporter.Settings { return exporter.Settings{ ID: id,