opentelemetry-exporter-otlp 0.7.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41bcdac16475886dcce6be45e8e1489055086ed69149a1e87aea46a5961ec770
4
- data.tar.gz: 8d89e00696585b6488d1180bb43d1bdf4afbef664d7bf8e39c3d8aa46d632d93
3
+ metadata.gz: a82ddc3fb2e5d64af320a0c2673b1e5c52f7b32cd15dbbf40e8a6442f0ae0eb7
4
+ data.tar.gz: a256ebed6d862f8e62a31f8a06e12adb90c4dff26db4fda2f5190ae8623737f8
5
5
  SHA512:
6
- metadata.gz: 31e7c1e7a89ff6a8e6e73f846948cb497e6c7b392bfbbf934b989de7c5182007e3e5fd8a6ecc64bb0b48ece3c2bad96eb899e7f9bcedc5b8a04c1eba941d10ee
7
- data.tar.gz: e2a31561c78ee17d87102b79e1cbe45646caae5c220f527e12bb2900a2d9afde80226e437e79a4329e7e582a2983bad8d79ce2dd18db8cabc609dc2ac3f66890
6
+ metadata.gz: 45c4cdc80fb6e3cad4a32edde1de12f928ace262afdb6d8b395ae052b754d67ee8a80c7a0571bb2ff3764708400801b3aec7594af7a658bab5863ce1f9c112e6
7
+ data.tar.gz: 7e8bc1bf14d1c496efe948900170fe1f5bf4a21213f3862df3780e0d5b1d06548afc47b7cc4e9e43d592496211618c4332ea3e01cb50f7638134d6613e6c3155
@@ -1,5 +1,39 @@
1
1
  # Release History: opentelemetry-exporter-otlp
2
2
 
3
+ ### v0.12.0 / 2020-12-24
4
+
5
+ * (No significant changes)
6
+
7
+ ### v0.11.0 / 2020-12-11
8
+
9
+ * BREAKING CHANGE: Implement tracestate
10
+
11
+ * ADDED: Implement tracestate
12
+ * ADDED: Metrics reporting from trace export
13
+ * FIXED: Copyright comments to not reference year
14
+
15
+ ### v0.10.0 / 2020-12-03
16
+
17
+ * (No significant changes)
18
+
19
+ ### v0.9.0 / 2020-11-27
20
+
21
+ * BREAKING CHANGE: Add timeout for force_flush and shutdown
22
+
23
+ * ADDED: Add timeout for force_flush and shutdown
24
+ * FIXED: Remove unused kwarg from otlp exporter retry
25
+
26
+ ### v0.8.0 / 2020-10-27
27
+
28
+ * BREAKING CHANGE: Move context/span methods to Trace module
29
+ * BREAKING CHANGE: Remove 'canonical' from status codes
30
+ * BREAKING CHANGE: Assorted SpanContext fixes
31
+
32
+ * FIXED: Move context/span methods to Trace module
33
+ * FIXED: Remove 'canonical' from status codes
34
+ * FIXED: Add gzip support to OTLP exporter
35
+ * FIXED: Assorted SpanContext fixes
36
+
3
37
  ### v0.7.0 / 2020-10-07
4
38
 
5
39
  * FIXED: OTLP parent_span_id should be nil for root
data/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2020 OpenTelemetry Authors
189
+ Copyright The OpenTelemetry Authors
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -4,9 +4,11 @@
4
4
  #
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
+ require 'opentelemetry/common'
7
8
  require 'opentelemetry/sdk'
8
9
  require 'net/http'
9
10
  require 'csv'
11
+ require 'zlib'
10
12
 
11
13
  require 'opentelemetry/proto/common/v1/common_pb'
12
14
  require 'opentelemetry/proto/resource/v1/resource_pb'
@@ -20,23 +22,24 @@ module OpenTelemetry
20
22
  class Exporter # rubocop:disable Metrics/ClassLength
21
23
  SUCCESS = OpenTelemetry::SDK::Trace::Export::SUCCESS
22
24
  FAILURE = OpenTelemetry::SDK::Trace::Export::FAILURE
