lib/opentelemetry/exporter/otlp/exporter.rb in opentelemetry-exporter-otlp-0.26.1 vs lib/opentelemetry/exporter/otlp/exporter.rb in opentelemetry-exporter-otlp-0.26.2
- old
+ new
@@ -5,11 +5,10 @@
# SPDX-License-Identifier: Apache-2.0
require 'opentelemetry/common'
require 'opentelemetry/sdk'
require 'net/http'
-require 'csv'
require 'zlib'
require 'google/rpc/status_pb'
require 'opentelemetry/proto/common/v1/common_pb'
@@ -45,26 +44,21 @@
else
OpenSSL::SSL::VERIFY_PEER
end
end
- def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'http://localhost:4318/v1/traces'),
+ def initialize(endpoint: nil,
certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'),
ssl_verify_mode: Exporter.ssl_verify_mode,
headers: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS', default: {}),
compression: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION', default: 'gzip'),
timeout: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10),
metrics_reporter: nil)
- raise ArgumentError, "invalid url for OTLP::Exporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)
+ @uri = prepare_endpoint(endpoint)
+
raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil? || %w[gzip none].include?(compression)
- @uri = if endpoint == ENV['OTEL_EXPORTER_OTLP_ENDPOINT']
- URI.join(endpoint, 'v1/traces')
- else
- URI(endpoint)
- end
-
@http = http_connection(@uri, ssl_verify_mode, certificate_file)
@path = @uri.path
@headers = prepare_headers(headers)
@timeout = timeout.to_f
@@ -170,12 +164,11 @@
when Net::HTTPRequestTimeOut, Net::HTTPGatewayTimeOut, Net::HTTPBadGateway
response.body # Read and discard body
redo if backoff?(retry_count: retry_count += 1, reason: response.code)
FAILURE
when Net::HTTPNotFound
- OpenTelemetry.handle_error(message: "OTLP exporter received http.code=404 for uri: '#{@path}'")
- @metrics_reporter.add_to_counter('otel.otlp_exporter.failure', labels: { 'reason' => response.code })
+ log_request_failure(response.code)
FAILURE
when Net::HTTPBadRequest, Net::HTTPClientError, Net::HTTPServerError
log_status(response.body)
@metrics_reporter.add_to_counter('otel.otlp_exporter.failure', labels: { 'reason' => response.code })
FAILURE
@@ -183,10 +176,11 @@
@http.finish
handle_redirect(response['location'])
redo if backoff?(retry_after: 0, retry_count: retry_count += 1, reason: response.code)
else
@http.finish
+ log_request_failure(response.code)
FAILURE
end
rescue Net::OpenTimeout, Net::ReadTimeout
retry if backoff?(retry_count: retry_count += 1, reason: 'timeout')
return FAILURE
@@ -225,15 +219,20 @@
status = Google::Rpc::Status.decode(body)
details = status.details.map do |detail|
klass_or_nil = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(detail.type_name).msgclass
detail.unpack(klass_or_nil) if klass_or_nil
end.compact
- OpenTelemetry.handle_error(message: "OTLP exporter received rpc.Status{message=#{status.message}, details=#{details}}")
+ OpenTelemetry.handle_error(message: "OTLP exporter received rpc.Status{message=#{status.message}, details=#{details}} for uri=#{@uri}")
rescue StandardError => e
OpenTelemetry.handle_error(exception: e, message: 'unexpected error decoding rpc.Status in OTLP::Exporter#log_status')
end
+ def log_request_failure(response_code)
+ OpenTelemetry.handle_error(message: "OTLP exporter received http.code=#{response_code} for uri='#{@uri}' in OTLP::Exporter#send_bytes")
+ @metrics_reporter.add_to_counter('otel.otlp_exporter.failure', labels: { 'reason' => response_code })
+ end
+
def measure_request_duration
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
begin
response = yield
ensure
@@ -244,11 +243,11 @@
labels: { 'status' => response&.code || 'unknown' })
end
end
def backoff?(retry_count:, reason:, retry_after: nil) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
- @metrics_reporter.add_to_counter('otel.otlp_exporter.failure', labels: { 'reason' => reason })
+ log_request_failure(reason)
return false if retry_count > RETRY_COUNT
sleep_interval = nil
unless retry_after.nil?
sleep_interval =
@@ -382,9 +381,24 @@
when Array
values = value.map { |element| as_otlp_any_value(element) }
result.array_value = Opentelemetry::Proto::Common::V1::ArrayValue.new(values: values)
end
result
+ end
+
+ def prepare_endpoint(endpoint)
+ endpoint ||= ENV['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT']
+ 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 prepare_headers(config_headers)
headers = case config_headers
when String then parse_headers(config_headers)