open-telemetry/opentelemetry-ruby

OTLP exporter env var handling is not spec compliant

pichlermarc opened this issue ยท 1 comments

Description of the bug

Hi everyone ๐Ÿ™‚ It looks like the handling of the OTEL_EXPORTER_OTLP_TRACES_ENDPOINT and OTEL_EXPORTER_OTLP_ENDPOINT environment variables is not in compliance with the spec, there are a few examples of this that we discovered in some internal testing:

  • endpoint and OTEL_EXPORTER_OTLP_ENDPOINT are both set to the same value, `
    • expected behavior: the URL from endpoint is used and not modified
    • actual behavior: v1/traces is appended to the endpoint
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT and OTEL_EXPORTER_OTLP_ENDPOINT are set to the same value
    • expected behavior: the URL from OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is used and not modified
    • actual behavior: when v1/tracesis appended to the value fromOTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
  • if OTEL_EXPORTER_OTLP_ENDPOINT does not have a trailing slash (example: https://localhost:1234/api/v2/otlp)
    • expected behavior: the URL from OTEL_EXPORTER_OTLP_ENDPOINT is appended with /v1/traces (example: https://localhost:1234/api/v2/otlp becomes https://localhost:1234/api/v2/otlp/v1/traces)
    • actual behavior: the URL from OTEL_EXPORTER_OTLP_ENDPOINT is stripped of the last part and appended with /v1/traces (example: https://localhost:1234/api/v2/otlp becomes https://localhost:1234/api/v2/v1/otlp)

Share details about your runtime

Operating system details: Linux, Ubuntu 22.04 LTS
RUBY_ENGINE: "ruby"
RUBY_VERSION: "3.2.0"
RUBY_DESCRIPTION: "ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux]"

Share a simplified reproduction if possible

Tests intended for `exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb', all of them should fail in the current implementation

    it 'does not join endpoint with v1/traces if endpoint is set and is equal to OTEL_EXPORTER_OTLP_ENDPOINT' do
      exp = OpenTelemetry::TestHelpers.with_env(
        'OTEL_EXPORTER_OTLP_ENDPOINT' => 'https://localhost:1234/custom/path'
      ) do
        OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'https://localhost:1234/custom/path')
      end
      _(exp.instance_variable_get(:@path)).must_equal '/custom/path'
    end

    it 'appends the correct path if OTEL_EXPORTER_OTLP_ENDPOINT does have a path without a trailing slash' do
      exp = OpenTelemetry::TestHelpers.with_env(
        # simulate OTLP endpoints built on top of an exiting API
        'OTEL_EXPORTER_OTLP_ENDPOINT' => 'https://localhost:1234/api/v2/otlp'
      ) do
        OpenTelemetry::Exporter::OTLP::Exporter.new
      end
      _(exp.instance_variable_get(:@path)).must_equal '/api/v2/otlp/v1/traces'
    end

    it 'appends the correct path if OTEL_EXPORTER_OTLP_ENDPOINT does have a path without a trailing slash' do
      exp = OpenTelemetry::TestHelpers.with_env(
        # simulate OTLP endpoints built on top of an exiting API
        'OTEL_EXPORTER_OTLP_ENDPOINT' => 'https://localhost:1234/api/v2/otlp'
      ) do
        OpenTelemetry::Exporter::OTLP::Exporter.new
      end
      _(exp.instance_variable_get(:@path)).must_equal '/api/v2/otlp/v1/traces'
    end

I have not really used ruby before, but I have prototyped a PR to take care of this over at #1506 ๐Ÿ™‚