23
- private_constant(:SUCCESS, :FAILURE)
25
+ TIMEOUT = OpenTelemetry::SDK::Trace::Export::TIMEOUT
26
+ private_constant(:SUCCESS, :FAILURE, :TIMEOUT)
24
27
 
25
28
  # Default timeouts in seconds.
26
29
  KEEP_ALIVE_TIMEOUT = 30
27
- OPEN_TIMEOUT = 5
28
- READ_TIMEOUT = 5
29
30
  RETRY_COUNT = 5
30
- private_constant(:KEEP_ALIVE_TIMEOUT, :OPEN_TIMEOUT, :READ_TIMEOUT, :RETRY_COUNT)
31
+ WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
32
+ private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED)
31
33
 
32
- def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_SPAN_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'localhost:55681/v1/trace'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
34
+ def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_SPAN_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'localhost:55681/v1/trace'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
33
35
  insecure: config_opt('OTEL_EXPORTER_OTLP_SPAN_INSECURE', 'OTEL_EXPORTER_OTLP_INSECURE', default: false),
34
36
  certificate_file: config_opt('OTEL_EXPORTER_OTLP_SPAN_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'),
35
37
  headers: config_opt('OTEL_EXPORTER_OTLP_SPAN_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS'), # TODO: what format is expected here?
36
38
  compression: config_opt('OTEL_EXPORTER_OTLP_SPAN_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION'),
