Skip to content

[exporter/loadbalancing] Bug introduced in #43721 - Fails to create exporter per endpoints #43950

@l00py

Description

@l00py

Component(s)

exporter/loadbalancing

What happened?

Description

Steps to Reproduce

  • Build from main
  • Set the loadbalancingexporter with DNS resolver

Expected Result

  • Creation of sub-exporters success

Actual Result

  • See below log outputs

Collector version

605222e

Environment information

Environment

Build via make otelcontribcol GOOS=linux GOARCH=amd64

OpenTelemetry Collector configuration

exporters:
  loadbalancing:
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 60s
    sending_queue:
      enabled: true
      num_consumers: 10
      queue_size: 10000
      block_on_overflow: false
      sizer: items
    protocol:
      otlp:
        timeout: 1s
        tls:
          insecure: true
    resolver:
      dns:
        hostname: otel-receivers.test
        port: '4317'
        interval: 5s
        timeout: 1s

Log output

2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*loadBalancer).addMissingExporters
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/loadbalancer.go:178
2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*loadBalancer).onBackendChanges
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/loadbalancer.go:166
2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*dnsResolver).resolve
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/resolver_dns.go:179
2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*dnsResolver).start
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/resolver_dns.go:92
2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*loadBalancer).Start
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/loadbalancer.go:150
2025-10-31 11:39:29 github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter.(*logExporterImp).Start
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter@v0.138.0/log_exporter.go:69
2025-10-31 11:39:29 go.opentelemetry.io/collector/component.StartFunc.Start
2025-10-31 11:39:29     go.opentelemetry.io/collector/component@v1.44.1-0.20251028105454-507664fb82dc/component.go:66
2025-10-31 11:39:29 go.opentelemetry.io/collector/exporter/exporterhelper/internal.(*BaseExporter).Start
2025-10-31 11:39:29     go.opentelemetry.io/collector/exporter/exporterhelper@v0.138.1-0.20251028105454-507664fb82dc/internal/base_exporter.go:122
2025-10-31 11:39:29 go.opentelemetry.io/collector/service/internal/graph.(*Graph).StartAll
2025-10-31 11:39:29     go.opentelemetry.io/collector/service@v0.138.1-0.20251028105454-507664fb82dc/internal/graph/graph.go:432
2025-10-31 11:39:29 go.opentelemetry.io/collector/service.(*Service).Start
2025-10-31 11:39:29     go.opentelemetry.io/collector/service@v0.138.1-0.20251028105454-507664fb82dc/service.go:237
2025-10-31 11:39:29 go.opentelemetry.io/collector/otelcol.(*Collector).setupConfigurationComponents
2025-10-31 11:39:29     go.opentelemetry.io/collector/otelcol@v0.138.1-0.20251028105454-507664fb82dc/collector.go:249
2025-10-31 11:39:29 go.opentelemetry.io/collector/otelcol.(*Collector).Run
2025-10-31 11:39:29     go.opentelemetry.io/collector/otelcol@v0.138.1-0.20251028105454-507664fb82dc/collector.go:324
2025-10-31 11:39:29 go.opentelemetry.io/collector/otelcol.NewCommand.func1
2025-10-31 11:39:29     go.opentelemetry.io/collector/otelcol@v0.138.1-0.20251028105454-507664fb82dc/command.go:39
2025-10-31 11:39:29 github.com/spf13/cobra.(*Command).execute
2025-10-31 11:39:29     github.com/spf13/cobra@v1.10.1/command.go:1015
2025-10-31 11:39:29 github.com/spf13/cobra.(*Command).ExecuteC
2025-10-31 11:39:29     github.com/spf13/cobra@v1.10.1/command.go:1148
2025-10-31 11:39:29 github.com/spf13/cobra.(*Command).Execute
2025-10-31 11:39:29     github.com/spf13/cobra@v1.10.1/command.go:1071
2025-10-31 11:39:29 main.runInteractive
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/cmd/otelcontribcol/main.go:70
2025-10-31 11:39:29 main.run
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/cmd/otelcontribcol/main_others.go:10
2025-10-31 11:39:29 main.main
2025-10-31 11:39:29     github.com/open-telemetry/opentelemetry-collector-contrib/cmd/otelcontribcol/main.go:63
2025-10-31 11:39:29 runtime.main
2025-10-31 11:39:29     runtime/proc.go:283
2025-10-31 11:39:29 2025-10-31T18:39:29.447Z    error   loadbalancingexporter@v0.138.0/loadbalancer.go:178      failed to create new exporter for endpoint    {"resource": {"service.instance.id": "3cac90d4-38c5-48eb-af03-27d53c507da5", "service.name": "otelcontribcol", "service.version": "0.138.0-dev"}, "otelcol.component.id": "loadbalancing", "otelcol.component.kind": "exporter", "otelcol.signal": "logs", "endpoint": "172.28.0.22:4317", "error": "component type mismatch: component ID \"loadbalancing\" does not have type \"otlp\""}

Additional context

Initial fix

Option A

  • Update the component ID to otlp.
  • Acceptable approach since the exporter only supports otlp, and currently hardcoded in few places.. refactoring opportunities.

Problem

  • The following seems to only create 1 sub-exporter despite having multiple endpoints
  • The ID may need some form of protocol/endpoint identifier
func buildExporterSettings(params exporter.Settings, endpoint string) exporter.Settings {
	otlpFactory := otlpexporter.NewFactory()
	params.ID = component.NewID(otlpFactory.Type())
	params.Logger = params.Logger.With(zap.String(zapEndpointKey, endpoint))
	return params
}

Option B (Revert)

Revert the changes in #43721

  • The following example ensures that we have a unique identifier per protocol/endpoint for the sub-exporter creations
func buildExporterSettings(params exporter.Settings, endpoint string) exporter.Settings {
	otlpFactory := otlpexporter.NewFactory()
	params.ID = component.NewIDWithName(otlpFactory.Type(), endpoint)
	params.Logger = params.Logger.With(zap.String(zapEndpointKey, endpoint))
	return params
}

Problem

  • Possible exporter collisions if naming is not unique. e.g. otlp vs otlp/<endpoint> vs loadbalancing

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions