Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# SPDX-License-Identifier: Apache-2.0

require 'opentelemetry'
require 'opentelemetry/exporter/otlp/common/utilities'
require 'opentelemetry/exporter/otlp/common/version'

require 'google/rpc/status_pb'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'opentelemetry/common'

module OpenTelemetry
module Exporter
module OTLP
module Common
# Contains common utilities used by the otlp exporters
module Utilities
extend self

# Builds a url using the endpoint defined and if not present uses the configured sources
def build_uri(endpoint, path = '', primary_src = '', secondary_src = '', default = nil)
env_endpoint = OpenTelemetry::Common::Utilities.config_opt(primary_src, secondary_src, default: default) unless endpoint
endpoint ||= env_endpoint
raise ArgumentError, "invalid url for OTLPExporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)

if !env_endpoint.nil? && env_endpoint != ENV[primary_src]
env_endpoint += '/' unless env_endpoint.end_with?('/')
URI.join(env_endpoint, path)
else
URI(endpoint)
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'googleapis-common-protos-types', '~> 1.3'
spec.add_dependency 'google-protobuf', '~> 3.19'
spec.add_dependency 'opentelemetry-api', '~> 1.1'
spec.add_dependency 'opentelemetry-common'

if spec.respond_to?(:metadata)
spec.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}/file/CHANGELOG.md"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'test_helper'

describe OpenTelemetry::Exporter::OTLP::Common::Utilities do
describe 'IPv4/IPv6 compatibility' do
it 'handles IPv6 loopback address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://[::1]:4318/v1/logs')
_(exp.host).must_equal '[::1]'
_(exp.port).must_equal 4318
_(exp.path).must_equal '/v1/logs'
end

it 'handles IPv6 full address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://[2001:db8::1]:4318/v1/logs')
_(exp.host).must_equal '[2001:db8::1]'
_(exp.port).must_equal 4318
end

it 'handles IPv6 address with https' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('https://[::1]:4318/v1/logs')
_(exp.host).must_equal '[::1]'
_(exp.port).must_equal 4318
_(exp.scheme).must_equal 'https'
end

it 'handles IPv6 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://[::1]:8080/custom/path')
_(exp.host).must_equal '[::1]'
_(exp.port).must_equal 8080
_(exp.path).must_equal '/custom/path'
end

it 'handles IPv4 loopback address' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://127.0.0.1:4318/v1/logs')
_(exp.host).must_equal '127.0.0.1'
_(exp.port).must_equal 4318
_(exp.path).must_equal '/v1/logs'
end

it 'handles IPv4 address with custom port' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://192.168.1.100:8080/v1/logs')
_(exp.host).must_equal '192.168.1.100'
_(exp.port).must_equal 8080
end

it 'handles IPv4 address with https' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('https://10.0.0.1:4318/v1/logs')
_(exp.host).must_equal '10.0.0.1'
_(exp.port).must_equal 4318
_(exp.scheme).must_equal 'https'
end

it 'handles IPv4 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://127.0.0.1:9090/custom/path')
_(exp.host).must_equal '127.0.0.1'
_(exp.port).must_equal 9090
_(exp.path).must_equal '/custom/path'
end

it 'handles IPv4 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://192.168.1.1:4318') do
OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri(nil, 'v1/logs', 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT')
end
_(exp.host).must_equal '192.168.1.1'
_(exp.port).must_equal 4318
_(exp.path).must_equal '/v1/logs'
end

it 'handles hostnames' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://localhost:4318/v1/logs')
_(exp.host).must_equal 'localhost'
_(exp.port).must_equal 4318
end

it 'handles fully qualified domain names' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('http://otel.example.com:4318/v1/logs')
_(exp.host).must_equal 'otel.example.com'
_(exp.port).must_equal 4318
end

it 'handles hostnames with https' do
exp = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri('https://otel-collector.prod.example.com:443/v1/logs')
_(exp.host).must_equal 'otel-collector.prod.example.com'
_(exp.port).must_equal 443
_(exp.scheme).must_equal 'https'
end

it 'handles IPv6 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://[::1]:4318') do
OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri(nil, 'v1/logs', 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT')
end
_(exp.host).must_equal '[::1]'
_(exp.port).must_equal 4318
_(exp.path).must_equal '/v1/logs'
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ class TraceExporter
FAILURE = OpenTelemetry::SDK::Trace::Export::FAILURE
private_constant(:SUCCESS, :FAILURE)

def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'http://localhost:4317/v1/traces'),
def initialize(endpoint: nil,
timeout: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10),
certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'),
client_certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'),
client_key_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY', 'OTEL_EXPORTER_OTLP_CLIENT_KEY'),
metrics_reporter: nil)
raise ArgumentError, "invalid url for OTLP::Exporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)

uri = URI(endpoint)
uri = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri(endpoint, 'v1/traces', 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318/')

creds = if !client_key_file.nil? && !client_certificate_file.nil?
# Permits constructing with nil root cert.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def initialize(endpoint: nil,
timeout: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10))
raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil? || %w[gzip none].include?(compression)

@uri = prepare_endpoint(endpoint)
@uri = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri(endpoint, 'v1/traces', 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318/')

@http = http_connection(@uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)

Expand Down Expand Up @@ -258,21 +258,6 @@ def prepare_headers(config_headers)
headers
end

def prepare_endpoint(endpoint)
endpoint ||= ENV.fetch('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', nil)
if endpoint.nil?
endpoint = ENV['OTEL_EXPORTER_OTLP_ENDPOINT'] || 'http://localhost:4318'
endpoint += '/' unless endpoint.end_with?('/')
URI.join(endpoint, 'v1/traces')
elsif endpoint.strip.empty?
raise ArgumentError, "invalid url for OTLP::Exporter #{endpoint}"
else
URI(endpoint)
end
rescue URI::InvalidURIError
raise ArgumentError, "invalid url for OTLP::Exporter #{endpoint}"
end

def parse_headers(raw)
entries = raw.split(',')
raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS if entries.empty?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,112 +356,6 @@
end
end

describe 'IPv4/IPv6 compatibility' do
it 'handles IPv6 loopback address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://[::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles IPv6 full address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://[2001:db8::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '2001:db8::1'
_(http.port).must_equal 4318
end

it 'handles IPv6 address with https' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'https://[::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(http.use_ssl?).must_equal true
end

it 'handles IPv6 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://[::1]:8080/custom/path')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 8080
_(exp.instance_variable_get(:@path)).must_equal '/custom/path'
end

it 'handles IPv4 loopback address' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://127.0.0.1:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '127.0.0.1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles IPv4 address with custom port' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://192.168.1.100:8080/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '192.168.1.100'
_(http.port).must_equal 8080
end

it 'handles IPv4 address with https' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'https://10.0.0.1:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '10.0.0.1'
_(http.port).must_equal 4318
_(http.use_ssl?).must_equal true
end

it 'handles IPv4 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://127.0.0.1:9090/custom/path')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '127.0.0.1'
_(http.port).must_equal 9090
_(exp.instance_variable_get(:@path)).must_equal '/custom/path'
end

it 'handles IPv4 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://192.168.1.1:4318') do
OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new
end
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '192.168.1.1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles hostnames' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://localhost:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'localhost'
_(http.port).must_equal 4318
end

it 'handles fully qualified domain names' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'http://otel.example.com:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'otel.example.com'
_(http.port).must_equal 4318
end

it 'handles hostnames with https' do
exp = OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new(endpoint: 'https://otel-collector.prod.example.com:443/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'otel-collector.prod.example.com'
_(http.port).must_equal 443
_(http.use_ssl?).must_equal true
end

it 'handles IPv6 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://[::1]:4318') do
OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new
end
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end
end

describe '#export' do
let(:exporter) { OpenTelemetry::Exporter::OTLP::HTTP::TraceExporter.new }

Expand Down
1 change: 1 addition & 0 deletions exporter/otlp-logs/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ group :test, :development do
gem 'yard-doctest', '~> 0.1.6'
gem 'opentelemetry-api', path: '../../api', require: false
gem 'opentelemetry-common', path: '../../common', require: false
gem 'opentelemetry-exporter-otlp-common', path: '../otlp-common', require: false
gem 'opentelemetry-logs-api', path: '../../logs_api', require: false
gem 'opentelemetry-logs-sdk', path: '../../logs_sdk', require: false
gem 'opentelemetry-registry', path: '../../registry', require: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# SPDX-License-Identifier: Apache-2.0

require 'opentelemetry/common'
require 'opentelemetry/exporter/otlp/common'
require 'opentelemetry/sdk'
require 'opentelemetry-logs-api' # the sdk isn't loading the api, but not sure why
require 'opentelemetry/sdk/logs'
Expand Down Expand Up @@ -50,24 +51,17 @@ def self.ssl_verify_mode
end
# rubocop:enable Lint/DuplicateBranch

def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'http://localhost:4318/v1/logs'),
def initialize(endpoint: nil,
certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'),
client_certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE'),
client_key_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY', 'OTEL_EXPORTER_OTLP_CLIENT_KEY'),
ssl_verify_mode: LogsExporter.ssl_verify_mode,
headers: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS', default: {}),
compression: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION', default: 'gzip'),
timeout: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_LOGS_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10))
raise ArgumentError, "invalid url for OTLP::Logs::LogsExporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)
raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil? || %w[gzip none].include?(compression)

@uri = if endpoint == ENV['OTEL_EXPORTER_OTLP_ENDPOINT']
endpoint += '/' unless endpoint.end_with?('/')
URI.join(endpoint, 'v1/logs')
else
URI(endpoint)
end

@uri = OpenTelemetry::Exporter::OTLP::Common::Utilities.build_uri(endpoint, 'v1/logs', 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318/')
@http = http_connection(@uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)

@path = @uri.path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'google-protobuf', '>= 3.18'
spec.add_dependency 'opentelemetry-api', '~> 1.1'
spec.add_dependency 'opentelemetry-common', '~> 0.20'
spec.add_dependency 'opentelemetry-exporter-otlp-common'
spec.add_dependency 'opentelemetry-logs-api', '~> 0.1'
spec.add_dependency 'opentelemetry-logs-sdk', '~> 0.1'
spec.add_dependency 'opentelemetry-sdk'
Expand Down
Loading