opentelemetry-sdk 0.11.0 → 0.13.1
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 +32 -0
- data/README.md +2 -2
- data/lib/opentelemetry/sdk.rb +11 -0
- data/lib/opentelemetry/sdk/configurator.rb +14 -7
- data/lib/opentelemetry/sdk/internal.rb +11 -1
- data/lib/opentelemetry/sdk/resources/constants.rb +40 -0
- data/lib/opentelemetry/sdk/resources/resource.rb +18 -6
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +22 -20
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +24 -20
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +1 -1
- data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +8 -0
- data/lib/opentelemetry/sdk/trace/samplers/parent_based.rb +12 -0
- data/lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb +4 -0
- data/lib/opentelemetry/sdk/trace/span.rb +22 -12
- data/lib/opentelemetry/sdk/trace/tracer.rb +5 -4
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +2 -1
- data/lib/opentelemetry/sdk/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a416d898ec2b20cc5feb768d96b7a475948ec0af1b806a67ccd600c30be45bf2
|
|
4
|
+
data.tar.gz: e878674694f2889a350e2fec5e98c8189d3949a5060a6fdd96d81da8ff3a9090
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41ad50a204ce134e73559ea98fdca585aa0bce6f8c2746eb3bfdef81b49d7e56b07a2844872949351f25026af3c1143142ae96552ac1e05e08c03429e2a6fe76
|
|
7
|
+
data.tar.gz: a42fb2fcdbe87588b4694fefd95ab314c5f63eeade37e42ead3933f858590c85ac9db7b0baa62d4f290f23aefb12c6dfaf5c4f4810500e8903b6e1cbc95485e9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Release History: opentelemetry-sdk
|
|
2
2
|
|
|
3
|
+
### v0.13.1 / 2021-02-01
|
|
4
|
+
|
|
5
|
+
* FIXED: Leaky test
|
|
6
|
+
* FIXED: Allow env var override of service.name
|
|
7
|
+
|
|
8
|
+
### v0.13.0 / 2021-01-29
|
|
9
|
+
|
|
10
|
+
* BREAKING CHANGE: Remove MILLIS from BatchSpanProcessor vars
|
|
11
|
+
|
|
12
|
+
* ADDED: Process.runtime resource
|
|
13
|
+
* ADDED: Provide default resource in SDK
|
|
14
|
+
* ADDED: Add optional attributes to record_exception
|
|
15
|
+
* FIXED: Resource.merge consistency
|
|
16
|
+
* FIXED: Remove MILLIS from BatchSpanProcessor vars
|
|
17
|
+
|
|
18
|
+
### v0.12.1 / 2021-01-13
|
|
19
|
+
|
|
20
|
+
* FIXED: Fix several BatchSpanProcessor errors related to fork safety
|
|
21
|
+
* FIXED: Define default value for traceid ratio
|
|
22
|
+
|
|
23
|
+
### v0.12.0 / 2020-12-24
|
|
24
|
+
|
|
25
|
+
* ADDED: Structured error handling
|
|
26
|
+
* ADDED: Pluggable ID generation
|
|
27
|
+
* FIXED: BSP dropped span buffer full reporting
|
|
28
|
+
* FIXED: Implement SDK environment variables
|
|
29
|
+
* FIXED: Remove incorrect TODO
|
|
30
|
+
|
|
31
|
+
### v0.11.1 / 2020-12-16
|
|
32
|
+
|
|
33
|
+
* FIXED: BSP dropped span buffer full reporting
|
|
34
|
+
|
|
3
35
|
### v0.11.0 / 2020-12-11
|
|
4
36
|
|
|
5
37
|
* ADDED: Metrics reporting from trace export
|
data/README.md
CHANGED
|
@@ -66,8 +66,8 @@ The `opentelemetry-sdk` gem is distributed under the Apache 2.0 license. See [LI
|
|
|
66
66
|
[opentelemetry-home]: https://opentelemetry.io
|
|
67
67
|
[bundler-home]: https://bundler.io
|
|
68
68
|
[repo-github]: https://github.com/open-telemetry/opentelemetry-ruby
|
|
69
|
-
[license-github]: https://github.com/open-telemetry/opentelemetry-ruby/blob/
|
|
70
|
-
[examples-github]: https://github.com/open-telemetry/opentelemetry-ruby/tree/
|
|
69
|
+
[license-github]: https://github.com/open-telemetry/opentelemetry-ruby/blob/main/LICENSE
|
|
70
|
+
[examples-github]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/examples
|
|
71
71
|
[ruby-sig]: https://github.com/open-telemetry/community#ruby-sig
|
|
72
72
|
[community-meetings]: https://github.com/open-telemetry/community#community-meetings
|
|
73
73
|
[ruby-gitter]: https://gitter.im/open-telemetry/opentelemetry-ruby
|
data/lib/opentelemetry/sdk.rb
CHANGED
|
@@ -18,6 +18,11 @@ module OpenTelemetry
|
|
|
18
18
|
module SDK
|
|
19
19
|
extend self
|
|
20
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
|
+
|
|
21
26
|
# Configures SDK and instrumentation
|
|
22
27
|
#
|
|
23
28
|
# @yieldparam [Configurator] configurator Yields a configurator to the
|
|
@@ -57,6 +62,12 @@ module OpenTelemetry
|
|
|
57
62
|
configurator = Configurator.new
|
|
58
63
|
yield configurator if block_given?
|
|
59
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
|
|
60
71
|
end
|
|
61
72
|
end
|
|
62
73
|
end
|
|
@@ -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 = []
|
|
@@ -27,13 +27,18 @@ module OpenTelemetry
|
|
|
27
27
|
@text_map_injectors = nil
|
|
28
28
|
@span_processors = []
|
|
29
29
|
@use_mode = USE_MODE_UNSPECIFIED
|
|
30
|
-
@resource = Resources::Resource.
|
|
30
|
+
@resource = Resources::Resource.default
|
|
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.
|
|
@@ -41,7 +46,7 @@ module OpenTelemetry
|
|
|
41
46
|
#
|
|
42
47
|
# @param [Resource] new_resource The resource to be merged
|
|
43
48
|
def resource=(new_resource)
|
|
44
|
-
@resource =
|
|
49
|
+
@resource = @resource.merge(new_resource)
|
|
45
50
|
end
|
|
46
51
|
|
|
47
52
|
# Accepts a string that is merged in as the service.name resource attribute.
|
|
@@ -49,9 +54,9 @@ module OpenTelemetry
|
|
|
49
54
|
# calls to this setter.
|
|
50
55
|
# @param [String] service_name The value to be used as the service name
|
|
51
56
|
def service_name=(service_name)
|
|
52
|
-
|
|
57
|
+
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
|
|
53
58
|
OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:name] => service_name
|
|
54
|
-
)
|
|
59
|
+
)
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
# Accepts a string that is merged in as the service.version resource attribute.
|
|
@@ -59,9 +64,9 @@ module OpenTelemetry
|
|
|
59
64
|
# calls to this setter.
|
|
60
65
|
# @param [String] service_version The value to be used as the service version
|
|
61
66
|
def service_version=(service_version)
|
|
62
|
-
|
|
67
|
+
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
|
|
63
68
|
OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:version] => service_version
|
|
64
|
-
)
|
|
69
|
+
)
|
|
65
70
|
end
|
|
66
71
|
|
|
67
72
|
# Install an instrumentation with specificied optional +config+.
|
|
@@ -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
|
|
@@ -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
|
|
@@ -77,6 +77,46 @@ module OpenTelemetry
|
|
|
77
77
|
deployment_name: 'k8s.deployment.name'
|
|
78
78
|
}.freeze
|
|
79
79
|
|
|
80
|
+
# Attributes defining an operating system process.
|
|
81
|
+
PROCESS_RESOURCE = {
|
|
82
|
+
# Process identifier (PID).
|
|
83
|
+
pid: 'process.pid',
|
|
84
|
+
|
|
85
|
+
# The name of the process executable.
|
|
86
|
+
executable_name: 'process.executable.name',
|
|
87
|
+
|
|
88
|
+
# The full path to the process executable.
|
|
89
|
+
executable_path: 'process.executable.path',
|
|
90
|
+
|
|
91
|
+
# The command used to launch the process (i.e. the command name).
|
|
92
|
+
command: 'process.command',
|
|
93
|
+
|
|
94
|
+
# The full command used to launch the process as a single string
|
|
95
|
+
# representing the full command.
|
|
96
|
+
command_line: 'process.command_line',
|
|
97
|
+
|
|
98
|
+
# All the command arguments (including the command/executable itself)
|
|
99
|
+
# as received by the process.
|
|
100
|
+
command_args: 'process.command_args',
|
|
101
|
+
|
|
102
|
+
# The username of the user that owns the process.
|
|
103
|
+
owner: 'process.owner'
|
|
104
|
+
}.freeze
|
|
105
|
+
|
|
106
|
+
# Attributes defining the single (language) runtime instance which is monitored.
|
|
107
|
+
PROCESS_RUNTIME_RESOURCE = {
|
|
108
|
+
# The name of the runtime of this process.
|
|
109
|
+
name: 'process.runtime.name',
|
|
110
|
+
|
|
111
|
+
# The version of the runtime of this process, as returned by the runtime
|
|
112
|
+
# without modification.
|
|
113
|
+
version: 'process.runtime.version',
|
|
114
|
+
|
|
115
|
+
# An additional description about the runtime of the process, for example
|
|
116
|
+
# a specific vendor customization of the runtime environment.
|
|
117
|
+
description: 'process.runtime.description'
|
|
118
|
+
}.freeze
|
|
119
|
+
|
|
80
120
|
# Attributes defining a computing instance (e.g. host).
|
|
81
121
|
HOST_RESOURCE = {
|
|
82
122
|
# Unique host id. For Cloud this must be the instance_id assigned by the
|
|
@@ -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
|
|
@@ -30,6 +30,10 @@ module OpenTelemetry
|
|
|
30
30
|
new(frozen_attributes)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def default
|
|
34
|
+
@default ||= create(Constants::SERVICE_RESOURCE[:name] => 'unknown_service').merge(process).merge(telemetry_sdk)
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
def telemetry_sdk
|
|
34
38
|
resource_attributes = {
|
|
35
39
|
Constants::TELEMETRY_SDK_RESOURCE[:name] => 'opentelemetry',
|
|
@@ -48,6 +52,18 @@ module OpenTelemetry
|
|
|
48
52
|
resource_attributes.delete_if { |_key, value| value.nil? || value.empty? }
|
|
49
53
|
create(resource_attributes)
|
|
50
54
|
end
|
|
55
|
+
|
|
56
|
+
def process
|
|
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
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
create(resource_attributes)
|
|
66
|
+
end
|
|
51
67
|
end
|
|
52
68
|
|
|
53
69
|
# @api private
|
|
@@ -79,11 +95,7 @@ module OpenTelemetry
|
|
|
79
95
|
def merge(other)
|
|
80
96
|
return self unless other.is_a?(Resource)
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
old_v.empty? ? new_v : old_v
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
self.class.send(:new, merged_attributes.freeze)
|
|
98
|
+
self.class.send(:new, attributes.merge(other.attributes).freeze)
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
protected
|
|
@@ -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.fetch('OTEL_TRACE_SAMPLER_ARG', 1.0)))
|
|
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.fetch('OTEL_TRACE_SAMPLER_ARG', 1.0))))
|
|
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
|
|
@@ -19,7 +19,7 @@ module OpenTelemetry
|
|
|
19
19
|
# All spans reported by the SDK implementation are first added to a
|
|
20
20
|
# synchronized queue (with a {max_queue_size} maximum size, after the
|
|
21
21
|
# size is reached spans are dropped) and exported every
|
|
22
|
-
#
|
|
22
|
+
# schedule_delay to the exporter pipeline in batches of
|
|
23
23
|
# max_export_batch_size.
|
|
24
24
|
#
|
|
25
25
|
# If the queue gets half full a preemptive notification is sent to the
|
|
@@ -29,11 +29,11 @@ module OpenTelemetry
|
|
|
29
29
|
# Returns a new instance of the {BatchSpanProcessor}.
|
|
30
30
|
#
|
|
31
31
|
# @param [SpanExporter] exporter
|
|
32
|
-
# @param [Numeric]
|
|
33
|
-
# consecutive exports. Defaults to the value of the
|
|
32
|
+
# @param [Numeric] exporter_timeout the delay interval between two
|
|
33
|
+
# consecutive exports. Defaults to the value of the OTEL_BSP_EXPORT_TIMEOUT
|
|
34
34
|
# environment variable, if set, or 30,000 (30 seconds).
|
|
35
|
-
# @param [Numeric]
|
|
36
|
-
# Defaults to the value of the
|
|
35
|
+
# @param [Numeric] schedule_delay the maximum allowed time to export data.
|
|
36
|
+
# Defaults to the value of the OTEL_BSP_SCHEDULE_DELAY environment
|
|
37
37
|
# variable, if set, or 5,000 (5 seconds).
|
|
38
38
|
# @param [Integer] max_queue_size the maximum queue size in spans.
|
|
39
39
|
# Defaults to the value of the OTEL_BSP_MAX_QUEUE_SIZE environment
|
|
@@ -44,8 +44,8 @@ module OpenTelemetry
|
|
|
44
44
|
#
|
|
45
45
|
# @return a new instance of the {BatchSpanProcessor}.
|
|
46
46
|
def initialize(exporter:,
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
exporter_timeout: Float(ENV.fetch('OTEL_BSP_EXPORT_TIMEOUT', 30_000)),
|
|
48
|
+
schedule_delay: Float(ENV.fetch('OTEL_BSP_SCHEDULE_DELAY', 5_000)),
|
|
49
49
|
max_queue_size: Integer(ENV.fetch('OTEL_BSP_MAX_QUEUE_SIZE', 2048)),
|
|
50
50
|
max_export_batch_size: Integer(ENV.fetch('OTEL_BSP_MAX_EXPORT_BATCH_SIZE', 512)),
|
|
51
51
|
start_thread_on_boot: String(ENV['OTEL_RUBY_BSP_START_THREAD_ON_BOOT']) !~ /false/i,
|
|
@@ -53,12 +53,12 @@ module OpenTelemetry
|
|
|
53
53
|
raise ArgumentError if max_export_batch_size > max_queue_size
|
|
54
54
|
|
|
55
55
|
@exporter = exporter
|
|
56
|
-
@exporter_timeout_seconds =
|
|
56
|
+
@exporter_timeout_seconds = exporter_timeout / 1000.0
|
|
57
57
|
@mutex = Mutex.new
|
|
58
58
|
@export_mutex = Mutex.new
|
|
59
59
|
@condition = ConditionVariable.new
|
|
60
60
|
@keep_running = true
|
|
61
|
-
@delay_seconds =
|
|
61
|
+
@delay_seconds = schedule_delay / 1000.0
|
|
62
62
|
@max_queue_size = max_queue_size
|
|
63
63
|
@batch_size = max_export_batch_size
|
|
64
64
|
@metrics_reporter = metrics_reporter || OpenTelemetry::SDK::Trace::Export::MetricsReporter
|
|
@@ -78,8 +78,10 @@ module OpenTelemetry
|
|
|
78
78
|
lock do
|
|
79
79
|
reset_on_fork
|
|
80
80
|
n = spans.size + 1 - max_queue_size
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if n.positive?
|
|
82
|
+
spans.shift(n)
|
|
83
|
+
report_dropped_spans(n, reason: 'buffer-full')
|
|
84
|
+
end
|
|
83
85
|
spans << span
|
|
84
86
|
@condition.signal if spans.size > batch_size
|
|
85
87
|
end
|
|
@@ -96,10 +98,10 @@ module OpenTelemetry
|
|
|
96
98
|
# @param [optional Numeric] timeout An optional timeout in seconds.
|
|
97
99
|
# @return [Integer] SUCCESS if no error occurred, FAILURE if a
|
|
98
100
|
# non-specific failure occurred, TIMEOUT if a timeout occurred.
|
|
99
|
-
def force_flush(timeout: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
101
|
+
def force_flush(timeout: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
|
100
102
|
start_time = Time.now
|
|
101
103
|
snapshot = lock do
|
|
102
|
-
reset_on_fork
|
|
104
|
+
reset_on_fork if @keep_running
|
|
103
105
|
spans.shift(spans.size)
|
|
104
106
|
end
|
|
105
107
|
until snapshot.empty?
|
|
@@ -117,8 +119,10 @@ module OpenTelemetry
|
|
|
117
119
|
# the snapshot because they're older than any spans in the spans buffer.
|
|
118
120
|
lock do
|
|
119
121
|
n = spans.size + snapshot.size - max_queue_size
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
if n.positive?
|
|
123
|
+
snapshot.shift(n)
|
|
124
|
+
report_dropped_spans(n, reason: 'buffer-full')
|
|
125
|
+
end
|
|
122
126
|
spans.unshift(snapshot) unless snapshot.empty?
|
|
123
127
|
@condition.signal if spans.size > max_queue_size / 2
|
|
124
128
|
end
|
|
@@ -132,12 +136,13 @@ module OpenTelemetry
|
|
|
132
136
|
# non-specific failure occurred, TIMEOUT if a timeout occurred.
|
|
133
137
|
def shutdown(timeout: nil)
|
|
134
138
|
start_time = Time.now
|
|
135
|
-
lock do
|
|
139
|
+
thread = lock do
|
|
136
140
|
@keep_running = false
|
|
137
141
|
@condition.signal
|
|
142
|
+
@thread
|
|
138
143
|
end
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
thread&.join(timeout)
|
|
141
146
|
force_flush(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
|
142
147
|
@exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
|
143
148
|
dropped_spans = lock { spans.size }
|
|
@@ -151,7 +156,6 @@ module OpenTelemetry
|
|
|
151
156
|
def work # rubocop:disable Metrics/AbcSize
|
|
152
157
|
loop do
|
|
153
158
|
batch = lock do
|
|
154
|
-
reset_on_fork(restart_thread: false)
|
|
155
159
|
@condition.wait(@mutex, @delay_seconds) if spans.size < batch_size && @keep_running
|
|
156
160
|
@condition.wait(@mutex, @delay_seconds) while spans.empty? && @keep_running
|
|
157
161
|
return unless @keep_running
|
|
@@ -171,7 +175,7 @@ module OpenTelemetry
|
|
|
171
175
|
|
|
172
176
|
@pid = pid
|
|
173
177
|
spans.clear
|
|
174
|
-
@thread = Thread.new { work }
|
|
178
|
+
@thread = restart_thread ? Thread.new { work } : nil
|
|
175
179
|
end
|
|
176
180
|
|
|
177
181
|
def export_batch(batch, timeout: @exporter_timeout_seconds)
|
|
@@ -185,7 +189,7 @@ module OpenTelemetry
|
|
|
185
189
|
@metrics_reporter.add_to_counter('otel.bsp.export.success')
|
|
186
190
|
@metrics_reporter.add_to_counter('otel.bsp.exported_spans', increment: batch.size)
|
|
187
191
|
else
|
|
188
|
-
OpenTelemetry.
|
|
192
|
+
OpenTelemetry.handle_error(message: "Unable to export #{batch.size} spans")
|
|
189
193
|
@metrics_reporter.add_to_counter('otel.bsp.export.failure')
|
|
190
194
|
report_dropped_spans(batch.size, reason: 'export-failure')
|
|
191
195
|
end
|
|
@@ -57,7 +57,7 @@ module OpenTelemetry
|
|
|
57
57
|
|
|
58
58
|
@span_exporter&.export([span.to_span_data])
|
|
59
59
|
rescue => e # rubocop:disable Style/RescueStandardError
|
|
60
|
-
OpenTelemetry.
|
|
60
|
+
OpenTelemetry.handle_error(exception: e, message: 'unexpected error in span.on_finish')
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# Export all ended spans to the configured `Exporter` that have not yet
|
|
@@ -19,12 +19,20 @@ module OpenTelemetry
|
|
|
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
30
|
Result.new(decision: @decision, tracestate: OpenTelemetry::Trace.current_span(parent_context).context.tracestate)
|
|
27
31
|
end
|
|
32
|
+
|
|
33
|
+
protected
|
|
34
|
+
|
|
35
|
+
attr_reader :decision
|
|
28
36
|
end
|
|
29
37
|
end
|
|
30
38
|
end
|
|
@@ -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}.
|
|
@@ -47,6 +55,10 @@ module OpenTelemetry
|
|
|
47
55
|
end
|
|
48
56
|
delegate.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
|
|
49
57
|
end
|
|
58
|
+
|
|
59
|
+
protected
|
|
60
|
+
|
|
61
|
+
attr_reader :root, :remote_parent_sampled, :remote_parent_not_sampled, :local_parent_sampled, :local_parent_not_sampled
|
|
50
62
|
end
|
|
51
63
|
end
|
|
52
64
|
end
|
|
@@ -120,15 +120,20 @@ module OpenTelemetry
|
|
|
120
120
|
# can be recorded on a span.
|
|
121
121
|
#
|
|
122
122
|
# @param [Exception] exception The exception to be recorded
|
|
123
|
+
# @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
|
|
124
|
+
# attributes One or more key:value pairs, where the keys must be
|
|
125
|
+
# strings and the values may be (array of) string, boolean or numeric
|
|
126
|
+
# type.
|
|
123
127
|
#
|
|
124
128
|
# @return [void]
|
|
125
|
-
def record_exception(exception)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
def record_exception(exception, attributes: nil)
|
|
130
|
+
event_attributes = {
|
|
131
|
+
'exception.type' => exception.class.to_s,
|
|
132
|
+
'exception.message' => exception.message,
|
|
133
|
+
'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
|
|
134
|
+
}
|
|
135
|
+
event_attributes.merge!(attributes) unless attributes.nil?
|
|
136
|
+
add_event('exception', attributes: event_attributes)
|
|
132
137
|
end
|
|
133
138
|
|
|
134
139
|
# Sets the Status to the Span
|
|
@@ -199,7 +204,7 @@ module OpenTelemetry
|
|
|
199
204
|
return self
|
|
200
205
|
end
|
|
201
206
|
@end_timestamp = end_timestamp || Time.now
|
|
202
|
-
@attributes.freeze
|
|
207
|
+
@attributes = validated_attributes(@attributes).freeze
|
|
203
208
|
@events.freeze
|
|
204
209
|
@ended = true
|
|
205
210
|
end
|
|
@@ -269,12 +274,16 @@ module OpenTelemetry
|
|
|
269
274
|
|
|
270
275
|
private
|
|
271
276
|
|
|
277
|
+
def validated_attributes(attrs)
|
|
278
|
+
return attrs if Internal.valid_attributes?(attrs)
|
|
279
|
+
|
|
280
|
+
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
|
281
|
+
end
|
|
282
|
+
|
|
272
283
|
def trim_span_attributes(attrs)
|
|
273
284
|
return if attrs.nil?
|
|
274
285
|
|
|
275
286
|
excess = attrs.size - @trace_config.max_attributes_count
|
|
276
|
-
# TODO: with Ruby 2.5, replace with the more efficient
|
|
277
|
-
# attrs.shift(excess) if excess.positive?
|
|
278
287
|
excess.times { attrs.shift } if excess.positive?
|
|
279
288
|
nil
|
|
280
289
|
end
|
|
@@ -301,11 +310,12 @@ module OpenTelemetry
|
|
|
301
310
|
def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
302
311
|
max_events_count = @trace_config.max_events_count
|
|
303
312
|
max_attributes_per_event = @trace_config.max_attributes_per_event
|
|
313
|
+
valid_attributes = Internal.valid_attributes?(event.attributes)
|
|
304
314
|
|
|
305
315
|
# Fast path (likely) common case.
|
|
306
316
|
if events.size < max_events_count &&
|
|
307
317
|
event.attributes.size <= max_attributes_per_event &&
|
|
308
|
-
|
|
318
|
+
valid_attributes
|
|
309
319
|
return events << event
|
|
310
320
|
end
|
|
311
321
|
|
|
@@ -314,7 +324,7 @@ module OpenTelemetry
|
|
|
314
324
|
events.shift(excess) if excess.positive?
|
|
315
325
|
|
|
316
326
|
excess = event.attributes.size - max_attributes_per_event
|
|
317
|
-
if excess.positive? || !
|
|
327
|
+
if excess.positive? || !valid_attributes
|
|
318
328
|
attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
|
|
319
329
|
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
|
320
330
|
excess = attrs.size - max_attributes_per_event
|
|
@@ -42,7 +42,7 @@ module OpenTelemetry
|
|
|
42
42
|
parent_span_id = parent_span_context.span_id
|
|
43
43
|
trace_id = parent_span_context.trace_id
|
|
44
44
|
end
|
|
45
|
-
trace_id ||=
|
|
45
|
+
trace_id ||= tracer_provider.id_generator.generate_trace_id
|
|
46
46
|
sampler = tracer_provider.active_trace_config.sampler
|
|
47
47
|
result = sampler.should_sample?(trace_id: trace_id, parent_context: with_parent, links: links, name: name, kind: kind, attributes: attributes)
|
|
48
48
|
internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent)
|
|
@@ -50,10 +50,11 @@ module OpenTelemetry
|
|
|
50
50
|
|
|
51
51
|
private
|
|
52
52
|
|
|
53
|
-
def internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context) # rubocop:disable Metrics/AbcSize
|
|
53
|
+
def internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
54
|
+
span_id = tracer_provider.id_generator.generate_span_id
|
|
54
55
|
if result.recording? && !tracer_provider.stopped?
|
|
55
56
|
trace_flags = result.sampled? ? OpenTelemetry::Trace::TraceFlags::SAMPLED : OpenTelemetry::Trace::TraceFlags::DEFAULT
|
|
56
|
-
context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, trace_flags: trace_flags, tracestate: result.tracestate)
|
|
57
|
+
context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, trace_flags: trace_flags, tracestate: result.tracestate)
|
|
57
58
|
attributes = attributes&.merge(result.attributes) || result.attributes
|
|
58
59
|
Span.new(
|
|
59
60
|
context,
|
|
@@ -70,7 +71,7 @@ module OpenTelemetry
|
|
|
70
71
|
@instrumentation_library
|
|
71
72
|
)
|
|
72
73
|
else
|
|
73
|
-
OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id))
|
|
74
|
+
OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, tracestate: result.tracestate))
|
|
74
75
|
end
|
|
75
76
|
end
|
|
76
77
|
end
|
|
@@ -12,7 +12,7 @@ module OpenTelemetry
|
|
|
12
12
|
Key = Struct.new(:name, :version)
|
|
13
13
|
private_constant(:Key)
|
|
14
14
|
|
|
15
|
-
attr_accessor :active_trace_config
|
|
15
|
+
attr_accessor :active_trace_config, :id_generator
|
|
16
16
|
attr_reader :active_span_processor, :stopped, :resource
|
|
17
17
|
alias stopped? stopped
|
|
18
18
|
|
|
@@ -24,6 +24,7 @@ module OpenTelemetry
|
|
|
24
24
|
@registry = {}
|
|
25
25
|
@active_span_processor = NoopSpanProcessor.instance
|
|
26
26
|
@active_trace_config = Config::TraceConfig::DEFAULT
|
|
27
|
+
@id_generator = OpenTelemetry::Trace
|
|
27
28
|
@registered_span_processors = []
|
|
28
29
|
@stopped = false
|
|
29
30
|
@resource = resource
|
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: 0.
|
|
4
|
+
version: 0.13.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenTelemetry Authors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-02-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: opentelemetry-api
|
|
@@ -16,28 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
19
|
+
version: 0.13.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: 0.
|
|
26
|
+
version: 0.13.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.
|
|
33
|
+
version: 0.13.0
|
|
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.
|
|
40
|
+
version: 0.13.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: bundler
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -201,10 +201,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
|
|
|
201
201
|
licenses:
|
|
202
202
|
- Apache-2.0
|
|
203
203
|
metadata:
|
|
204
|
-
changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.
|
|
205
|
-
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/
|
|
204
|
+
changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.13.1/file.CHANGELOG.html
|
|
205
|
+
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/sdk
|
|
206
206
|
bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
|
|
207
|
-
documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.
|
|
207
|
+
documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.13.1
|
|
208
208
|
post_install_message:
|
|
209
209
|
rdoc_options: []
|
|
210
210
|
require_paths:
|