opentelemetry-sdk 0.8.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/LICENSE +1 -1
  4. data/lib/opentelemetry-sdk.rb +1 -1
  5. data/lib/opentelemetry/sdk.rb +13 -1
  6. data/lib/opentelemetry/sdk/baggage.rb +1 -1
  7. data/lib/opentelemetry/sdk/baggage/builder.rb +1 -1
  8. data/lib/opentelemetry/sdk/baggage/manager.rb +1 -1
  9. data/lib/opentelemetry/sdk/configurator.rb +9 -2
  10. data/lib/opentelemetry/sdk/instrumentation_library.rb +1 -1
  11. data/lib/opentelemetry/sdk/internal.rb +12 -2
  12. data/lib/opentelemetry/sdk/resources.rb +1 -1
  13. data/lib/opentelemetry/sdk/resources/constants.rb +1 -1
  14. data/lib/opentelemetry/sdk/resources/resource.rb +2 -2
  15. data/lib/opentelemetry/sdk/trace.rb +1 -1
  16. data/lib/opentelemetry/sdk/trace/config.rb +1 -1
  17. data/lib/opentelemetry/sdk/trace/config/trace_config.rb +23 -21
  18. data/lib/opentelemetry/sdk/trace/event.rb +1 -1
  19. data/lib/opentelemetry/sdk/trace/export.rb +2 -1
  20. data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +67 -30
  21. data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +3 -3
  22. data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +5 -3
  23. data/lib/opentelemetry/sdk/trace/export/metrics_reporter.rb +59 -0
  24. data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +15 -17
  25. data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +6 -3
  26. data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +13 -5
  27. data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +21 -5
  28. data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +5 -3
  29. data/lib/opentelemetry/sdk/trace/samplers.rb +7 -13
  30. data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +12 -5
  31. data/lib/opentelemetry/sdk/trace/samplers/decision.rb +1 -1
  32. data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +17 -4
  33. data/lib/opentelemetry/sdk/trace/samplers/result.rb +14 -3
  34. data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +8 -5
  35. data/lib/opentelemetry/sdk/trace/span.rb +12 -7
  36. data/lib/opentelemetry/sdk/trace/span_data.rb +1 -1
  37. data/lib/opentelemetry/sdk/trace/tracer.rb +9 -11
  38. data/lib/opentelemetry/sdk/trace/tracer_provider.rb +7 -4
  39. data/lib/opentelemetry/sdk/version.rb +2 -2
  40. metadata +21 -6
@@ -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
 
@@ -18,7 +18,7 @@ module OpenTelemetry
18
18
  @stopped = false
19
19
  end
20
20
 
21
- def export(spans)
21
+ def export(spans, timeout: nil)
22
22
  return FAILURE if @stopped
23
23
 
24
24
  Array(spans).each { |s| pp s }
@@ -26,7 +26,7 @@ module OpenTelemetry
26
26
  SUCCESS
27
27
  end
28
28
 
29
- def shutdown
29
+ def shutdown(timeout: nil)
30
30
  @stopped = true
31
31
  SUCCESS
32
32
  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
 
@@ -60,9 +60,10 @@ module OpenTelemetry
60
60
  #
61
61
  # @param [Enumerable<SpanData>] span_datas the list of sampled {SpanData}s to be
62
62
  # exported.
63
+ # @param [optional Numeric] timeout An optional timeout in seconds.
63
64
  # @return [Integer] the result of the export, SUCCESS or
64
65
  # FAILURE
65
- def export(span_datas)
66
+ def export(span_datas, timeout: nil)
66
67
  @mutex.synchronize do
67
68
  return FAILURE if @stopped
68
69
 
@@ -74,9 +75,10 @@ module OpenTelemetry
74
75
  # Called when {TracerProvider#shutdown} is called, if this exporter is
75
76
  # registered to a {TracerProvider} object.
76
77
  #