37
- timeout: config_opt('OTEL_EXPORTER_OTLP_SPAN_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10))
39
+ timeout: config_opt('OTEL_EXPORTER_OTLP_SPAN_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10),
40
+ metrics_reporter: nil)
38
41
  raise ArgumentError, "invalid url for OTLP::Exporter #{endpoint}" if invalid_url?("http://#{endpoint}")
39
- raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil?
42
+ raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil? || compression == 'gzip'
40
43
  raise ArgumentError, 'headers must be comma-separated k:v pairs or a Hash' unless valid_headers?(headers)
41
44
 
42
45
  uri = URI "http://#{endpoint}"
@@ -44,8 +47,6 @@ module OpenTelemetry
44
47
  @http.use_ssl = insecure.to_s.downcase == 'false'
45
48
  @http.ca_file = certificate_file unless certificate_file.nil?
46
49
  @http.keep_alive_timeout = KEEP_ALIVE_TIMEOUT
47
- @http.open_timeout = OPEN_TIMEOUT
48
- @http.read_timeout = READ_TIMEOUT
49
50
 
50
51
  @path = uri.path
51
52
  @headers = case headers
@@ -53,7 +54,8 @@ module OpenTelemetry
53
54
  when Hash then headers
54
55
  end
55
56
  @timeout = timeout.to_f # TODO: use this as a default timeout when we implement timeouts in https://github.com/open-telemetry/opentelemetry-ruby/pull/341
56
- @tracer = OpenTelemetry.tracer_provider.tracer
57
+ @compression = compression
58
+ @metrics_reporter = metrics_reporter || OpenTelemetry::SDK::Trace::Export::MetricsReporter
57
59
 
58
60
  @shutdown = false
59
61
  end
@@ -63,17 +65,20 @@ module OpenTelemetry
63
65
  # @param [Enumerable<OpenTelemetry::SDK::Trace::SpanData>] span_data the
64
66
  # list of recorded {OpenTelemetry::SDK::Trace::SpanData} structs to be
65
67
  # exported.
68
+ # @param [optional Numeric] timeout An optional timeout in seconds.
66
69
  # @return [Integer] the result of the export.
67
- def export(span_data)
70
+ def export(span_data, timeout: nil)
68
71
  return FAILURE if @shutdown
69
72
 
70
- send_bytes(encode(span_data))
73
+ send_bytes(encode(span_data), timeout: timeout)
71
74
  end
72
75
 
73
76
  # Called when {OpenTelemetry::SDK::Trace::Tracer#shutdown} is called, if
74
77
  # this exporter is registered to a {OpenTelemetry::SDK::Trace::Tracer}
75
78
  # object.
76
- def shutdown
79
+ #
80
+ # @param [optional Numeric] timeout An optional timeout in seconds.
81
+ def shutdown(timeout: nil)
77
82
  @shutdown = true
78
83
  @http.finish if @http.started?
79
84
  end
@@ -107,18 +112,29 @@ module OpenTelemetry
107
112
  true
108
113
  end
109
114
 
110
- def send_bytes(bytes) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
115
+ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
111
116
  retry_count = 0
117
+ timeout ||= @timeout
118
+ start_time = Time.now
112
119
  untraced do # rubocop:disable Metrics/BlockLength
113
120
  request = Net::HTTP::Post.new(@path)
114
- request.body = bytes
121
+ request.body = if @compression == 'gzip'
122
+ request.add_field('Content-Encoding', 'gzip')
123
+ Zlib.gzip(bytes)
124
+ else
125
+ bytes
126
+ end
115
127
  request.add_field('Content-Type', 'application/x-protobuf')
116
128
  @headers&.each { |key, value| request.add_field(key, value) }
117
- # TODO: enable gzip when https://github.com/open-telemetry/opentelemetry-collector/issues/1344 is fixed.
118
- # request.add_field('Content-Encoding', 'gzip')
119
129
 
130
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
131
+ return TIMEOUT if remaining_timeout.zero?
132
+
133
+ @http.open_timeout = remaining_timeout
134
+ @http.read_timeout = remaining_timeout
135
+ @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED
120
136
  @http.start unless @http.started?
121
- response = @http.request(request)
137
+ response = measure_request_duration { @http.request(request) }
122
138
 
123
139
  case response
124
140
  when Net::HTTPOK
@@ -126,11 +142,11 @@ module OpenTelemetry
126
142
  SUCCESS
127
143
  when Net::HTTPServiceUnavailable, Net::HTTPTooManyRequests
128
144
  response.body # Read and discard body
129
- redo if backoff?(retry_after: response['Retry-After'], retry_count: retry_count += 1)
145
+ redo if backoff?(retry_after: response['Retry-After'], retry_count: retry_count += 1, reason: response.code)
130
146
  FAILURE
131
147
  when Net::HTTPRequestTimeOut, Net::HTTPGatewayTimeOut, Net::HTTPBadGateway
132
148
  response.body # Read and discard body
133
- redo if backoff?(retry_count: retry_count += 1)
149
+ redo if backoff?(retry_count: retry_count += 1, reason: response.code)
134
150
  FAILURE
135
151
  when Net::HTTPBadRequest, Net::HTTPClientError, Net::HTTPServerError
136
152
  # TODO: decode the body as a google.rpc.Status Protobuf-encoded message when https://github.com/open-telemetry/opentelemetry-collector/issues/1357 is fixed.
@@ -139,15 +155,20 @@ module OpenTelemetry
139
155
  when Net::HTTPRedirection
140
156
  @http.finish
141
157
  handle_redirect(response['location'])
142
- redo if backoff?(retry_after: 0, retry_count: retry_count += 1)
158
+ redo if backoff?(retry_after: 0, retry_count: retry_count += 1, reason: response.code)
143
159
  else
144
160
  @http.finish
145
161
  FAILURE
146
162
  end
147
163
  rescue Net::OpenTimeout, Net::ReadTimeout
148
- retry if backoff?(retry_count: retry_count += 1)
164
+ retry if backoff?(retry_count: retry_count += 1, reason: 'timeout')
149
165
  return FAILURE
150
166
  end
167
+ ensure
168
+ # Reset timeouts to defaults for the next call.
169
+ @http.open_timeout = @timeout
170
+ @http.read_timeout = @timeout
171
+ @http.write_timeout = @timeout if WRITE_TIMEOUT_SUPPORTED
151
172
  end
152
173
 
153
174
  def handle_redirect(location)
@@ -155,12 +176,27 @@ module OpenTelemetry
155
176
  end
156
177
 
157
178
  def untraced
158
- @tracer.with_span(OpenTelemetry::Trace::Span.new) { yield }
179
+ OpenTelemetry::Trace.with_span(OpenTelemetry::Trace::Span.new) { yield }
180
+ end
181
+
182
+ def measure_request_duration
183
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
184
+ begin
185
+ response = yield
186
+ ensure
187
+ stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
188
+ duration_ms = 1000.0 * (stop - start)
189
+ @metrics_reporter.record_value('otel.otlp_exporter.request_duration',
190
+ value: duration_ms,
191
+ labels: { 'status' => response&.code || 'unknown' })
192
+ end
159
193
  end
160
194
 
161
195
  def backoff?(retry_after: nil, retry_count:, reason:)
162
196
  return false if retry_count > RETRY_COUNT
163
197
 
198
+ @metrics_reporter.add_to_counter('otel.otlp_exporter.failure', labels: { 'reason' => reason })
199
+
164
200
  sleep_interval = nil
165
201
  unless retry_after.nil?
166
202
  sleep_interval =
@@ -214,7 +250,7 @@ module OpenTelemetry
214
250
  Opentelemetry::Proto::Trace::V1::Span.new(
215
251
  trace_id: span_data.trace_id,
216
252
  span_id: span_data.span_id,
217
- trace_state: span_data.tracestate,
253
+ trace_state: span_data.tracestate.to_s,
218
254
  parent_span_id: span_data.parent_span_id == OpenTelemetry::Trace::INVALID_SPAN_ID ? nil : span_data.parent_span_id,
219
255
  name: span_data.name,
220
256
  kind: as_otlp_span_kind(span_data.kind),
@@ -233,9 +269,9 @@ module OpenTelemetry
233
269
  dropped_events_count: span_data.total_recorded_events - span_data.events&.size.to_i,
234
270
  links: span_data.links&.map do |link|
235
271
  Opentelemetry::Proto::Trace::V1::Span::Link.new(
236
- trace_id: link.context.trace_id,
237
- span_id: link.context.span_id,
238
- trace_state: link.context.tracestate,
272
+ trace_id: link.span_context.trace_id,
273
+ span_id: link.span_context.span_id,
274
+ trace_state: link.span_context.tracestate.to_s,
239
275
  attributes: link.attributes&.map { |k, v| as_otlp_key_value(k, v) }
240
276
  # TODO: track dropped_attributes_count in Span#trim_links
241
277
  )
@@ -244,7 +280,7 @@ module OpenTelemetry
244
280
  status: span_data.status&.yield_self do |status|
245
281
  # TODO: fix this based on spec update.
246
282
  Opentelemetry::Proto::Trace::V1::Status.new(
247
- code: status.canonical_code == OpenTelemetry::Trace::Status::ERROR ? Opentelemetry::Proto::Trace::V1::Status::StatusCode::UnknownError : Opentelemetry::Proto::Trace::V1::Status::StatusCode::Ok,
283
+ code: status.code == OpenTelemetry::Trace::Status::ERROR ? Opentelemetry::Proto::Trace::V1::Status::StatusCode::UnknownError : Opentelemetry::Proto::Trace::V1::Status::StatusCode::Ok,
248
284
  message: status.description
249
285
  )
250
286
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2019 OpenTelemetry Authors
3
+ # Copyright The OpenTelemetry Authors
4
4
  #
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
@@ -8,7 +8,7 @@ module OpenTelemetry
8
8
  module Exporter
9
9
  module OTLP
10
10
  ## Current OpenTelemetry OTLP exporter version
11
- VERSION = '0.7.0'
11
+ VERSION = '0.12.0'
12
12
  end
13
13
  end
14
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-exporter-otlp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-08 00:00:00.000000000 Z
11
+ date: 2020-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -36,14 +36,28 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.7.0
39
+ version: 0.12.0
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.7.0
46
+ version: 0.12.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: opentelemetry-common
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.12.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.12.0
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: bundler
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +206,11 @@ files:
192
206
  homepage: https://github.com/open-telemetry/opentelemetry-ruby
193
207
  licenses:
194
208
  - Apache-2.0
195
- metadata: {}
209
+ metadata:
210
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-exporter-otlp/v0.12.0/file.CHANGELOG.html
211
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/master/exporter/otlp
212
+ bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
213
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-exporter-otlp/v0.12.0
196
214
  post_install_message:
197
215
  rdoc_options: []
198
216
  require_paths: