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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/LICENSE +1 -1
- data/lib/opentelemetry-sdk.rb +1 -1
- data/lib/opentelemetry/sdk.rb +13 -1
- data/lib/opentelemetry/sdk/baggage.rb +1 -1
- data/lib/opentelemetry/sdk/baggage/builder.rb +1 -1
- data/lib/opentelemetry/sdk/baggage/manager.rb +1 -1
- data/lib/opentelemetry/sdk/configurator.rb +9 -2
- data/lib/opentelemetry/sdk/instrumentation_library.rb +1 -1
- data/lib/opentelemetry/sdk/internal.rb +12 -2
- data/lib/opentelemetry/sdk/resources.rb +1 -1
- data/lib/opentelemetry/sdk/resources/constants.rb +1 -1
- data/lib/opentelemetry/sdk/resources/resource.rb +2 -2
- data/lib/opentelemetry/sdk/trace.rb +1 -1
- data/lib/opentelemetry/sdk/trace/config.rb +1 -1
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +23 -21
- data/lib/opentelemetry/sdk/trace/event.rb +1 -1
- data/lib/opentelemetry/sdk/trace/export.rb +2 -1
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +67 -30
- data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +3 -3
- data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +5 -3
- data/lib/opentelemetry/sdk/trace/export/metrics_reporter.rb +59 -0
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +15 -17
- data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +6 -3
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +13 -5
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +21 -5
- data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +5 -3
- data/lib/opentelemetry/sdk/trace/samplers.rb +7 -13
- data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +12 -5
- data/lib/opentelemetry/sdk/trace/samplers/decision.rb +1 -1
- data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +17 -4
- data/lib/opentelemetry/sdk/trace/samplers/result.rb +14 -3
- data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +8 -5
- data/lib/opentelemetry/sdk/trace/span.rb +12 -7
- data/lib/opentelemetry/sdk/trace/span_data.rb +1 -1
- data/lib/opentelemetry/sdk/trace/tracer.rb +9 -11
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +7 -4
- data/lib/opentelemetry/sdk/version.rb +2 -2
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 718ea2029bb234ea6ed56da8b65923595e275bb4730c3f3ea50bc20c4a01597d
|
4
|
+
data.tar.gz: 39e4031d0ef4ff426fe9bd776b4e85a2dd351a77c9dc8e19b80330dc5bf9d544
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: caa3842133c57ab739e0c21d8e1cd5f9cd58293e1e34055eef6b18fd4ff0869a39edbe87bcbb0fef7e76ea733f9ea0f9ff84663cf70a3a88820b7074c78c156d
|
7
|
+
data.tar.gz: f3e8176d0b495ea3784b6f8e2b2676000e35b3db7a1fab7b0890014ff69accd9caa69a00af02b4668964d3837aabd470bdaec78bda0d06ada1a9cfe6f1b000a7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,40 @@
|
|
1
1
|
# Release History: opentelemetry-sdk
|
2
2
|
|
3
|
+
### v0.12.0 / 2020-12-24
|
4
|
+
|
5
|
+
* ADDED: Structured error handling
|
6
|
+
* ADDED: Pluggable ID generation
|
7
|
+
* FIXED: BSP dropped span buffer full reporting
|
8
|
+
* FIXED: Implement SDK environment variables
|
9
|
+
* FIXED: Remove incorrect TODO
|
10
|
+
|
11
|
+
### v0.11.1 / 2020-12-16
|
12
|
+
|
13
|
+
* FIXED: BSP dropped span buffer full reporting
|
14
|
+
|
15
|
+
### v0.11.0 / 2020-12-11
|
16
|
+
|
17
|
+
* ADDED: Metrics reporting from trace export
|
18
|
+
* FIXED: Copyright comments to not reference year
|
19
|
+
|
20
|
+
### v0.10.0 / 2020-12-03
|
21
|
+
|
22
|
+
* BREAKING CHANGE: Allow samplers to modify tracestate
|
23
|
+
|
24
|
+
* FIXED: Allow samplers to modify tracestate
|
25
|
+
|
26
|
+
### v0.9.0 / 2020-11-27
|
27
|
+
|
28
|
+
* BREAKING CHANGE: Pass full Context to samplers
|
29
|
+
* BREAKING CHANGE: Add timeout for force_flush and shutdown
|
30
|
+
|
31
|
+
* ADDED: Add OTEL_RUBY_BSP_START_THREAD_ON_BOOT env var
|
32
|
+
* ADDED: Add timeout for force_flush and shutdown
|
33
|
+
* FIXED: Signal at batch_size
|
34
|
+
* FIXED: SDK Span.recording? after finish
|
35
|
+
* FIXED: Pass full Context to samplers
|
36
|
+
* DOCS: Add documentation on usage scenarios for span processors
|
37
|
+
|
3
38
|
### v0.8.0 / 2020-10-27
|
4
39
|
|
5
40
|
* BREAKING CHANGE: Move context/span methods to Trace module
|
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
|
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.
|
data/lib/opentelemetry-sdk.rb
CHANGED
data/lib/opentelemetry/sdk.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
7
7
|
require 'opentelemetry'
|
8
|
+
require 'opentelemetry/common'
|
8
9
|
|
9
10
|
# OpenTelemetry is an open source observability framework, providing a
|
10
11
|
# general-purpose API, SDK, and related tools required for the instrumentation
|
@@ -17,6 +18,11 @@ module OpenTelemetry
|
|
17
18
|
module SDK
|
18
19
|
extend self
|
19
20
|
|
21
|
+
# ConfigurationError is an exception type used to wrap configuration errors
|
22
|
+
# passed to OpenTelemetry.error_handler. This can be used to distinguish
|
23
|
+
# errors reported during SDK configuration.
|
24
|
+
ConfigurationError = Class.new(OpenTelemetry::Error)
|
25
|
+
|
20
26
|
# Configures SDK and instrumentation
|
21
27
|
#
|
22
28
|
# @yieldparam [Configurator] configurator Yields a configurator to the
|
@@ -56,6 +62,12 @@ module OpenTelemetry
|
|
56
62
|
configurator = Configurator.new
|
57
63
|
yield configurator if block_given?
|
58
64
|
configurator.configure
|
65
|
+
rescue StandardError
|
66
|
+
begin
|
67
|
+
raise ConfigurationError
|
68
|
+
rescue ConfigurationError => e
|
69
|
+
OpenTelemetry.handle_error(exception: e, message: 'unexpected configuration error')
|
70
|
+
end
|
59
71
|
end
|
60
72
|
end
|
61
73
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -16,7 +16,7 @@ module OpenTelemetry
|
|
16
16
|
private_constant :USE_MODE_UNSPECIFIED, :USE_MODE_ONE, :USE_MODE_ALL
|
17
17
|
|
18
18
|
attr_writer :logger, :http_extractors, :http_injectors, :text_map_extractors,
|
19
|
-
:text_map_injectors
|
19
|
+
:text_map_injectors, :error_handler, :id_generator
|
20
20
|
|
21
21
|
def initialize
|
22
22
|
@instrumentation_names = []
|
@@ -28,12 +28,17 @@ module OpenTelemetry
|
|
28
28
|
@span_processors = []
|
29
29
|
@use_mode = USE_MODE_UNSPECIFIED
|
30
30
|
@resource = Resources::Resource.telemetry_sdk
|
31
|
+
@id_generator = OpenTelemetry::Trace
|
31
32
|
end
|
32
33
|
|
33
34
|
def logger
|
34
35
|
@logger ||= OpenTelemetry.logger
|
35
36
|
end
|
36
37
|
|
38
|
+
def error_handler
|
39
|
+
@error_handler ||= OpenTelemetry.error_handler
|
40
|
+
end
|
41
|
+
|
37
42
|
# Accepts a resource object that is merged with the default telemetry sdk
|
38
43
|
# resource. The use of this method is optional, and is provided as means
|
39
44
|
# to include additional resource information.
|
@@ -110,9 +115,11 @@ module OpenTelemetry
|
|
110
115
|
# - install instrumentation
|
111
116
|
def configure
|
112
117
|
OpenTelemetry.logger = logger
|
118
|
+
OpenTelemetry.error_handler = error_handler
|
113
119
|
OpenTelemetry.baggage = Baggage::Manager.new
|
114
120
|
configure_propagation
|
115
121
|
configure_span_processors
|
122
|
+
tracer_provider.id_generator = @id_generator
|
116
123
|
OpenTelemetry.tracer_provider = tracer_provider
|
117
124
|
install_instrumentation
|
118
125
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -45,7 +45,17 @@ module OpenTelemetry
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def valid_attributes?(attrs)
|
48
|
-
attrs.nil? || attrs.all?
|
48
|
+
attrs.nil? || attrs.all? do |k, v|
|
49
|
+
if !valid_key?(k)
|
50
|
+
OpenTelemetry.handle_error(message: "invalid attribute key type #{v.class}")
|
51
|
+
false
|
52
|
+
elsif !valid_value?(v)
|
53
|
+
OpenTelemetry.handle_error(message: "invalid attribute value type #{v.class}")
|
54
|
+
false
|
55
|
+
else
|
56
|
+
true
|
57
|
+
end
|
58
|
+
end
|
49
59
|
end
|
50
60
|
end
|
51
61
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -22,7 +22,7 @@ module OpenTelemetry
|
|
22
22
|
def create(attributes = {})
|
23
23
|
frozen_attributes = attributes.each_with_object({}) do |(k, v), memo|
|
24
24
|
raise ArgumentError, 'attribute keys must be strings' unless k.is_a?(String)
|
25
|
-
raise ArgumentError, 'attribute values must be strings, integers, floats, or booleans' unless Internal.valid_value?(v)
|
25
|
+
raise ArgumentError, 'attribute values must be (array of) strings, integers, floats, or booleans' unless Internal.valid_value?(v)
|
26
26
|
|
27
27
|
memo[-k] = v.freeze
|
28
28
|
end.freeze
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -10,20 +10,6 @@ module OpenTelemetry
|
|
10
10
|
module Config
|
11
11
|
# Class that holds global trace parameters.
|
12
12
|
class TraceConfig
|
13
|
-
DEFAULT_SAMPLER = Samplers.parent_based(root: Samplers::ALWAYS_ON)
|
14
|
-
DEFAULT_MAX_ATTRIBUTES_COUNT = 32
|
15
|
-
DEFAULT_MAX_EVENTS_COUNT = 128
|
16
|
-
DEFAULT_MAX_LINKS_COUNT = 32
|
17
|
-
DEFAULT_MAX_ATTRIBUTES_PER_EVENT = 32
|
18
|
-
DEFAULT_MAX_ATTRIBUTES_PER_LINK = 32
|
19
|
-
|
20
|
-
private_constant(:DEFAULT_SAMPLER,
|
21
|
-
:DEFAULT_MAX_ATTRIBUTES_COUNT,
|
22
|
-
:DEFAULT_MAX_EVENTS_COUNT,
|
23
|
-
:DEFAULT_MAX_LINKS_COUNT,
|
24
|
-
:DEFAULT_MAX_ATTRIBUTES_PER_EVENT,
|
25
|
-
:DEFAULT_MAX_ATTRIBUTES_PER_LINK)
|
26
|
-
|
27
13
|
# The global default sampler (see {Samplers}).
|
28
14
|
attr_reader :sampler
|
29
15
|
|
@@ -46,12 +32,12 @@ module OpenTelemetry
|
|
46
32
|
#
|
47
33
|
# @return [TraceConfig] with the desired values.
|
48
34
|
# @raise [ArgumentError] if any of the max numbers are not positive.
|
49
|
-
def initialize(sampler:
|
50
|
-
max_attributes_count:
|
51
|
-
max_events_count:
|
52
|
-
max_links_count:
|
53
|
-
max_attributes_per_event:
|
54
|
-
max_attributes_per_link:
|
35
|
+
def initialize(sampler: sampler_from_environment(Samplers.parent_based(root: Samplers::ALWAYS_ON)),
|
36
|
+
max_attributes_count: Integer(ENV.fetch('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 1000)),
|
37
|
+
max_events_count: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 1000)),
|
38
|
+
max_links_count: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 1000)),
|
39
|
+
max_attributes_per_event: max_attributes_count,
|
40
|
+
max_attributes_per_link: max_attributes_count)
|
55
41
|
raise ArgumentError, 'max_attributes_count must be positive' unless max_attributes_count.positive?
|
56
42
|
raise ArgumentError, 'max_events_count must be positive' unless max_events_count.positive?
|
57
43
|
raise ArgumentError, 'max_links_count must be positive' unless max_links_count.positive?
|
@@ -67,6 +53,22 @@ module OpenTelemetry
|
|
67
53
|
end
|
68
54
|
|
69
55
|
# TODO: from_proto
|
56
|
+
private
|
57
|
+
|
58
|
+
def sampler_from_environment(default_sampler) # rubocop:disable Metrics/CyclomaticComplexity
|
59
|
+
case ENV['OTEL_TRACE_SAMPLER']
|
60
|
+
when 'always_on' then Samplers::ALWAYS_ON
|
61
|
+
when 'always_off' then Samplers::ALWAYS_OFF
|
62
|
+
when 'traceidratio' then Samplers.trace_id_ratio_based(Float(ENV['OTEL_TRACE_SAMPLER_ARG']))
|
63
|
+
when 'parentbased_always_on' then Samplers.parent_based(root: Samplers::ALWAYS_ON)
|
64
|
+
when 'parentbased_always_off' then Samplers.parent_based(root: Samplers::ALWAYS_OFF)
|
65
|
+
when 'parentbased_traceidratio' then Samplers.parent_based(root: Samplers.trace_id_ratio_based(Float(ENV['OTEL_TRACE_SAMPLER_ARG'])))
|
66
|
+
else default_sampler
|
67
|
+
end
|
68
|
+
rescue StandardError => e
|
69
|
+
OpenTelemetry.handle_error(exception: e, message: "installing default sampler #{default_sampler.description}")
|
70
|
+
default_sampler
|
71
|
+
end
|
70
72
|
|
71
73
|
# The default {TraceConfig}.
|
72
74
|
DEFAULT = new
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -30,6 +30,7 @@ end
|
|
30
30
|
require 'opentelemetry/sdk/trace/export/batch_span_processor'
|
31
31
|
require 'opentelemetry/sdk/trace/export/console_span_exporter'
|
32
32
|
require 'opentelemetry/sdk/trace/export/in_memory_span_exporter'
|
33
|
+
require 'opentelemetry/sdk/trace/export/metrics_reporter'
|
33
34
|
require 'opentelemetry/sdk/trace/export/multi_span_exporter'
|
34
35
|
require 'opentelemetry/sdk/trace/export/noop_span_exporter'
|
35
36
|
require 'opentelemetry/sdk/trace/export/simple_span_processor'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
4
|
#
|
5
5
|
# SPDX-License-Identifier: Apache-2.0
|
6
6
|
|
@@ -13,6 +13,9 @@ module OpenTelemetry
|
|
13
13
|
# Implementation of the duck type SpanProcessor that batches spans
|
14
14
|
# exported by the SDK then pushes them to the exporter pipeline.
|
15
15
|
#
|
16
|
+
# Typically, the BatchSpanProcessor will be more suitable for
|
17
|
+
# production environments than the SimpleSpanProcessor.
|
18
|
+
#
|
16
19
|
# All spans reported by the SDK implementation are first added to a
|
17
20
|
# synchronized queue (with a {max_queue_size} maximum size, after the
|
18
21
|
# size is reached spans are dropped) and exported every
|
@@ -22,7 +25,7 @@ module OpenTelemetry
|
|
22
25
|
# If the queue gets half full a preemptive notification is sent to the
|
23
26
|
# worker thread that exports the spans to wake up and start a new
|
24
27
|
# export cycle.
|
25
|
-
class BatchSpanProcessor
|
28
|
+
class BatchSpanProcessor # rubocop:disable Metrics/ClassLength
|
26
29
|
# Returns a new instance of the {BatchSpanProcessor}.
|
27
30
|
#
|
28
31
|
# @param [SpanExporter] exporter
|
@@ -44,42 +47,46 @@ module OpenTelemetry
|
|
44
47
|
exporter_timeout_millis: Float(ENV.fetch('OTEL_BSP_EXPORT_TIMEOUT_MILLIS', 30_000)),
|
45
48
|
schedule_delay_millis: Float(ENV.fetch('OTEL_BSP_SCHEDULE_DELAY_MILLIS', 5_000)),
|
46
49
|
max_queue_size: Integer(ENV.fetch('OTEL_BSP_MAX_QUEUE_SIZE', 2048)),
|
47
|
-
max_export_batch_size: Integer(ENV.fetch('OTEL_BSP_MAX_EXPORT_BATCH_SIZE', 512))
|
50
|
+
max_export_batch_size: Integer(ENV.fetch('OTEL_BSP_MAX_EXPORT_BATCH_SIZE', 512)),
|
51
|
+
start_thread_on_boot: String(ENV['OTEL_RUBY_BSP_START_THREAD_ON_BOOT']) !~ /false/i,
|
52
|
+
metrics_reporter: nil)
|
48
53
|
raise ArgumentError if max_export_batch_size > max_queue_size
|
49
54
|
|
50
55
|
@exporter = exporter
|
51
56
|
@exporter_timeout_seconds = exporter_timeout_millis / 1000.0
|
52
57
|
@mutex = Mutex.new
|
58
|
+
@export_mutex = Mutex.new
|
53
59
|
@condition = ConditionVariable.new
|
54
60
|
@keep_running = true
|
55
61
|
@delay_seconds = schedule_delay_millis / 1000.0
|
56
62
|
@max_queue_size = max_queue_size
|
57
63
|
@batch_size = max_export_batch_size
|
64
|
+
@metrics_reporter = metrics_reporter || OpenTelemetry::SDK::Trace::Export::MetricsReporter
|
58
65
|
@spans = []
|
59
66
|
@pid = nil
|
60
67
|
@thread = nil
|
61
|
-
reset_on_fork
|
68
|
+
reset_on_fork(restart_thread: start_thread_on_boot)
|
62
69
|
end
|
63
70
|
|
64
|
-
#
|
65
|
-
def on_start(
|
66
|
-
# noop
|
67
|
-
end
|
71
|
+
# Does nothing for this processor
|
72
|
+
def on_start(_span, _parent_context); end
|
68
73
|
|
69
|
-
#
|
74
|
+
# Adds a span to the batch. Thread-safe; may block on lock.
|
70
75
|
def on_finish(span) # rubocop:disable Metrics/AbcSize
|
71
76
|
return unless span.context.trace_flags.sampled?
|
72
77
|
|
73
78
|
lock do
|
74
79
|
reset_on_fork
|
75
80
|
n = spans.size + 1 - max_queue_size
|
76
|
-
|
81
|
+
if n.positive?
|
82
|
+
spans.shift(n)
|
83
|
+
report_dropped_spans(n, reason: 'buffer-full')
|
84
|
+
end
|
77
85
|
spans << span
|
78
|
-
@condition.signal if spans.size >
|
86
|
+
@condition.signal if spans.size > batch_size
|
79
87
|
end
|
80
88
|
end
|
81
89
|
|
82
|
-
# TODO: test this explicitly.
|
83
90
|
# Export all ended spans to the configured `Exporter` that have not yet
|
84
91
|
# been exported.
|
85
92
|
#
|
@@ -88,42 +95,64 @@ module OpenTelemetry
|
|
88
95
|
# the process after an invocation, but before the `Processor` exports
|
89
96
|
# the completed spans.
|
90
97
|
#
|
98
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
91
99
|
# @return [Integer] SUCCESS if no error occurred, FAILURE if a
|
92
100
|
# non-specific failure occurred, TIMEOUT if a timeout occurred.
|
93
|
-
def force_flush
|
101
|
+
def force_flush(timeout: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
102
|
+
start_time = Time.now
|
94
103
|
snapshot = lock do
|
95
104
|
reset_on_fork(restart_thread: false) if @keep_running
|
96
105
|
spans.shift(spans.size)
|
97
106
|
end
|
98
107
|
until snapshot.empty?
|
108
|
+
remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
|
109
|
+
return TIMEOUT if remaining_timeout&.zero?
|
110
|
+
|
99
111
|
batch = snapshot.shift(@batch_size).map!(&:to_span_data)
|
100
|
-
result_code =
|
101
|
-
|
112
|
+
result_code = export_batch(batch, timeout: remaining_timeout)
|
113
|
+
return result_code unless result_code == SUCCESS
|
102
114
|
end
|
115
|
+
|
103
116
|
SUCCESS
|
117
|
+
ensure
|
118
|
+
# Unshift the remaining spans if we timed out. We drop excess spans from
|
119
|
+
# the snapshot because they're older than any spans in the spans buffer.
|
120
|
+
lock do
|
121
|
+
n = spans.size + snapshot.size - max_queue_size
|
122
|
+
if n.positive?
|
123
|
+
snapshot.shift(n)
|
124
|
+
report_dropped_spans(n, reason: 'buffer-full')
|
125
|
+
end
|
126
|
+
spans.unshift(snapshot) unless snapshot.empty?
|
127
|
+
@condition.signal if spans.size > max_queue_size / 2
|
128
|
+
end
|
104
129
|
end
|
105
130
|
|
106
|
-
#
|
107
|
-
# will block until the thread is finished
|
131
|
+
# Shuts the consumer thread down and flushes the current accumulated buffer
|
132
|
+
# will block until the thread is finished.
|
108
133
|
#
|
134
|
+
# @param [optional Numeric] timeout An optional timeout in seconds.
|
109
135
|
# @return [Integer] SUCCESS if no error occurred, FAILURE if a
|
110
136
|
# non-specific failure occurred, TIMEOUT if a timeout occurred.
|
111
|
-
def shutdown
|
137
|
+
def shutdown(timeout: nil)
|
138
|
+
start_time = Time.now
|
112
139
|
lock do
|
113
140
|
@keep_running = false
|
114
141
|
@condition.signal
|
115
142
|
end
|
116
143
|
|
117
|
-
@thread.join
|
118
|
-
force_flush
|
119
|
-
@exporter.shutdown
|
144
|
+
@thread.join(timeout)
|
145
|
+
force_flush(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
146
|
+
@exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
147
|
+
dropped_spans = lock { spans.size }
|
148
|
+
report_dropped_spans(dropped_spans, reason: 'terminating') if dropped_spans.positive?
|
120
149
|
end
|
121
150
|
|
122
151
|
private
|
123
152
|
|
124
153
|
attr_reader :spans, :max_queue_size, :batch_size
|
125
154
|
|
126
|
-
def work
|
155
|
+
def work # rubocop:disable Metrics/AbcSize
|
127
156
|
loop do
|
128
157
|
batch = lock do
|
129
158
|
reset_on_fork(restart_thread: false)
|
@@ -134,6 +163,8 @@ module OpenTelemetry
|
|
134
163
|
fetch_batch
|
135
164
|
end
|
136
165
|
|
166
|
+
@metrics_reporter.observe_value('otel.bsp.buffer_utilization', value: spans.size / max_queue_size.to_f)
|
167
|
+
|
137
168
|
export_batch(batch)
|
138
169
|
end
|
139
170
|
end
|
@@ -147,19 +178,25 @@ module OpenTelemetry
|
|
147
178
|
@thread = Thread.new { work } if restart_thread
|
148
179
|
end
|
149
180
|
|
150
|
-
def export_batch(batch)
|
151
|
-
result_code =
|
181
|
+
def export_batch(batch, timeout: @exporter_timeout_seconds)
|
182
|
+
result_code = @export_mutex.synchronize { @exporter.export(batch, timeout: timeout) }
|
152
183
|
report_result(result_code, batch)
|
184
|
+
result_code
|
153
185
|
end
|
154
186
|
|
155
|
-
def
|
156
|
-
|
157
|
-
|
158
|
-
|
187
|
+
def report_result(result_code, batch)
|
188
|
+
if result_code == SUCCESS
|
189
|
+
@metrics_reporter.add_to_counter('otel.bsp.export.success')
|
190
|
+
@metrics_reporter.add_to_counter('otel.bsp.exported_spans', increment: batch.size)
|
191
|
+
else
|
192
|
+
OpenTelemetry.handle_error(message: "Unable to export #{batch.size} spans")
|
193
|
+
@metrics_reporter.add_to_counter('otel.bsp.export.failure')
|
194
|
+
report_dropped_spans(batch.size, reason: 'export-failure')
|
195
|
+
end
|
159
196
|
end
|
160
197
|
|
161
|
-
def
|
162
|
-
|
198
|
+
def report_dropped_spans(count, reason:)
|
199
|
+
@metrics_reporter.add_to_counter('otel.bsp.dropped_spans', increment: count, labels: { 'reason' => reason })
|
163
200
|
end
|
164
201
|
|
165
202
|
def fetch_batch
|