opentelemetry-sdk 0.8.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|