opentelemetry-sdk 1.0.0.rc1 → 1.0.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 +56 -0
- data/README.md +25 -2
- data/lib/opentelemetry/sdk/configurator.rb +44 -18
- data/lib/opentelemetry/sdk/forwarding_logger.rb +69 -0
- data/lib/opentelemetry/sdk/resources/resource.rb +16 -9
- data/lib/opentelemetry/sdk/resources.rb +0 -1
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +6 -2
- data/lib/opentelemetry/sdk/trace/export/{noop_span_exporter.rb → span_exporter.rb} +8 -7
- data/lib/opentelemetry/sdk/trace/export.rb +3 -2
- data/lib/opentelemetry/sdk/trace/span.rb +35 -29
- data/lib/opentelemetry/sdk/trace/span_limits.rb +60 -0
- data/lib/opentelemetry/sdk/trace/{noop_span_processor.rb → span_processor.rb} +5 -8
- data/lib/opentelemetry/sdk/trace/tracer.rb +1 -37
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +89 -19
- data/lib/opentelemetry/sdk/trace.rb +2 -3
- data/lib/opentelemetry/sdk/version.rb +1 -1
- data/lib/opentelemetry/sdk.rb +3 -1
- metadata +61 -22
- data/lib/opentelemetry/sdk/resources/constants.rb +0 -205
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +0 -85
- data/lib/opentelemetry/sdk/trace/config.rb +0 -18
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +0 -76
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b0251902390864d89d8f00496f9ae36adcf3a52d1a84c574a73a107ccea70f0
|
4
|
+
data.tar.gz: ed15513dcd3d4decc53a0923db83c8e10d9b65a86247775c05d354212c1439c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3954c44377c4250f6dd2dcba2f88a781aa34acec642f19996014014c9d49ce3733846956043f09ce548ceee0362befa9ff9af660f894c39a446bdca5e0d7fb3
|
7
|
+
data.tar.gz: f8ddde936a93b87682a2f85a0d3a800ed0de25643bce04e420d01c8565c2ed33548dda6174c213d868aab82fe5398868144051690601d2b49015ea48bd999b9f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,61 @@
|
|
1
1
|
# Release History: opentelemetry-sdk
|
2
2
|
|
3
|
+
### v1.0.1 / 2021-10-29
|
4
|
+
|
5
|
+
* FIXED: Add unexpected error handlign in BSP and OTLP exporter (#995)
|
6
|
+
|
7
|
+
### v1.0.0 / 2021-09-29
|
8
|
+
|
9
|
+
* (No significant changes)
|
10
|
+
|
11
|
+
### v1.0.0.rc3 / 2021-08-12
|
12
|
+
|
13
|
+
* BREAKING CHANGE: Remove optional parent_context from in_span
|
14
|
+
* BREAKING CHANGE: Replace Time.now with Process.clock_gettime
|
15
|
+
* BREAKING CHANGE: Refactor Baggage to remove Noop*
|
16
|
+
* BREAKING CHANGE: Remove unnecessary readers from SDK Tracer
|
17
|
+
* BREAKING CHANGE: Total order constraint on span.status=
|
18
|
+
* BREAKING CHANGE: Use auto-generated resource constants in sdk and resource_detectors
|
19
|
+
* BREAKING CHANGE: Span limits env vars
|
20
|
+
|
21
|
+
* ADDED: Add Tracer.non_recording_span to API
|
22
|
+
* ADDED: Add unnamed tracer warning message
|
23
|
+
* ADDED: Allow disabling of install messages
|
24
|
+
* ADDED: Make API's NoopTextMapPropagator private
|
25
|
+
* ADDED: Use auto-generated resource constants in sdk and resource_detectors
|
26
|
+
* ADDED: Allow selecting multiple exporter
|
27
|
+
* ADDED: Add explicit BSP export error
|
28
|
+
* FIXED: Remove optional parent_context from in_span
|
29
|
+
* FIXED: Replace Time.now with Process.clock_gettime
|
30
|
+
* FIXED: Rename cloud.zone to cloud.availability_zone
|
31
|
+
* FIXED: Improve attribute error messages
|
32
|
+
* FIXED: Refactor Baggage to remove Noop*
|
33
|
+
* FIXED: Support OTEL_SERVICE_NAME env var
|
34
|
+
* FIXED: Remove unnecessary readers from SDK Tracer
|
35
|
+
* FIXED: Total order constraint on span.status=
|
36
|
+
* FIXED: Flakey tracer provider test
|
37
|
+
* FIXED: Split lock in TracerProvider
|
38
|
+
* FIXED: Span limits env vars
|
39
|
+
* FIXED: Prune invalid links
|
40
|
+
* DOCS: Update docs to rely more on environment variable configuration
|
41
|
+
|
42
|
+
### v1.0.0.rc2 / 2021-06-23
|
43
|
+
|
44
|
+
* BREAKING CHANGE: Remove optional parent_context from in_span [729](https://github.com/open-telemetry/opentelemetry-ruby/pull/729)
|
45
|
+
* BREAKING CHANGE: Replace Time.now with Process.clock_gettime [717](https://github.com/open-telemetry/opentelemetry-ruby/pull/717)
|
46
|
+
* BREAKING CHANGE: Refactor Baggage to remove Noop* [800](https://github.com/open-telemetry/opentelemetry-ruby/pull/800)
|
47
|
+
* BREAKING CHANGE: Remove unnecessary readers from SDK Tracer [820](https://github.com/open-telemetry/opentelemetry-ruby/pull/820)
|
48
|
+
- Tracer no longer surfaces attribute readers for the name, version, or tracer_provider
|
49
|
+
* BREAKING CHANGE: Total order constraint on span.status= [805](https://github.com/open-telemetry/opentelemetry-ruby/pull/805)
|
50
|
+
|
51
|
+
* ADDED: Add Tracer.non_recording_span to API [799](https://github.com/open-telemetry/opentelemetry-ruby/pull/799)
|
52
|
+
* ADDED: Add unnamed tracer warning message [830](https://github.com/open-telemetry/opentelemetry-ruby/pull/830)
|
53
|
+
* ADDED: Allow disabling of install messages [831](https://github.com/open-telemetry/opentelemetry-ruby/pull/831)
|
54
|
+
* FIXED: Rename cloud.zone to cloud.availability_zone [734](https://github.com/open-telemetry/opentelemetry-ruby/pull/734)
|
55
|
+
* FIXED: Improve attribute error messages [742](https://github.com/open-telemetry/opentelemetry-ruby/pull/742)
|
56
|
+
* FIXED: Support OTEL_SERVICE_NAME env var [806]https://github.com/open-telemetry/opentelemetry-ruby/pull/806
|
57
|
+
* FIXED: Flakey tracer provider test
|
58
|
+
|
3
59
|
### v1.0.0.rc1 / 2021-05-21
|
4
60
|
|
5
61
|
* BREAKING CHANGE: Remove optional parent_context from in_span
|
data/README.md
CHANGED
@@ -29,10 +29,33 @@ Then, configure the SDK according to your desired handling of telemetry data, an
|
|
29
29
|
```ruby
|
30
30
|
require 'opentelemetry/sdk'
|
31
31
|
|
32
|
-
# Configure the sdk with default export and context propagation formats
|
33
|
-
# see SDK#configure for customizing the setup
|
32
|
+
# Configure the sdk with default export and context propagation formats.
|
34
33
|
OpenTelemetry::SDK.configure
|
35
34
|
|
35
|
+
# Many configuration options may be set via the environment. To use them,
|
36
|
+
# set the appropriate variable before calling configure. For example:
|
37
|
+
#
|
38
|
+
# ENV['OTEL_TRACES_EXPORTER'] = 'console'
|
39
|
+
# ENV['OTEL_PROPAGATORS'] = 'ottrace'
|
40
|
+
# OpenTelemetry::SDK.configure
|
41
|
+
#
|
42
|
+
# You may also configure the SDK programmatically, for advanced usage or to
|
43
|
+
# enable auto-instrumentation. For example:
|
44
|
+
#
|
45
|
+
# OpenTelemetry::SDK.configure do |c|
|
46
|
+
# c.service_name = something_calculated_dynamically
|
47
|
+
# c.add_span_processor(
|
48
|
+
# OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
|
49
|
+
# OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
|
50
|
+
# )
|
51
|
+
# )
|
52
|
+
#
|
53
|
+
# c.use 'OpenTelemetry::Instrumentation::Net::HTTP'
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# Note that the SimpleSpanExporter is not recommended for use in production.
|
57
|
+
|
58
|
+
|
36
59
|
# To start a trace you need to get a Tracer from the TracerProvider
|
37
60
|
tracer = OpenTelemetry.tracer_provider.tracer('my_app_or_gem', '0.1.0')
|
38
61
|
|
@@ -9,13 +9,29 @@ module OpenTelemetry
|
|
9
9
|
# The configurator provides defaults and facilitates configuring the
|
10
10
|
# SDK for use.
|
11
11
|
class Configurator # rubocop:disable Metrics/ClassLength
|
12
|
+
# @api private
|
13
|
+
class NoopTextMapPropagator
|
14
|
+
EMPTY_LIST = [].freeze
|
15
|
+
private_constant(:EMPTY_LIST)
|
16
|
+
|
17
|
+
def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter); end
|
18
|
+
|
19
|
+
def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
|
20
|
+
context
|
21
|
+
end
|
22
|
+
|
23
|
+
def fields
|
24
|
+
EMPTY_LIST
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
12
28
|
USE_MODE_UNSPECIFIED = 0
|
13
29
|
USE_MODE_ONE = 1
|
14
30
|
USE_MODE_ALL = 2
|
15
31
|
|
16
32
|
private_constant :USE_MODE_UNSPECIFIED, :USE_MODE_ONE, :USE_MODE_ALL
|
17
33
|
|
18
|
-
attr_writer :
|
34
|
+
attr_writer :propagators, :error_handler, :id_generator
|
19
35
|
|
20
36
|
def initialize
|
21
37
|
@instrumentation_names = []
|
@@ -31,6 +47,15 @@ module OpenTelemetry
|
|
31
47
|
@logger ||= OpenTelemetry.logger
|
32
48
|
end
|
33
49
|
|
50
|
+
# Accepts a logger and wraps it in the {ForwardingLogger} which allows
|
51
|
+
# for controlling the severity level emitted by the OpenTelemetry.logger
|
52
|
+
# independently of the supplied logger.
|
53
|
+
#
|
54
|
+
# @param [Logger] new_logger The logger for OpenTelemetry to use
|
55
|
+
def logger=(new_logger)
|
56
|
+
@logger = ForwardingLogger.new(new_logger, level: ENV['OTEL_LOG_LEVEL'] || Logger::INFO)
|
57
|
+
end
|
58
|
+
|
34
59
|
def error_handler
|
35
60
|
@error_handler ||= OpenTelemetry.error_handler
|
36
61
|
end
|
@@ -51,7 +76,7 @@ module OpenTelemetry
|
|
51
76
|
# @param [String] service_name The value to be used as the service name
|
52
77
|
def service_name=(service_name)
|
53
78
|
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
|
54
|
-
OpenTelemetry::
|
79
|
+
OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => service_name
|
55
80
|
)
|
56
81
|
end
|
57
82
|
|
@@ -61,7 +86,7 @@ module OpenTelemetry
|
|
61
86
|
# @param [String] service_version The value to be used as the service version
|
62
87
|
def service_version=(service_version)
|
63
88
|
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
|
64
|
-
OpenTelemetry::
|
89
|
+
OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION => service_version
|
65
90
|
)
|
66
91
|
end
|
67
92
|
|
@@ -112,7 +137,6 @@ module OpenTelemetry
|
|
112
137
|
def configure
|
113
138
|
OpenTelemetry.logger = logger
|
114
139
|
OpenTelemetry.error_handler = error_handler
|
115
|
-
OpenTelemetry.baggage = Baggage::Manager.new
|
116
140
|
configure_propagation
|
117
141
|
configure_span_processors
|
118
142
|
tracer_provider.id_generator = @id_generator
|
@@ -123,7 +147,7 @@ module OpenTelemetry
|
|
123
147
|
private
|
124
148
|
|
125
149
|
def tracer_provider
|
126
|
-
@tracer_provider ||= Trace::TracerProvider.new(@resource)
|
150
|
+
@tracer_provider ||= Trace::TracerProvider.new(resource: @resource)
|
127
151
|
end
|
128
152
|
|
129
153
|
def check_use_mode!(mode)
|
@@ -141,21 +165,23 @@ module OpenTelemetry
|
|
141
165
|
end
|
142
166
|
|
143
167
|
def configure_span_processors
|
144
|
-
processors = @span_processors.empty? ?
|
168
|
+
processors = @span_processors.empty? ? wrapped_exporters_from_env.compact : @span_processors
|
145
169
|
processors.each { |p| tracer_provider.add_span_processor(p) }
|
146
170
|
end
|
147
171
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
172
|
+
def wrapped_exporters_from_env
|
173
|
+
exporters = ENV.fetch('OTEL_TRACES_EXPORTER', 'otlp')
|
174
|
+
exporters.split(',').map do |exporter|
|
175
|
+
case exporter.strip
|
176
|
+
when 'none' then nil
|
177
|
+
when 'otlp' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::OTLP::Exporter')
|
178
|
+
when 'jaeger' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Jaeger::CollectorExporter')
|
179
|
+
when 'zipkin' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Zipkin::Exporter')
|
180
|
+
when 'console' then Trace::Export::SimpleSpanProcessor.new(Trace::Export::ConsoleSpanExporter.new)
|
181
|
+
else
|
182
|
+
OpenTelemetry.logger.warn "The #{exporter} exporter is unknown and cannot be configured, spans will not be exported"
|
183
|
+
nil
|
184
|
+
end
|
159
185
|
end
|
160
186
|
end
|
161
187
|
|
@@ -171,7 +197,7 @@ module OpenTelemetry
|
|
171
197
|
when 'ottrace' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::OTTrace')
|
172
198
|
else
|
173
199
|
OpenTelemetry.logger.warn "The #{propagator} propagator is unknown and cannot be configured"
|
174
|
-
|
200
|
+
NoopTextMapPropagator.new
|
175
201
|
end
|
176
202
|
end
|
177
203
|
OpenTelemetry.propagation = Context::Propagation::CompositeTextMapPropagator.compose_propagators((@propagators || propagators).compact)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module OpenTelemetry
|
6
|
+
module SDK
|
7
|
+
# The ForwardingLogger provides a wrapper to control the OpenTelemetry
|
8
|
+
# log level, while respecting the configured level of the supplied logger.
|
9
|
+
# If the OTEL_LOG_LEVEL is set to debug, and the supplied logger is configured
|
10
|
+
# with an ERROR log level, only OpenTelemetry logs at the ERROR level or higher
|
11
|
+
# will be emitted.
|
12
|
+
class ForwardingLogger
|
13
|
+
def initialize(logger, level:) # rubocop:disable Metrics/CyclomaticComplexity
|
14
|
+
@logger = logger
|
15
|
+
|
16
|
+
if level.is_a?(Integer)
|
17
|
+
@level = level
|
18
|
+
else
|
19
|
+
case level.to_s.downcase
|
20
|
+
when 'debug'
|
21
|
+
@level = Logger::DEBUG
|
22
|
+
when 'info'
|
23
|
+
@level = Logger::INFO
|
24
|
+
when 'warn'
|
25
|
+
@level = Logger::WARN
|
26
|
+
when 'error'
|
27
|
+
@level = Logger::ERROR
|
28
|
+
when 'fatal'
|
29
|
+
@level = Logger::FATAL
|
30
|
+
when 'unknown'
|
31
|
+
@level = Logger::UNKNOWN
|
32
|
+
else
|
33
|
+
raise ArgumentError, "invalid log level: #{level}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def add(severity, message = nil, progname = nil)
|
39
|
+
return true if severity < @level
|
40
|
+
|
41
|
+
@logger.add(severity, message, progname)
|
42
|
+
end
|
43
|
+
|
44
|
+
def debug(progname = nil, &block)
|
45
|
+
add(Logger::DEBUG, nil, progname, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def info(progname = nil, &block)
|
49
|
+
add(Logger::INFO, nil, progname, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def warn(progname = nil, &block)
|
53
|
+
add(Logger::WARN, nil, progname, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def error(progname = nil, &block)
|
57
|
+
add(Logger::ERROR, nil, progname, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
def fatal(progname = nil, &block)
|
61
|
+
add(Logger::FATAL, nil, progname, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
def unknown(progname = nil, &block)
|
65
|
+
add(Logger::UNKNOWN, nil, progname, &block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -31,14 +31,14 @@ module OpenTelemetry
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def default
|
34
|
-
@default ||= create(
|
34
|
+
@default ||= create(SemanticConventions::Resource::SERVICE_NAME => 'unknown_service').merge(process).merge(telemetry_sdk).merge(service_name_from_env)
|
35
35
|
end
|
36
36
|
|
37
37
|
def telemetry_sdk
|
38
38
|
resource_attributes = {
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
SemanticConventions::Resource::TELEMETRY_SDK_NAME => 'opentelemetry',
|
40
|
+
SemanticConventions::Resource::TELEMETRY_SDK_LANGUAGE => 'ruby',
|
41
|
+
SemanticConventions::Resource::TELEMETRY_SDK_VERSION => OpenTelemetry::SDK::VERSION
|
42
42
|
}
|
43
43
|
|
44
44
|
resource_pairs = ENV['OTEL_RESOURCE_ATTRIBUTES']
|
@@ -55,15 +55,22 @@ module OpenTelemetry
|
|
55
55
|
|
56
56
|
def process
|
57
57
|
resource_attributes = {
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
SemanticConventions::Resource::PROCESS_PID => Process.pid,
|
59
|
+
SemanticConventions::Resource::PROCESS_COMMAND => $PROGRAM_NAME,
|
60
|
+
SemanticConventions::Resource::PROCESS_RUNTIME_NAME => RUBY_ENGINE,
|
61
|
+
SemanticConventions::Resource::PROCESS_RUNTIME_VERSION => RUBY_VERSION,
|
62
|
+
SemanticConventions::Resource::PROCESS_RUNTIME_DESCRIPTION => RUBY_DESCRIPTION
|
63
63
|
}
|
64
64
|
|
65
65
|
create(resource_attributes)
|
66
66
|
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def service_name_from_env
|
71
|
+
service_name = ENV['OTEL_SERVICE_NAME']
|
72
|
+
create(SemanticConventions::Resource::SERVICE_NAME => service_name) unless service_name.nil?
|
73
|
+
end
|
67
74
|
end
|
68
75
|
|
69
76
|
# @api private
|
@@ -146,9 +146,9 @@ module OpenTelemetry
|
|
146
146
|
|
147
147
|
thread&.join(timeout)
|
148
148
|
force_flush(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
149
|
-
@exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
150
149
|
dropped_spans = lock { spans.size }
|
151
150
|
report_dropped_spans(dropped_spans, reason: 'terminating') if dropped_spans.positive?
|
151
|
+
@exporter.shutdown(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
|
152
152
|
end
|
153
153
|
|
154
154
|
private
|
@@ -187,6 +187,10 @@ module OpenTelemetry
|
|
187
187
|
result_code = @export_mutex.synchronize { @exporter.export(batch, timeout: timeout) }
|
188
188
|
report_result(result_code, batch)
|
189
189
|
result_code
|
190
|
+
rescue StandardError => e
|
191
|
+
report_result(FAILURE, batch)
|
192
|
+
@metrics_reporter.add_to_counter('otel.bsp.error', labels: { 'reason' => e.class.to_s })
|
193
|
+
FAILURE
|
190
194
|
end
|
191
195
|
|
192
196
|
def report_result(result_code, batch)
|
@@ -194,7 +198,7 @@ module OpenTelemetry
|
|
194
198
|
@metrics_reporter.add_to_counter('otel.bsp.export.success')
|
195
199
|
@metrics_reporter.add_to_counter('otel.bsp.exported_spans', increment: batch.size)
|
196
200
|
else
|
197
|
-
OpenTelemetry.handle_error(
|
201
|
+
OpenTelemetry.handle_error(exception: ExportError.new("Unable to export #{batch.size} spans"))
|
198
202
|
@metrics_reporter.add_to_counter('otel.bsp.export.failure')
|
199
203
|
report_dropped_spans(batch.size, reason: 'export-failure')
|
200
204
|
end
|
@@ -8,24 +8,25 @@ module OpenTelemetry
|
|
8
8
|
module SDK
|
9
9
|
module Trace
|
10
10
|
module Export
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# SpanExporter describes a duck type. It is not required to subclass this
|
12
|
+
# class to provide an implementation of SpanExporter, provided the interface is
|
13
|
+
# satisfied. SpanExporter allows different tracing services to export
|
13
14
|
# recorded data for sampled spans in their own format.
|
14
15
|
#
|
15
16
|
# To export data an exporter MUST be registered to the {TracerProvider} using
|
16
|
-
# a {
|
17
|
-
class
|
17
|
+
# a {SpanProcessor} implementation.
|
18
|
+
class SpanExporter
|
18
19
|
def initialize
|
19
20
|
@stopped = false
|
20
21
|
end
|
21
22
|
|
22
|
-
# Called to export sampled {
|
23
|
+
# Called to export sampled {SpanData}s.
|
23
24
|
#
|
24
|
-
# @param [Enumerable<
|
25
|
+
# @param [Enumerable<SpanData>] span_data the list of sampled {SpanData} to be
|
25
26
|
# exported.
|
26
27
|
# @param [optional Numeric] timeout An optional timeout in seconds.
|
27
28
|
# @return [Integer] the result of the export.
|
28
|
-
def export(
|
29
|
+
def export(span_data, timeout: nil)
|
29
30
|
return SUCCESS unless @stopped
|
30
31
|
|
31
32
|
FAILURE
|
@@ -10,6 +10,8 @@ module OpenTelemetry
|
|
10
10
|
# The Export module contains the built-in exporters and span processors for the OpenTelemetry
|
11
11
|
# reference implementation.
|
12
12
|
module Export
|
13
|
+
ExportError = Class.new(OpenTelemetry::Error)
|
14
|
+
|
13
15
|
# Result codes for the SpanExporter#export method and the SpanProcessor#force_flush and SpanProcessor#shutdown methods.
|
14
16
|
|
15
17
|
# The operation finished successfully.
|
@@ -31,6 +33,5 @@ require 'opentelemetry/sdk/trace/export/batch_span_processor'
|
|
31
33
|
require 'opentelemetry/sdk/trace/export/console_span_exporter'
|
32
34
|
require 'opentelemetry/sdk/trace/export/in_memory_span_exporter'
|
33
35
|
require 'opentelemetry/sdk/trace/export/metrics_reporter'
|
34
|
-
require 'opentelemetry/sdk/trace/export/
|
35
|
-
require 'opentelemetry/sdk/trace/export/noop_span_exporter'
|
36
|
+
require 'opentelemetry/sdk/trace/export/span_exporter'
|
36
37
|
require 'opentelemetry/sdk/trace/export/simple_span_processor'
|
@@ -10,13 +10,13 @@ module OpenTelemetry
|
|
10
10
|
# Implementation of {OpenTelemetry::Trace::Span} that records trace events.
|
11
11
|
#
|
12
12
|
# This implementation includes reader methods intended to allow access to
|
13
|
-
# internal state by
|
13
|
+
# internal state by {SpanProcessor}s.
|
14
14
|
# Instrumentation should use the API provided by {OpenTelemetry::Trace::Span}
|
15
15
|
# and should consider {Span} to be write-only.
|
16
16
|
#
|
17
17
|
# rubocop:disable Metrics/ClassLength
|
18
18
|
class Span < OpenTelemetry::Trace::Span
|
19
|
-
DEFAULT_STATUS = OpenTelemetry::Trace::Status.
|
19
|
+
DEFAULT_STATUS = OpenTelemetry::Trace::Status.unset
|
20
20
|
EMPTY_ATTRIBUTES = {}.freeze
|
21
21
|
|
22
22
|
private_constant :DEFAULT_STATUS, :EMPTY_ATTRIBUTES
|
@@ -159,7 +159,7 @@ module OpenTelemetry
|
|
159
159
|
event_attributes = {
|
160
160
|
'exception.type' => exception.class.to_s,
|
161
161
|
'exception.message' => exception.message,
|
162
|
-
'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
|
162
|
+
'exception.stacktrace' => exception.full_message(highlight: false, order: :top).encode('UTF-8', invalid: :replace, undef: :replace, replace: '�')
|
163
163
|
}
|
164
164
|
event_attributes.merge!(attributes) unless attributes.nil?
|
165
165
|
add_event('exception', attributes: event_attributes)
|
@@ -167,20 +167,23 @@ module OpenTelemetry
|
|
167
167
|
|
168
168
|
# Sets the Status to the Span
|
169
169
|
#
|
170
|
-
# If used, this will override the default Span status. Default
|
170
|
+
# If used, this will override the default Span status. Default has code = Status::UNSET.
|
171
171
|
#
|
172
|
-
#
|
173
|
-
#
|
172
|
+
# An attempt to set the status with code == Status::UNSET is ignored.
|
173
|
+
# If the status is set with code == Status::OK, any further attempt to set the status
|
174
|
+
# is ignored.
|
174
175
|
#
|
175
176
|
# @param [Status] status The new status, which overrides the default Span
|
176
|
-
# status, which
|
177
|
+
# status, which has code = Status::UNSET.
|
177
178
|
#
|
178
179
|
# @return [void]
|
179
180
|
def status=(status)
|
181
|
+
return if status.code == OpenTelemetry::Trace::Status::UNSET
|
182
|
+
|
180
183
|
@mutex.synchronize do
|
181
184
|
if @ended
|
182
185
|
OpenTelemetry.logger.warn('Calling status= on an ended Span.')
|
183
|
-
|
186
|
+
elsif @status.code != OpenTelemetry::Trace::Status::OK
|
184
187
|
@status = status
|
185
188
|
end
|
186
189
|
end
|
@@ -235,7 +238,7 @@ module OpenTelemetry
|
|
235
238
|
@events.freeze
|
236
239
|
@ended = true
|
237
240
|
end
|
238
|
-
@
|
241
|
+
@span_processors.each { |processor| processor.on_finish(self) }
|
239
242
|
self
|
240
243
|
end
|
241
244
|
|
@@ -273,14 +276,14 @@ module OpenTelemetry
|
|
273
276
|
end
|
274
277
|
|
275
278
|
# @api private
|
276
|
-
def initialize(context, parent_context, name, kind, parent_span_id,
|
279
|
+
def initialize(context, parent_context, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
|
277
280
|
super(span_context: context)
|
278
281
|
@mutex = Mutex.new
|
279
282
|
@name = name
|
280
283
|
@kind = kind
|
281
284
|
@parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
|
282
|
-
@
|
283
|
-
@
|
285
|
+
@span_limits = span_limits
|
286
|
+
@span_processors = span_processors
|
284
287
|
@resource = resource
|
285
288
|
@instrumentation_library = instrumentation_library
|
286
289
|
@ended = false
|
@@ -293,8 +296,8 @@ module OpenTelemetry
|
|
293
296
|
@attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
|
294
297
|
trim_span_attributes(@attributes)
|
295
298
|
@events = nil
|
296
|
-
@links = trim_links(links,
|
297
|
-
@
|
299
|
+
@links = trim_links(links, span_limits.link_count_limit, span_limits.link_attribute_count_limit)
|
300
|
+
@span_processors.each { |processor| processor.on_start(self, parent_context) }
|
298
301
|
end
|
299
302
|
|
300
303
|
# TODO: Java implementation overrides finalize to log if a span isn't finished.
|
@@ -310,7 +313,7 @@ module OpenTelemetry
|
|
310
313
|
def trim_span_attributes(attrs)
|
311
314
|
return if attrs.nil?
|
312
315
|
|
313
|
-
excess = attrs.size - @
|
316
|
+
excess = attrs.size - @span_limits.attribute_count_limit
|
314
317
|
excess.times { attrs.shift } if excess.positive?
|
315
318
|
truncate_attribute_values(attrs)
|
316
319
|
nil
|
@@ -319,51 +322,54 @@ module OpenTelemetry
|
|
319
322
|
def truncate_attribute_values(attrs)
|
320
323
|
return EMPTY_ATTRIBUTES if attrs.nil?
|
321
324
|
|
322
|
-
|
323
|
-
attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value,
|
325
|
+
attribute_length_limit = @span_limits.attribute_length_limit
|
326
|
+
attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value, attribute_length_limit) } if attribute_length_limit
|
324
327
|
attrs
|
325
328
|
end
|
326
329
|
|
327
|
-
def trim_links(links,
|
330
|
+
def trim_links(links, link_count_limit, link_attribute_count_limit) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
328
331
|
# Fast path (likely) common cases.
|
329
332
|
return nil if links.nil?
|
330
333
|
|
331
|
-
if links.size <=
|
332
|
-
links.all? { |link| link.attributes.size <=
|
334
|
+
if links.size <= link_count_limit &&
|
335
|
+
links.all? { |link| link.span_context.valid? && link.attributes.size <= link_attribute_count_limit && Internal.valid_attributes?(name, 'link', link.attributes) }
|
333
336
|
return links.frozen? ? links : links.clone.freeze
|
334
337
|
end
|
335
338
|
|
336
339
|
# Slow path: trim attributes for each Link.
|
337
|
-
links.
|
340
|
+
valid_links = links.select { |link| link.span_context.valid? }
|
341
|
+
excess_link_count = valid_links.size - link_count_limit
|
342
|
+
valid_links.pop(excess_link_count) if excess_link_count.positive?
|
343
|
+
valid_links.map! do |link|
|
338
344
|
attrs = Hash[link.attributes] # link.attributes is frozen, so we need an unfrozen copy to adjust.
|
339
345
|
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
340
|
-
excess = attrs.size -
|
346
|
+
excess = attrs.size - link_attribute_count_limit
|
341
347
|
excess.times { attrs.shift } if excess.positive?
|
342
348
|
OpenTelemetry::Trace::Link.new(link.span_context, attrs)
|
343
349
|
end.freeze
|
344
350
|
end
|
345
351
|
|
346
352
|
def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
347
|
-
|
348
|
-
|
353
|
+
event_count_limit = @span_limits.event_count_limit
|
354
|
+
event_attribute_count_limit = @span_limits.event_attribute_count_limit
|
349
355
|
valid_attributes = Internal.valid_attributes?(name, 'event', event.attributes)
|
350
356
|
|
351
357
|
# Fast path (likely) common case.
|
352
|
-
if events.size <
|
353
|
-
event.attributes.size <=
|
358
|
+
if events.size < event_count_limit &&
|
359
|
+
event.attributes.size <= event_attribute_count_limit &&
|
354
360
|
valid_attributes
|
355
361
|
return events << event
|
356
362
|
end
|
357
363
|
|
358
364
|
# Slow path.
|
359
|
-
excess = events.size + 1 -
|
365
|
+
excess = events.size + 1 - event_count_limit
|
360
366
|
events.shift(excess) if excess.positive?
|
361
367
|
|
362
|
-
excess = event.attributes.size -
|
368
|
+
excess = event.attributes.size - event_attribute_count_limit
|
363
369
|
if excess.positive? || !valid_attributes
|
364
370
|
attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
|
365
371
|
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
366
|
-
excess = attrs.size -
|
372
|
+
excess = attrs.size - event_attribute_count_limit
|
367
373
|
excess.times { attrs.shift } if excess.positive?
|
368
374
|
event = Event.new(event.name, attrs.freeze, event.timestamp)
|
369
375
|
end
|