78
+ # @param [optional Numeric] timeout An optional timeout in seconds.
77
79
  # @return [Integer] SUCCESS if no error occurred, FAILURE if a
78
80
  # non-specific failure occurred, TIMEOUT if a timeout occurred.
79
- def shutdown
81
+ def shutdown(timeout: nil)
80
82
  @mutex.synchronize do
81
83
  @finished_spans.clear
82
84
  @stopped = true
@@ -0,0 +1,59 @@
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 Trace
10
+ module Export
11
+ # MetricsReporter defines an interface used for reporting metrics from
12
+ # span processors (like the BatchSpanProcessor) and exporters. It can
13
+ # be used to report metrics such as dropped spans, and successful and
14
+ # failed export attempts. This exists to decouple the Trace SDK from
15
+ # the unstable OpenTelemetry Metrics API. An example implementation in
16
+ # terms of StatsD is:
17
+ #
18
+ # module MetricsReporter
19
+ # def add_to_counter(metric, increment: 1, labels: {})
20
+ # StatsD.increment(metric, increment, labels, no_prefix: true)
21
+ # end
22
+ # def record_value(metric, value:, labels: {})
23
+ # StatsD.distribution(metric, value, labels, no_prefix: true)
24
+ # end
25
+ # def observe_value(metric, value:, labels: {})
26
+ # StatsD.gauge(metric, value, labels, no_prefix: true)
27
+ # end
28
+ # end
29
+ module MetricsReporter
30
+ extend self
31
+
32
+ # Adds an increment to a metric with the provided labels.
33
+ #
34
+ # @param [String] metric The metric name.
35
+ # @param [optional Numeric] increment An optional increment to report.
36
+ # @param [optional Hash<String, String>] labels Optional labels to
37
+ # associate with the metric.
38
+ def add_to_counter(metric, increment: 1, labels: {}); end
39
+
40
+ # Records a value for a metric with the provided labels.
41
+ #
42
+ # @param [String] metric The metric name.
43
+ # @param [Numeric] value The value to report.
44
+ # @param [optional Hash<String, String>] labels Optional labels to
45
+ # associate with the metric.
46
+ def record_value(metric, value:, labels: {}); end
47
+
48
+ # Observes a value for a metric with the provided labels.
49
+ #
50
+ # @param [String] metric The metric name.
51
+ # @param [Numeric] value The value to observe.
52
+ # @param [optional Hash<String, String>] labels Optional labels to
53
+ # associate with the metric.
54
+ def observe_value(metric, value:, labels: {}); end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ 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
 
@@ -23,36 +23,34 @@ module OpenTelemetry
23
23
  #
24
24
  # @param [Enumerable<Span>] spans the list of sampled {Span}s to be
25
25
  # exported.
26
+ # @param [optional Numeric] timeout An optional timeout in seconds.
26
27
  # @return [Integer] the result of the export.
