opentelemetry-sdk 1.0.0.rc2 → 1.0.2

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: d43559eaa2be64a3597d078d032c168429702e47bdeaee1ac454dc5e74f9f496
4
- data.tar.gz: 583f42bb1b6543d6375d3cfc8e4bd2319d5146306f42a73d726ca73f3c01e56d
3
+ metadata.gz: 7bdebb54966352742da13ac2700b592e49a9f06a751961f7e9d41e70cf855c29
4
+ data.tar.gz: 4a977ef6391a6c76b6c333797abab87aba952ee357541b482b72441156c4a7fc
5
5
  SHA512:
6
- metadata.gz: 14112a30284f0ececabcf75dda91f6634b3748c44ccec52e19c6d42e7fae59979e6ea82ef276d21ea5503d2b4f35821945b62d2b1afc83c5bcb9d4a6a9ce6bf4
7
- data.tar.gz: 87aaa08db88b9495c86ee1135cdcbfb95827fbbed42edf3280500d86025ff269ee3af95c675e20231267e7b561082cea12df7738db004922468246ad437805fb
6
+ metadata.gz: 8c54d7a07907e48fcef2e9bcab362ca15e8f86d290daa9e88fc2118135004e734fb136998d7f4f46ac419e3a193775dd9ad5fb572fb170d71bd909c9f01a419b
7
+ data.tar.gz: be5d9d93ae1f824a250f8dbea0ca63d5318c1d109bc3d83a9a7d237305a2de899c102dd144eb9f03ecb6f653af7415616deecbf609ca30fba7a9941532d88d2a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Release History: opentelemetry-sdk
2
2
 
3
+ ### v1.0.2 / 2021-12-01
4
+
5
+ * FIXED: Default span kind
6
+ * FIXED: Use monotonic clock where possible
7
+
8
+ ### v1.0.1 / 2021-10-29
9
+
10
+ * FIXED: Add unexpected error handlign in BSP and OTLP exporter (#995)
11
+
12
+ ### v1.0.0 / 2021-09-29
13
+
14
+ * (No significant changes)
15
+
16
+ ### v1.0.0.rc3 / 2021-08-12
17
+
18
+ * BREAKING CHANGE: Remove optional parent_context from in_span
19
+ * BREAKING CHANGE: Replace Time.now with Process.clock_gettime
20
+ * BREAKING CHANGE: Refactor Baggage to remove Noop*
21
+ * BREAKING CHANGE: Remove unnecessary readers from SDK Tracer
22
+ * BREAKING CHANGE: Total order constraint on span.status=
23
+ * BREAKING CHANGE: Use auto-generated resource constants in sdk and resource_detectors
24
+ * BREAKING CHANGE: Span limits env vars
25
+
26
+ * ADDED: Add Tracer.non_recording_span to API
27
+ * ADDED: Add unnamed tracer warning message
28
+ * ADDED: Allow disabling of install messages
29
+ * ADDED: Make API's NoopTextMapPropagator private
30
+ * ADDED: Use auto-generated resource constants in sdk and resource_detectors
31
+ * ADDED: Allow selecting multiple exporter
32
+ * ADDED: Add explicit BSP export error
33
+ * FIXED: Remove optional parent_context from in_span
34
+ * FIXED: Replace Time.now with Process.clock_gettime
35
+ * FIXED: Rename cloud.zone to cloud.availability_zone
36
+ * FIXED: Improve attribute error messages
37
+ * FIXED: Refactor Baggage to remove Noop*
38
+ * FIXED: Support OTEL_SERVICE_NAME env var
39
+ * FIXED: Remove unnecessary readers from SDK Tracer
40
+ * FIXED: Total order constraint on span.status=
41
+ * FIXED: Flakey tracer provider test
42
+ * FIXED: Split lock in TracerProvider
43
+ * FIXED: Span limits env vars
44
+ * FIXED: Prune invalid links
45
+ * DOCS: Update docs to rely more on environment variable configuration
46
+
3
47
  ### v1.0.0.rc2 / 2021-06-23
4
48
 
5
49
  * BREAKING CHANGE: Remove optional parent_context from in_span [729](https://github.com/open-telemetry/opentelemetry-ruby/pull/729)
data/README.md CHANGED
@@ -29,10 +29,33 @@ Then, configure the SDK according to your desired handling of telemetry data, an
29
29
  ```ruby
30
30
  require 'opentelemetry/sdk'
31
31
 
32
- # Configure the sdk with default export and context propagation formats
33
- # see SDK#configure for customizing the setup
32
+ # Configure the sdk with default export and context propagation formats.
34
33
  OpenTelemetry::SDK.configure
35
34
 
35
+ # Many configuration options may be set via the environment. To use them,
36
+ # set the appropriate variable before calling configure. For example:
37
+ #
38
+ # ENV['OTEL_TRACES_EXPORTER'] = 'console'
39
+ # ENV['OTEL_PROPAGATORS'] = 'ottrace'
40
+ # OpenTelemetry::SDK.configure
41
+ #
42
+ # You may also configure the SDK programmatically, for advanced usage or to
43
+ # enable auto-instrumentation. For example:
44
+ #
45
+ # OpenTelemetry::SDK.configure do |c|
46
+ # c.service_name = something_calculated_dynamically
47
+ # c.add_span_processor(
48
+ # OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
49
+ # OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
50
+ # )
51
+ # )
52
+ #
53
+ # c.use 'OpenTelemetry::Instrumentation::Net::HTTP'
54
+ # end
55
+ #
56
+ # Note that the SimpleSpanExporter is not recommended for use in production.
57
+
58
+
36
59
  # To start a trace you need to get a Tracer from the TracerProvider
37
60
  tracer = OpenTelemetry.tracer_provider.tracer('my_app_or_gem', '0.1.0')
38
61
 
@@ -9,6 +9,22 @@ module OpenTelemetry
9
9
  # The configurator provides defaults and facilitates configuring the
10
10
  # SDK for use.
11
11
  class Configurator # rubocop:disable Metrics/ClassLength
12
+ # @api private
13
+ class NoopTextMapPropagator
14
+ EMPTY_LIST = [].freeze
15
+ private_constant(:EMPTY_LIST)
16
+
17
+ def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter); end
18
+
19
+ def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
20
+ context
21
+ end
22
+
23
+ def fields
24
+ EMPTY_LIST
25
+ end
26
+ end
27
+
12
28
  USE_MODE_UNSPECIFIED = 0
13
29
  USE_MODE_ONE = 1
14
30
  USE_MODE_ALL = 2
@@ -60,7 +76,7 @@ module OpenTelemetry
60
76
  # @param [String] service_name The value to be used as the service name
61
77
  def service_name=(service_name)
62
78
  self.resource = OpenTelemetry::SDK::Resources::Resource.create(
63
- OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:name] => service_name
79
+ OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => service_name
64
80
  )
65
81
  end
66
82
 
@@ -70,7 +86,7 @@ module OpenTelemetry
70
86
  # @param [String] service_version The value to be used as the service version
71
87
  def service_version=(service_version)
72
88
  self.resource = OpenTelemetry::SDK::Resources::Resource.create(
73
- OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:version] => service_version
89
+ OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION => service_version
74
90
  )
75
91
  end
76
92
 
@@ -149,21 +165,23 @@ module OpenTelemetry
149
165
  end
150
166
 
151
167
  def configure_span_processors
152
- processors = @span_processors.empty? ? [wrapped_exporter_from_env].compact : @span_processors
168
+ processors = @span_processors.empty? ? wrapped_exporters_from_env.compact : @span_processors
153
169
  processors.each { |p| tracer_provider.add_span_processor(p) }
154
170
  end
155
171
 
156
- def wrapped_exporter_from_env
157
- exporter = ENV.fetch('OTEL_TRACES_EXPORTER', 'otlp')
158
- case exporter
159
- when 'none' then nil
160
- when 'otlp' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::OTLP::Exporter')
161
- when 'jaeger' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Jaeger::CollectorExporter')
162
- when 'zipkin' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Zipkin::Exporter')
163
- when 'console' then Trace::Export::SimpleSpanProcessor.new(Trace::Export::ConsoleSpanExporter.new)
164
- else
165
- OpenTelemetry.logger.warn "The #{exporter} exporter is unknown and cannot be configured, spans will not be exported"
166
- nil
172
+ def wrapped_exporters_from_env
173
+ exporters = ENV.fetch('OTEL_TRACES_EXPORTER', 'otlp')
174
+ exporters.split(',').map do |exporter|
175
+ case exporter.strip
176
+ when 'none' then nil
177
+ when 'otlp' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::OTLP::Exporter')
178
+ when 'jaeger' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Jaeger::CollectorExporter')
179
+ when 'zipkin' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Zipkin::Exporter')
180
+ when 'console' then Trace::Export::SimpleSpanProcessor.new(Trace::Export::ConsoleSpanExporter.new)
181
+ else
182
+ OpenTelemetry.logger.warn "The #{exporter} exporter is unknown and cannot be configured, spans will not be exported"
183
+ nil
184
+ end
167
185
  end
168
186
  end
169
187
 
@@ -179,7 +197,7 @@ module OpenTelemetry
179
197
  when 'ottrace' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::OTTrace')
180
198
  else
181
199
  OpenTelemetry.logger.warn "The #{propagator} propagator is unknown and cannot be configured"
182
- Context::Propagation::NoopTextMapPropagator.new
200
+ NoopTextMapPropagator.new
183
201
  end
184
202
  end
185
203
  OpenTelemetry.propagation = Context::Propagation::CompositeTextMapPropagator.compose_propagators((@propagators || propagators).compact)
@@ -31,14 +31,14 @@ module OpenTelemetry
31
31
  end
32
32
 
33
33
  def default
34
- @default ||= create(Constants::SERVICE_RESOURCE[:name] => 'unknown_service').merge(process).merge(telemetry_sdk).merge(service_name_from_env)
34
+ @default ||= create(SemanticConventions::Resource::SERVICE_NAME => 'unknown_service').merge(process).merge(telemetry_sdk).merge(service_name_from_env)
35
35
  end
36
36
 
37
37
  def telemetry_sdk
38
38
  resource_attributes = {
39
- Constants::TELEMETRY_SDK_RESOURCE[:name] => 'opentelemetry',
40
- Constants::TELEMETRY_SDK_RESOURCE[:language] => 'ruby',
41
- Constants::TELEMETRY_SDK_RESOURCE[:version] => OpenTelemetry::SDK::VERSION
39
+ SemanticConventions::Resource::TELEMETRY_SDK_NAME => 'opentelemetry',
40
+ SemanticConventions::Resource::TELEMETRY_SDK_LANGUAGE => 'ruby',
41
+ SemanticConventions::Resource::TELEMETRY_SDK_VERSION => OpenTelemetry::SDK::VERSION
42
42
  }
43
43
 
44
44
  resource_pairs = ENV['OTEL_RESOURCE_ATTRIBUTES']
@@ -55,11 +55,11 @@ module OpenTelemetry
55
55
 
56
56
  def process
57
57
  resource_attributes = {
58
- Constants::PROCESS_RESOURCE[:pid] => Process.pid,
59
- Constants::PROCESS_RESOURCE[:command] => $PROGRAM_NAME,
60
- Constants::PROCESS_RUNTIME_RESOURCE[:name] => RUBY_ENGINE,
61
- Constants::PROCESS_RUNTIME_RESOURCE[:version] => RUBY_VERSION,
62
- Constants::PROCESS_RUNTIME_RESOURCE[:description] => RUBY_DESCRIPTION
58
+ SemanticConventions::Resource::PROCESS_PID => Process.pid,
59
+ SemanticConventions::Resource::PROCESS_COMMAND => $PROGRAM_NAME,
60
+ SemanticConventions::Resource::PROCESS_RUNTIME_NAME => RUBY_ENGINE,
61
+ SemanticConventions::Resource::PROCESS_RUNTIME_VERSION => RUBY_VERSION,
62
+ SemanticConventions::Resource::PROCESS_RUNTIME_DESCRIPTION => RUBY_DESCRIPTION
63
63
  }
64
64
 
65
65
  create(resource_attributes)
@@ -69,7 +69,7 @@ module OpenTelemetry
69
69
 
70
70
  def service_name_from_env
71
71
  service_name = ENV['OTEL_SERVICE_NAME']
72
- create(Constants::SERVICE_RESOURCE[:name] => service_name) unless service_name.nil?
72
+ create(SemanticConventions::Resource::SERVICE_NAME => service_name) unless service_name.nil?
73
73
  end
74
74
  end
75
75
 
@@ -13,4 +13,3 @@ module OpenTelemetry
13
13
  end
14
14
 
15
15
  require 'opentelemetry/sdk/resources/resource'
16
- require 'opentelemetry/sdk/resources/constants'
@@ -146,9 +146,9 @@ module OpenTelemetry
146
146
 
147
147
  thread&.join(timeout)
148
148
  force_flush(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
149
- @exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
150
149
  dropped_spans = lock { spans.size }
151
150
  report_dropped_spans(dropped_spans, reason: 'terminating') if dropped_spans.positive?
151
+ @exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
152
152
  end
153
153
 
154
154
  private
@@ -187,6 +187,10 @@ module OpenTelemetry
187
187
  result_code = @export_mutex.synchronize { @exporter.export(batch, timeout: timeout) }
188
188
  report_result(result_code, batch)
189
189
  result_code
190
+ rescue StandardError => e
191
+ report_result(FAILURE, batch)
192
+ @metrics_reporter.add_to_counter('otel.bsp.error', labels: { 'reason' => e.class.to_s })
193
+ FAILURE
190
194
  end
191
195
 
192
196
  def report_result(result_code, batch)
@@ -194,7 +198,7 @@ module OpenTelemetry
194
198
  @metrics_reporter.add_to_counter('otel.bsp.export.success')
195
199
  @metrics_reporter.add_to_counter('otel.bsp.exported_spans', increment: batch.size)
196
200
  else
197
- OpenTelemetry.handle_error(message: "Unable to export #{batch.size} spans")
201
+ OpenTelemetry.handle_error(exception: ExportError.new("Unable to export #{batch.size} spans"))
198
202
  @metrics_reporter.add_to_counter('otel.bsp.export.failure')
199
203
  report_dropped_spans(batch.size, reason: 'export-failure')
200
204
  end
@@ -10,6 +10,8 @@ module OpenTelemetry
10
10
  # The Export module contains the built-in exporters and span processors for the OpenTelemetry
11
11
  # reference implementation.
12
12
  module Export
13
+ ExportError = Class.new(OpenTelemetry::Error)
14
+
13
15
  # Result codes for the SpanExporter#export method and the SpanProcessor#force_flush and SpanProcessor#shutdown methods.
14
16
 
15
17
  # The operation finished successfully.
@@ -131,7 +131,7 @@ module OpenTelemetry
131
131
  #
132
132
  # @return [self] returns itself
133
133
  def add_event(name, attributes: nil, timestamp: nil)
134
- event = Event.new(name, truncate_attribute_values(attributes), wall_clock(timestamp))
134
+ event = Event.new(name, truncate_attribute_values(attributes), relative_timestamp(timestamp))
135
135
 
136
136
  @mutex.synchronize do
137
137
  if @ended
@@ -233,7 +233,7 @@ module OpenTelemetry
233
233
  OpenTelemetry.logger.warn('Calling finish on an ended Span.')
234
234
  return self
235
235
  end
236
- @end_timestamp = wall_clock(end_timestamp)
236
+ @end_timestamp = relative_timestamp(end_timestamp)
237
237
  @attributes = validated_attributes(@attributes).freeze
238
238
  @events.freeze
239
239
  @ended = true
@@ -276,7 +276,7 @@ module OpenTelemetry
276
276
  end
277
277
 
278
278
  # @api private
279
- def initialize(context, parent_context, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
279
+ def initialize(context, parent_context, parent_span, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
280
280
  super(span_context: context)
281
281
  @mutex = Mutex.new
282
282
  @name = name
@@ -291,17 +291,45 @@ module OpenTelemetry
291
291
  @total_recorded_events = 0
292
292
  @total_recorded_links = links&.size || 0
293
293
  @total_recorded_attributes = attributes&.size || 0
294
- @start_timestamp = wall_clock(start_timestamp)
295
- @end_timestamp = nil
296
294
  @attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
297
295
  trim_span_attributes(@attributes)
298
296
  @events = nil
299
- @links = trim_links(links, span_limits.link_count_limit, span_limits.attribute_per_link_count_limit)
297
+ @links = trim_links(links, span_limits.link_count_limit, span_limits.link_attribute_count_limit)
298
+
299
+ # Times are hard. Whenever an explicit timestamp is provided
300
+ # (for Events or for the Span start_timestamp or end_timestamp),
301
+ # we use that as the recorded timestamp. An implicit Event timestamp
302
+ # and end_timestamp is computed as a monotonic clock offset from
303
+ # the realtime start_timestamp. The realtime start_timestamp is
304
+ # computed as a monotonic clock offset from the realtime
305
+ # start_timestamp of its parent span, if available, or it is
306
+ # fetched from the realtime system clock.
307
+ #
308
+ # We therefore have 3 start timestamps. The first two are used
309
+ # internally (and by child spans) to compute other timestamps.
310
+ # The last is the start timestamp actually recorded in the
311
+ # SpanData.
312
+ @monotonic_start_timestamp = monotonic_now
313
+ @realtime_start_timestamp = if parent_span.recording?
314
+ relative_realtime(parent_span.realtime_start_timestamp, parent_span.monotonic_start_timestamp)
315
+ else
316
+ realtime_now
317
+ end
318
+ @start_timestamp = if start_timestamp
319
+ time_in_nanoseconds(start_timestamp)
320
+ else
321
+ @realtime_start_timestamp
322
+ end
323
+ @end_timestamp = nil
300
324
  @span_processors.each { |processor| processor.on_start(self, parent_context) }
301
325
  end
302
326
 
303
327
  # TODO: Java implementation overrides finalize to log if a span isn't finished.
304
328
 
329
+ protected
330
+
331
+ attr_reader :monotonic_start_timestamp, :realtime_start_timestamp
332
+
305
333
  private
306
334
 
307
335
  def validated_attributes(attrs)
@@ -327,20 +355,23 @@ module OpenTelemetry
327
355
  attrs
328
356
  end
329
357
 
330
- def trim_links(links, link_count_limit, attribute_per_link_count_limit) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
358
+ def trim_links(links, link_count_limit, link_attribute_count_limit) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
331
359
  # Fast path (likely) common cases.
332
360
  return nil if links.nil?
333
361
 
334
362
  if links.size <= link_count_limit &&
335
- links.all? { |link| link.attributes.size <= attribute_per_link_count_limit && Internal.valid_attributes?(name, 'link', link.attributes) }
363
+ links.all? { |link| link.span_context.valid? && link.attributes.size <= link_attribute_count_limit && Internal.valid_attributes?(name, 'link', link.attributes) }
336
364
  return links.frozen? ? links : links.clone.freeze
337
365
  end
338
366
 
339
367
  # Slow path: trim attributes for each Link.
340
- links.last(link_count_limit).map! do |link|
368
+ valid_links = links.select { |link| link.span_context.valid? }
369
+ excess_link_count = valid_links.size - link_count_limit
370
+ valid_links.pop(excess_link_count) if excess_link_count.positive?
371
+ valid_links.map! do |link|
341
372
  attrs = Hash[link.attributes] # link.attributes is frozen, so we need an unfrozen copy to adjust.
342
373
  attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
343
- excess = attrs.size - attribute_per_link_count_limit
374
+ excess = attrs.size - link_attribute_count_limit
344
375
  excess.times { attrs.shift } if excess.positive?
345
376
  OpenTelemetry::Trace::Link.new(link.span_context, attrs)
346
377
  end.freeze
@@ -348,12 +379,12 @@ module OpenTelemetry
348
379
 
349
380
  def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
350
381
  event_count_limit = @span_limits.event_count_limit
351
- attribute_per_event_count_limit = @span_limits.attribute_per_event_count_limit
382
+ event_attribute_count_limit = @span_limits.event_attribute_count_limit
352
383
  valid_attributes = Internal.valid_attributes?(name, 'event', event.attributes)
353
384
 
354
385
  # Fast path (likely) common case.
355
386
  if events.size < event_count_limit &&
356
- event.attributes.size <= attribute_per_event_count_limit &&
387
+ event.attributes.size <= event_attribute_count_limit &&
357
388
  valid_attributes
358
389
  return events << event
359
390
  end
@@ -362,20 +393,37 @@ module OpenTelemetry
362
393
  excess = events.size + 1 - event_count_limit
363
394
  events.shift(excess) if excess.positive?
364
395
 
365
- excess = event.attributes.size - attribute_per_event_count_limit
396
+ excess = event.attributes.size - event_attribute_count_limit
366
397
  if excess.positive? || !valid_attributes
367
398
  attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
368
399
  attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
369
- excess = attrs.size - attribute_per_event_count_limit
400
+ excess = attrs.size - event_attribute_count_limit
370
401
  excess.times { attrs.shift } if excess.positive?
371
402
  event = Event.new(event.name, attrs.freeze, event.timestamp)
372
403
  end
373
404
  events << event
374
405
  end
375
406
 
376
- def wall_clock(timestamp)
377
- timestamp = (timestamp.to_r * 1_000_000_000).to_i unless timestamp.nil?
378
- timestamp || Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
407
+ def relative_timestamp(timestamp)
408
+ return time_in_nanoseconds(timestamp) unless timestamp.nil?
409
+
410
+ relative_realtime(realtime_start_timestamp, monotonic_start_timestamp)
411
+ end
412
+
413
+ def time_in_nanoseconds(timestamp)
414
+ (timestamp.to_r * 1_000_000_000).to_i
415
+ end
416
+
417
+ def relative_realtime(realtime_base, monotonic_base)
418
+ realtime_base + (monotonic_now - monotonic_base)
419
+ end
420
+
421
+ def realtime_now
422
+ Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
423
+ end
424
+
425
+ def monotonic_now
426
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
379
427
  end
380
428
  end
381
429
  # rubocop:enable Metrics/ClassLength
@@ -22,10 +22,10 @@ module OpenTelemetry
22
22
  attr_reader :link_count_limit
23
23
 
24
24
  # The global default max number of attributes per {OpenTelemetry::SDK::Trace::Event}.
25
- attr_reader :attribute_per_event_count_limit
25
+ attr_reader :event_attribute_count_limit
26
26
 
27
27
  # The global default max number of attributes per {OpenTelemetry::Trace::Link}.
28
- attr_reader :attribute_per_link_count_limit
28
+ attr_reader :link_attribute_count_limit
29
29
 
30
30
  # Returns a {SpanLimits} with the desired values.
31
31
  #
@@ -35,21 +35,21 @@ module OpenTelemetry
35
35
  attribute_length_limit: ENV['OTEL_RUBY_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT'],
36
36
  event_count_limit: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 128)),
37
37
  link_count_limit: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 128)),
38
- attribute_per_event_count_limit: attribute_count_limit,
39
- attribute_per_link_count_limit: attribute_count_limit)
38
+ event_attribute_count_limit: Integer(ENV.fetch('OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT', 128)),
39
+ link_attribute_count_limit: Integer(ENV.fetch('OTEL_LINK_ATTRIBUTE_COUNT_LIMIT', 128)))
40
40
  raise ArgumentError, 'attribute_count_limit must be positive' unless attribute_count_limit.positive?
41
41
  raise ArgumentError, 'attribute_length_limit must not be less than 32' unless attribute_length_limit.nil? || Integer(attribute_length_limit) >= 32
42
42
  raise ArgumentError, 'event_count_limit must be positive' unless event_count_limit.positive?
43
43
  raise ArgumentError, 'link_count_limit must be positive' unless link_count_limit.positive?
44
- raise ArgumentError, 'attribute_per_event_count_limit must be positive' unless attribute_per_event_count_limit.positive?
45
- raise ArgumentError, 'attribute_per_link_count_limit must be positive' unless attribute_per_link_count_limit.positive?
44
+ raise ArgumentError, 'event_attribute_count_limit must be positive' unless event_attribute_count_limit.positive?
45
+ raise ArgumentError, 'link_attribute_count_limit must be positive' unless link_attribute_count_limit.positive?
46
46
 
47
47
  @attribute_count_limit = attribute_count_limit
48
48
  @attribute_length_limit = attribute_length_limit.nil? ? nil : Integer(attribute_length_limit)
49
49
  @event_count_limit = event_count_limit
50
50
  @link_count_limit = link_count_limit
51
- @attribute_per_event_count_limit = attribute_per_event_count_limit
52
- @attribute_per_link_count_limit = attribute_per_link_count_limit
51
+ @event_attribute_count_limit = event_attribute_count_limit
52
+ @link_attribute_count_limit = link_attribute_count_limit
53
53
  end
54
54
 
55
55
  # The default {SpanLimits}.
@@ -31,12 +31,14 @@ module OpenTelemetry
31
31
  name ||= 'empty'
32
32
 
33
33
  with_parent ||= Context.current
34
+ parent_span = OpenTelemetry::Trace.current_span(with_parent)
34
35
  parent_span_context = OpenTelemetry::Trace.current_span(with_parent).context
35
36
  if parent_span_context.valid?
36
37
  parent_span_id = parent_span_context.span_id
37
38
  trace_id = parent_span_context.trace_id
38
39
  end
39
- @tracer_provider.internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent, @instrumentation_library)
40
+
41
+ @tracer_provider.internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent, parent_span, @instrumentation_library)
40
42
  end
41
43
  end
42
44
  end
@@ -33,6 +33,7 @@ module OpenTelemetry
33
33
  span_limits: SpanLimits::DEFAULT)
34
34
  @mutex = Mutex.new
35
35
  @registry = {}
36
+ @registry_mutex = Mutex.new
36
37
  @span_processors = []
37
38
  @span_limits = span_limits
38
39
  @sampler = sampler
@@ -51,7 +52,7 @@ module OpenTelemetry
51
52
  name ||= ''
52
53
  version ||= ''
53
54
  OpenTelemetry.logger.warn 'calling TracerProvider#tracer without providing a tracer name.' if name.empty?
54
- @mutex.synchronize { @registry[Key.new(name, version)] ||= Tracer.new(name, version, self) }
55
+ @registry_mutex.synchronize { @registry[Key.new(name, version)] ||= Tracer.new(name, version, self) }
55
56
  end
56
57
 
57
58
  # Attempts to stop all the activity for this {TracerProvider}. Calls
@@ -125,8 +126,15 @@ module OpenTelemetry
125
126
  end
126
127
 
127
128
  # @api private
128
- def internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context, instrumentation_library) # rubocop:disable Metrics/MethodLength
129
+ def internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context, parent_span, instrumentation_library) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
130
+ parent_span_context = parent_span.context
131
+ if parent_span_context.valid?
132
+ parent_span_id = parent_span_context.span_id
133
+ trace_id = parent_span_context.trace_id
134
+ end
135
+ name ||= 'empty'
129
136
  trace_id ||= @id_generator.generate_trace_id
137
+ kind ||= :internal
130
138
  result = @sampler.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
131
139
  span_id = @id_generator.generate_span_id
132
140
  if result.recording? && !@stopped
@@ -136,6 +144,7 @@ module OpenTelemetry
136
144
  Span.new(
137
145
  context,
138
146
  parent_context,
147
+ parent_span,
139
148
  name,
140
149
  kind,
141
150
  parent_span_id,
@@ -7,6 +7,6 @@
7
7
  module OpenTelemetry
8
8
  module SDK
9
9
  ## Current OpenTelemetry version
10
- VERSION = '1.0.0.rc2'
10
+ VERSION = '1.0.2'
11
11
  end
12
12
  end
@@ -7,6 +7,7 @@
7
7
  require 'opentelemetry'
8
8
  require 'opentelemetry/common'
9
9
  require 'opentelemetry-instrumentation-base'
10
+ require 'opentelemetry-semantic_conventions'
10
11
 
11
12
  # OpenTelemetry is an open source observability framework, providing a
12
13
  # general-purpose API, SDK, and related tools required for the instrumentation
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc2
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-24 00:00:00.000000000 Z
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -16,42 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0.rc2
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.0.rc2
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: opentelemetry-common
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.19.0
33
+ version: 0.19.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.19.0
40
+ version: 0.19.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: opentelemetry-instrumentation-base
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.18.1
47
+ version: 0.19.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.18.1
54
+ version: 0.19.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: opentelemetry-semantic_conventions
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -95,19 +109,33 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '5.0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: opentelemetry-exporter-jaeger
112
+ name: opentelemetry-exporter-zipkin
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 0.18.0
117
+ version: 0.19.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 0.18.0
124
+ version: 0.19.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: rake
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +206,20 @@ dependencies:
178
206
  - - "~>"
179
207
  - !ruby/object:Gem::Version
180
208
  version: 0.1.6
209
+ - !ruby/object:Gem::Dependency
210
+ name: pry-byebug
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
181
223
  description: A stats collection and distributed tracing framework
182
224
  email:
183
225
  - cncf-opentelemetry-contributors@lists.cncf.io
@@ -196,7 +238,6 @@ files:
196
238
  - lib/opentelemetry/sdk/instrumentation_library.rb
197
239
  - lib/opentelemetry/sdk/internal.rb
198
240
  - lib/opentelemetry/sdk/resources.rb
199
- - lib/opentelemetry/sdk/resources/constants.rb
200
241
  - lib/opentelemetry/sdk/resources/resource.rb
201
242
  - lib/opentelemetry/sdk/trace.rb
202
243
  - lib/opentelemetry/sdk/trace/event.rb
@@ -224,10 +265,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
224
265
  licenses:
225
266
  - Apache-2.0
226
267
  metadata:
227
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc2/file.CHANGELOG.html
268
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.2/file.CHANGELOG.html
228
269
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/sdk
229
270
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
230
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc2
271
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.2
231
272
  post_install_message:
232
273
  rdoc_options: []
233
274
  require_paths:
@@ -239,9 +280,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
239
280
  version: 2.5.0
240
281
  required_rubygems_version: !ruby/object:Gem::Requirement
241
282
  requirements:
242
- - - ">"
283
+ - - ">="
243
284
  - !ruby/object:Gem::Version
244
- version: 1.3.1
285
+ version: '0'
245
286
  requirements: []
246
287
  rubygems_version: 3.1.6
247
288
  signing_key:
@@ -1,205 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module OpenTelemetry
8
- module SDK
9
- module Resources
10
- module Constants
11
- # Attributes describing a service instance.
12
- SERVICE_RESOURCE = {
13
- # Logical name of the service.
14
- name: 'service.name',
15
-
16
- # A namespace for `service.name`.
17
- namespace: 'service.namespace',
18
-
19
- # The string ID of the service instance.
20
- instance_id: 'service.instance.id',
21
-
22
- # The version string of the service API or implementation.
23
- version: 'service.version'
24
- }.freeze
25
-
26
- # Attributes describing the telemetry library.
27
- TELEMETRY_SDK_RESOURCE = {
28
- # The name of the telemetry library.
29
- name: 'telemetry.sdk.name',
30
-
31
- # The language of the telemetry library and of the code instrumented with it.
32
- language: 'telemetry.sdk.language',
33
-
34
- # The version string of the telemetry library
35
- version: 'telemetry.sdk.version'
36
- }.freeze
37
-
38
- # Attributes defining a compute unit (e.g. Container, Process, Lambda
39
- # Function).
40
- CONTAINER_RESOURCE = {
41
- # The container name.
42
- name: 'container.name',
43
-
44
- # The name of the image the container was built on.
45
- image_name: 'container.image.name',
46
-
47
- # The container image tag.
48
- image_tag: 'container.image.tag'
49
- }.freeze
50
-
51
- FAAS_RESOURCE = {
52
- # The name of the function being executed.
53
- name: 'faas.name',
54
-
55
- # The unique name of the function being executed.
56
- id: 'faas.id',
57
-
58
- # The version string of the function being executed.
59
- version: 'faas.version',
60
-
61
- # The execution environment ID as a string.
62
- instance: 'faas.instance'
63
- }.freeze
64
-
65
- # Attributes defining a deployment service (e.g. Kubernetes).
66
- K8S_RESOURCE = {
67
- # The name of the cluster that the pod is running in.
68
- cluster_name: 'k8s.cluster.name',
69
-
70
- # The name of the Node.
71
- node_name: 'k8s.node.name',
72
-
73
- # The UID of the Node.
74
- node_uid: 'k8s.node.uid',
75
-
76
- # The name of the namespace that the pod is running in.
77
- namespace_name: 'k8s.namespace.name',
78
-
79
- # The name of the pod.
80
- pod_name: 'k8s.pod.name',
81
-
82
- # The UID of the Pod.
83
- pod_uid: 'k8s.pod.uid',
84
-
85
- # The name of the Container in a Pod template.
86
- container_name: 'k8s.container.name',
87
-
88
- # The UID of the ReplicaSet.
89
- replicaset_uid: 'k8s.replicaset.uid',
90
-
91
- # The name of the ReplicaSet.
92
- replicaset_name: 'k8s.replicaset.name',
93
-
94
- # The UID of the Deployment.
95
- deployment_uid: 'k8s.deployment.uid',
96
-
97
- # The name of the deployment.
98
- deployment_name: 'k8s.deployment.name',
99
-
100
- # The UID of the StatefulSet.
101
- statefulset_uid: 'k8s.statefulset.uid',
102
-
103
- # The name of the StatefulSet.
104
- statefulset_name: 'k8s.statefulset.name',
105
-
106
- # The UID of the DaemonSet.
107
- daemonset_uid: 'k8s.daemonset.uid',
108
-
109
- # The name of the DaemonSet.
110
- daemonset_name: 'k8s.daemonset.name',
111
-
112
- # The UID of the Job.
113
- job_uid: 'k8s.job.uid',
114
-
115
- # The name of the Job.
116
- job_name: 'k8s.job.name',
117
-
118
- # The UID of the CronJob.
119
- cronjob_uid: 'k8s.cronjob.uid',
120
-
121
- # The name of the CronJob.
122
- cronjob_name: 'k8s.cronjob.name'
123
- }.freeze
124
-
125
- # Attributes defining an operating system process.
126
- PROCESS_RESOURCE = {
127
- # Process identifier (PID).
128
- pid: 'process.pid',
129
-
130
- # The name of the process executable.
131
- executable_name: 'process.executable.name',
132
-
133
- # The full path to the process executable.
134
- executable_path: 'process.executable.path',
135
-
136
- # The command used to launch the process (i.e. the command name).
137
- command: 'process.command',
138
-
139
- # The full command used to launch the process as a single string
140
- # representing the full command.
141
- command_line: 'process.command_line',
142
-
143
- # All the command arguments (including the command/executable itself)
144
- # as received by the process.
145
- command_args: 'process.command_args',
146
-
147
- # The username of the user that owns the process.
148
- owner: 'process.owner'
149
- }.freeze
150
-
151
- # Attributes defining the single (language) runtime instance which is monitored.
152
- PROCESS_RUNTIME_RESOURCE = {
153
- # The name of the runtime of this process.
154
- name: 'process.runtime.name',
155
-
156
- # The version of the runtime of this process, as returned by the runtime
157
- # without modification.
158
- version: 'process.runtime.version',
159
-
160
- # An additional description about the runtime of the process, for example
161
- # a specific vendor customization of the runtime environment.
162
- description: 'process.runtime.description'
163
- }.freeze
164
-
165
- # Attributes defining a computing instance (e.g. host).
166
- HOST_RESOURCE = {
167
- # Unique host id. For Cloud this must be the instance_id assigned by the
168
- # cloud provider
169
- id: 'host.id',
170
-
171
- # Name of the host. It may contain what hostname returns on Unix systems,
172
- # the fully qualified, or a name specified by the user.
173
- name: 'host.name',
174
-
175
- # Type of host. For Cloud this must be the machine type.
176
- type: 'host.type',
177
-
178
- # Name of the VM image or OS install the host was instantiated from.
179
- image_name: 'host.image.name',
180
-
181
- # VM image id. For Cloud, this value is from the provider.
182
- image_id: 'host.image.id',
183
-
184
- # The version string of the VM image.
185
- image_version: 'host.image.version'
186
- }.freeze
187
-
188
- # Attributes defining a running environment (e.g. Cloud, Data Center).
189
- CLOUD_RESOURCE = {
190
- # Name of the cloud provider. Example values are aws, azure, gcp.
191
- provider: 'cloud.provider',
192
-
193
- # The cloud account id used to identify different entities.
194
- account_id: 'cloud.account.id',
195
-
196
- # A specific geographical location where different entities can run.
197
- region: 'cloud.region',
198
-
199
- # Availability zones are a sub set of the region connected through low-latency links.
200
- availability_zone: 'cloud.availability_zone'
201
- }.freeze
202
- end
203
- end
204
- end
205
- end