diff --git a/exporter/otlp/README.md b/exporter/otlp/README.md index 0567823d8..974a9955b 100644 --- a/exporter/otlp/README.md +++ b/exporter/otlp/README.md @@ -65,6 +65,22 @@ end For additional examples, see the [examples on github][examples-github]. +## How can I configure the OTLP exporter? + +The collector exporter can be configured explicitly in code, as shown above, or via environment variables. The configuration parameters, environment variables, and defaults are shown below. + +| Parameter | Environment variable | Default | +| ------------------- | -------------------------------------------- | ----------------------------------- | +| `endpoint:` | `OTEL_EXPORTER_OTLP_ENDPOINT` | `"http://localhost:4317/v1/traces"` | +| `certificate_file: `| `OTEL_EXPORTER_OTLP_CERTIFICATE` | | +| `headers:` | `OTEL_EXPORTER_OTLP_HEADERS` | | +| `compression:` | `OTEL_EXPORTER_OTLP_COMPRESSION` | | +| `timeout:` | `OTEL_EXPORTER_OTLP_TIMEOUT` | `10` | +| `ssl_verify_mode:` | `OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER` or | `OpenSSL::SSL:VERIFY_PEER` | +| | `OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE` | | + +`ssl_verify_mode:` parameter values should be flags for server certificate verification: `OpenSSL::SSL:VERIFY_PEER` and `OpenSSL::SSL:VERIFY_NONE` are acceptable. These values can also be set using the appropriately named environment variables as shown where `VERIFY_PEER` will take precedence over `VERIFY_NONE`. Please see [the Net::HTTP docs](https://ruby-doc.org/stdlib-2.5.1/libdoc/net/http/rdoc/Net/HTTP.html#verify_mode) for more information about these flags. + ## How can I get involved? The `opentelemetry-exporter-otlp` gem source is [on github][repo-github], along with related gems including `opentelemetry-sdk`. diff --git a/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb b/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb index 168ce5cd8..6a03afdb1 100644 --- a/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb +++ b/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb @@ -31,8 +31,19 @@ class Exporter # rubocop:disable Metrics/ClassLength WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED) - def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'https://localhost:4317/v1/traces'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + def self.ssl_verify_mode + if ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER') + OpenSSL::SSL::VERIFY_PEER + elsif ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE') + OpenSSL::SSL::VERIFY_NONE + else + OpenSSL::SSL::VERIFY_PEER + end + end + + def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'https://localhost:4317/v1/traces'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength certificate_file: config_opt('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'), + ssl_verify_mode: Exporter.ssl_verify_mode, headers: config_opt('OTEL_EXPORTER_OTLP_TRACES_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS'), compression: config_opt('OTEL_EXPORTER_OTLP_TRACES_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION'), timeout: config_opt('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10), @@ -49,6 +60,7 @@ def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_ @http = Net::HTTP.new(@uri.host, @uri.port) @http.use_ssl = @uri.scheme == 'https' + @http.verify_mode = ssl_verify_mode @http.ca_file = certificate_file unless certificate_file.nil? @http.keep_alive_timeout = KEEP_ALIVE_TIMEOUT diff --git a/exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb b/exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb index 83dae63ff..7d760a2af 100644 --- a/exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb +++ b/exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb @@ -22,6 +22,7 @@ _(http.ca_file).must_be_nil _(http.use_ssl?).must_equal true _(http.address).must_equal 'localhost' + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER _(http.port).must_equal 4317 end @@ -57,6 +58,7 @@ 'OTEL_EXPORTER_OTLP_CERTIFICATE' => '/foo/bar', 'OTEL_EXPORTER_OTLP_HEADERS' => 'a=b,c=d', 'OTEL_EXPORTER_OTLP_COMPRESSION' => 'gzip', + 'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true', 'OTEL_EXPORTER_OTLP_TIMEOUT' => '11') do OpenTelemetry::Exporter::OTLP::Exporter.new end @@ -68,6 +70,7 @@ _(http.ca_file).must_equal '/foo/bar' _(http.use_ssl?).must_equal false _(http.address).must_equal 'localhost' + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE _(http.port).must_equal 1234 end @@ -76,11 +79,13 @@ 'OTEL_EXPORTER_OTLP_CERTIFICATE' => '/foo/bar', 'OTEL_EXPORTER_OTLP_HEADERS' => 'a:b,c:d', 'OTEL_EXPORTER_OTLP_COMPRESSION' => 'flate', + 'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true', 'OTEL_EXPORTER_OTLP_TIMEOUT' => '11') do OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://localhost:4321', certificate_file: '/baz', headers: { 'x' => 'y' }, compression: 'gzip', + ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, timeout: 12) end _(exp.instance_variable_get(:@headers)).must_equal('x' => 'y') @@ -90,11 +95,39 @@ http = exp.instance_variable_get(:@http) _(http.ca_file).must_equal '/baz' _(http.use_ssl?).must_equal false + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE _(http.address).must_equal 'localhost' _(http.port).must_equal 4321 end end + describe 'ssl_verify_mode:' do + it 'can be set to VERIFY_NONE by an envvar' do + exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true') do + OpenTelemetry::Exporter::OTLP::Exporter.new + end + http = exp.instance_variable_get(:@http) + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE + end + + it 'can be set to VERIFY_PEER by an envvar' do + exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true') do + OpenTelemetry::Exporter::OTLP::Exporter.new + end + http = exp.instance_variable_get(:@http) + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER + end + + it 'VERIFY_PEER will override VERIFY_NONE' do + exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true', + 'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true') do + OpenTelemetry::Exporter::OTLP::Exporter.new + end + http = exp.instance_variable_get(:@http) + _(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER + end + end + describe '#export' do let(:exporter) { OpenTelemetry::Exporter::OTLP::Exporter.new }