27
- def export(spans)
28
- @span_exporters.inject(SUCCESS) do |result_code, span_exporter|
29
- merge_result_code(result_code, span_exporter.export(spans))
28
+ def export(spans, timeout: nil)
29
+ start_time = Time.now
30
+ results = @span_exporters.map do |span_exporter|
31
+ span_exporter.export(spans, timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
30
32
  rescue => e # rubocop:disable Style/RescueStandardError
31
33
  OpenTelemetry.logger.warn("exception raised by export - #{e}")
32
34
  FAILURE
33
35
  end
36
+ results.uniq.max || SUCCESS
34
37
  end
35
38
 
36
39
  # Called when {TracerProvider#shutdown} is called, if this exporter is
37
40
  # registered to a {TracerProvider} object.
38
41
  #
42
+ # @param [optional Numeric] timeout An optional timeout in seconds.
39
43
  # @return [Integer] SUCCESS if no error occurred, FAILURE if a
40
44
  # non-specific failure occurred, TIMEOUT if a timeout occurred.
41
- def shutdown
42
- @span_exporters.map(&:shutdown).uniq.max
43
- end
44
-
45
- private
45
+ def shutdown(timeout: nil)
46
+ start_time = Time.now
47
+ results = @span_exporters.map do |processor|
48
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
49
+ return TIMEOUT if remaining_timeout&.zero?
46
50
 
47
- # Returns a merged error code, see the rules in the code.
48
- def merge_result_code(result_code, new_result_code)
49
- if result_code == SUCCESS && new_result_code == SUCCESS
50
- # If both errors are success then return success.
51
- SUCCESS
52
- else
53
- # At this point at least one of the code is FAILURE, so return FAILURE.
54
- FAILURE
51
+ processor.shutdown(timeout: remaining_timeout)
55
52
  end
53
+ results.uniq.max || SUCCESS
56
54
  end
57
55
  end
58
56
  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
 
@@ -23,8 +23,9 @@ module OpenTelemetry
23
23
  #
24
24
  # @param [Enumerable<Span>] spans the list of sampled {Span}s to be
25
25
  # exported.
26
+ # @param [optional Numeric] timeout An optional timeout in seconds.
26
27
  # @return [Integer] the result of the export.
27
- def export(spans)
28
+ def export(spans, timeout: nil)
28
29
  return SUCCESS unless @stopped
29
30
 
30
31
  FAILURE
@@ -32,7 +33,9 @@ module OpenTelemetry
32
33
 
33
34
  # Called when {TracerProvider#shutdown} is called, if this exporter is
34
35
  # registered to a {TracerProvider} object.
35
- def shutdown
36
+ #
37
+ # @param [optional Numeric] timeout An optional timeout in seconds.
38
+ def shutdown(timeout: nil)
36
39
  @stopped = true
37
40
  SUCCESS
38
41
  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
 
@@ -12,6 +12,12 @@ module OpenTelemetry
12
12
  # {Span} to {io.opentelemetry.proto.trace.v1.Span} and passes it to the
13
13
  # configured exporter.
14
14
  #
15
+ # Typically, the SimpleSpanProcessor will be most suitable for use in testing;
16
+ # it should be used with caution in production. It may be appropriate for
17
+ # production use in scenarios where creating multiple threads is not desirable
18
+ # as well as scenarios where different custom attributes should be added to
19
+ # individual spans based on code scopes.
20
+ #
15
21
  # Only spans that are recorded are converted, {OpenTelemetry::Trace::Span#is_recording?} must
16
22
  # return true.
17
23
  class SimpleSpanProcessor
@@ -51,7 +57,7 @@ module OpenTelemetry
51
57
 
52
58
  @span_exporter&.export([span.to_span_data])
53
59
  rescue => e # rubocop:disable Style/RescueStandardError
54
- OpenTelemetry.logger.error("unexpected error in span.on_finish - #{e}")
60
+ OpenTelemetry.handle_error(exception: e, message: 'unexpected error in span.on_finish')
55
61
  end
56
62
 
57
63
  # Export all ended spans to the configured `Exporter` that have not yet
@@ -62,18 +68,20 @@ module OpenTelemetry
62
68
  # the process after an invocation, but before the `Processor` exports
63
69
  # the completed spans.
64
70
  #
71
+ # @param [optional Numeric] timeout An optional timeout in seconds.
65
72
  # @return [Integer] SUCCESS if no error occurred, FAILURE if a
66
73
  # non-specific failure occurred, TIMEOUT if a timeout occurred.
67
- def force_flush
74
+ def force_flush(timeout: nil)
68
75
  SUCCESS
69
76
  end
70
77
 
71
78
  # Called when {TracerProvider#shutdown} is called.
72
79
  #
80
+ # @param [optional Numeric] timeout An optional timeout in seconds.
73
81
  # @return [Integer] SUCCESS if no error occurred, FAILURE if a
74
82
  # non-specific failure occurred, TIMEOUT if a timeout occurred.
75
- def shutdown
76
- @span_exporter&.shutdown || SUCCESS
83
+ def shutdown(timeout: nil)
84
+ @span_exporter&.shutdown(timeout: timeout) || SUCCESS
77
85
  end
78
86
  end
79
87
  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
 
@@ -51,18 +51,34 @@ module OpenTelemetry
51
51
  # the process after an invocation, but before the `Processor` exports
52
52
  # the completed spans.
53
53
  #
54
+ # @param [optional Numeric] timeout An optional timeout in seconds.
54
55
  # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
55
56
  # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
56
- def force_flush
57
- @span_processors.map(&:force_flush).uniq.max
57
+ def force_flush(timeout: nil)
58
+ start_time = Time.now
59
+ results = @span_processors.map do |processor|
60
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
61
+ return Export::TIMEOUT if remaining_timeout&.zero?
62
+
63
+ processor.force_flush(timeout: remaining_timeout)
64
+ end
65
+ results.uniq.max
58
66
  end
59
67
 
60
68
  # Called when {TracerProvider#shutdown} is called.
61
69
  #
70
+ # @param [optional Numeric] timeout An optional timeout in seconds.
62
71
  # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
63
72
  # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
64
- def shutdown
65
- @span_processors.map(&:shutdown).uniq.max
73
+ def shutdown(timeout: nil)
74
+ start_time = Time.now
75
+ results = @span_processors.map do |processor|
76
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
77
+ return Export::TIMEOUT if remaining_timeout&.zero?
78
+
79
+ processor.shutdown(timeout: remaining_timeout)
80
+ end
81
+ results.uniq.max
66
82
  end
67
83
  end
68
84
  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
 
@@ -43,17 +43,19 @@ module OpenTelemetry
43
43
  # the process after an invocation, but before the `Processor` exports
44
44
  # the completed spans.
45
45
  #
46
+ # @param [optional Numeric] timeout An optional timeout in seconds.
46
47
  # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
47
48
  # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
48
- def force_flush
49
+ def force_flush(timeout: nil)
49
50
  Export::SUCCESS
50
51
  end
51
52
 
52
53
  # Called when {TracerProvider#shutdown} is called.
53
54
  #
55
+ # @param [optional Numeric] timeout An optional timeout in seconds.
54
56
  # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
55
57
  # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
56
- def shutdown
58
+ def shutdown(timeout: nil)
57
59
  Export::SUCCESS
58
60
  end
59
61
  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
 
@@ -25,9 +25,10 @@ module OpenTelemetry
25
25
  # Where:
26
26
  #
27
27
  # @param [String] trace_id The trace_id of the {Span} to be created.
28
- # @param [OpenTelemetry::Trace::SpanContext] parent_context The
29
- # {OpenTelemetry::Trace::SpanContext} of a parent span, typically
30
- # extracted from the wire. Can be nil for a root span.
28
+ # @param [OpenTelemetry::Context] parent_context The
29
+ # {OpenTelemetry::Context} with a parent {Span}. The {Span}'s
30
+ # {OpenTelemetry::Trace::SpanContext} may be invalid to indicate a
31
+ # root span.
31
32
  # @param [Enumerable<Link>] links A collection of links to be associated
32
33
  # with the {Span} to be created. Can be nil.
33
34
  # @param [String] name Name of the {Span} to be created.
@@ -37,18 +38,11 @@ module OpenTelemetry
37
38
  # to the {Span} to be created. Can be nil.
38
39
  # @return [Result] The sampling result.
39
40
  module Samplers
40
- RECORD_AND_SAMPLE = Result.new(decision: Decision::RECORD_AND_SAMPLE)
41
- DROP = Result.new(decision: Decision::DROP)
42
- RECORD_ONLY = Result.new(decision: Decision::RECORD_ONLY)
43
- SAMPLING_HINTS = [Decision::DROP, Decision::RECORD_ONLY, Decision::RECORD_AND_SAMPLE].freeze
44
-
45
- private_constant(:RECORD_AND_SAMPLE, :DROP, :RECORD_ONLY, :SAMPLING_HINTS)
46
-
47
41
  # Returns a {Result} with {Decision::RECORD_AND_SAMPLE}.
48
- ALWAYS_ON = ConstantSampler.new(result: RECORD_AND_SAMPLE, description: 'AlwaysOnSampler')
42
+ ALWAYS_ON = ConstantSampler.new(decision: Decision::RECORD_AND_SAMPLE, description: 'AlwaysOnSampler')
49
43
 
50
44
  # Returns a {Result} with {Decision::DROP}.
51
- ALWAYS_OFF = ConstantSampler.new(result: DROP, description: 'AlwaysOffSampler')
45
+ ALWAYS_OFF = ConstantSampler.new(decision: Decision::DROP, description: 'AlwaysOffSampler')
52
46
 
53
47
  # Returns a new sampler. It delegates to samplers according to the following rules:
54
48
  #
@@ -10,22 +10,29 @@ module OpenTelemetry
10
10
  module Samplers
11
11
  # @api private
12
12
  #
13
- # Implements a sampler returning a constant result.
13
+ # Implements a sampler returning a result with a constant decision.
14
14
  class ConstantSampler
15
15
  attr_reader :description
16
16
 
17
- def initialize(result:, description:)
18
- @result = result
17
+ def initialize(decision:, description:)
18
+ @decision = decision
19
19
  @description = description
20
20
  end
21
21
 
22
+ def ==(other)
23
+ @decision == other.decision && @description == other.description
24
+ end
25
+
22
26
  # @api private
23
27
  #
24
28
  # See {Samplers}.
25
29
  def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
26
- # All arguments ignored for sampling decision.
27
- @result
30
+ Result.new(decision: @decision, tracestate: OpenTelemetry::Trace.current_span(parent_context).context.tracestate)
28
31
  end
32
+
33
+ protected
34
+
35
+ attr_reader :decision
29
36
  end
30
37
  end
31
38
  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
 
@@ -26,6 +26,14 @@ module OpenTelemetry
26
26
  @local_parent_not_sampled = local_parent_not_sampled
27
27
  end
28
28
 
29
+ def ==(other)
30
+ @root == other.root &&
31
+ @remote_parent_sampled == other.remote_parent_sampled &&
32
+ @remote_parent_not_sampled == other.remote_parent_not_sampled &&
33
+ @local_parent_sampled == other.local_parent_sampled &&
34
+ @local_parent_not_sampled == other.local_parent_not_sampled
35
+ end
36
+
29
37
  # @api private
30
38
  #
31
39
  # See {Samplers}.
@@ -37,15 +45,20 @@ module OpenTelemetry
37
45
  #
38
46
  # See {Samplers}.
39
47
  def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
40
- delegate = if parent_context.nil?
48
+ parent_span_context = OpenTelemetry::Trace.current_span(parent_context).context
49
+ delegate = if !parent_span_context.valid?
41
50
  @root
42
- elsif parent_context.remote?
43
- parent_context.trace_flags.sampled? ? @remote_parent_sampled : @remote_parent_not_sampled
51
+ elsif parent_span_context.remote?
52
+ parent_span_context.trace_flags.sampled? ? @remote_parent_sampled : @remote_parent_not_sampled
44
53
  else
45
- parent_context.trace_flags.sampled? ? @local_parent_sampled : @local_parent_not_sampled
54
+ parent_span_context.trace_flags.sampled? ? @local_parent_sampled : @local_parent_not_sampled
46
55
  end
47
56
  delegate.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
48
57
  end
58
+
59
+ protected
60
+
61
+ attr_reader :root, :remote_parent_sampled, :remote_parent_not_sampled, :local_parent_sampled, :local_parent_not_sampled
49
62
  end
50
63
  end
51
64
  end