opentelemetry-sdk 0.12.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '079e4ea0a93345e6e014c3f7760425e042544ae619cf5761cb08813dac99a728'
4
- data.tar.gz: f36464e88c42bd56a60060854da46daa42b35b720619201ed30e8a038ea567c7
3
+ metadata.gz: 0231dc6f06956325ffb14fc4a209f579001c7cc059659da14d4a4790fd07efeb
4
+ data.tar.gz: 676299747265e10f02eb15ffda455bfcd70155a9969e1f021804fb37c26ba768
5
5
  SHA512:
6
- metadata.gz: 7305bdedc102299c04c3c0798d9137fc74919e4edd3eb37a4b239c739218274427b82f925d97cdcdebd192559033f025a6cad2f729f5d05c5856b6aa6e9e2170
7
- data.tar.gz: efcd32dc9aa6c9e260b05829d790c294308e08bc7ca275647c33f54b03ac463a63da7962a9038917c6fe3571ae10dc61efaa09dfc17eb5bfae4ed040719a8c80
6
+ metadata.gz: ea3a1003fd132137846cbf7957da2524e21dca19d0899c9663cebbc5836bd5ce1adafe4b0ecf8f899600a94701b410534ea1eca56409da9e2dc3de658b0cb4c7
7
+ data.tar.gz: ee4b4487c397cee00f0d40854c3c19b7e405bfff70f145ee8520f1ceb924ac7a99cb8b15a43af30c826f59d08028345ab62535d5fef0164c89e43bd6b221d43c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Release History: opentelemetry-sdk
2
2
 
3
+ ### v0.16.0 / 2021-03-17
4
+
5
+ * BREAKING CHANGE: Update SDK BaggageManager to match API
6
+ * BREAKING CHANGE: Implement Exporter#force_flush
7
+
8
+ * ADDED: Add force_flush to SDK's TracerProvider
9
+ * ADDED: Add k8s node to gcp resource detector
10
+ * ADDED: Add console option for OTEL_TRACES_EXPORTER
11
+ * ADDED: Span#add_attributes
12
+ * ADDED: Implement Exporter#force_flush
13
+ * FIXED: Update SDK BaggageManager to match API
14
+ * DOCS: Replace Gitter with GitHub Discussions
15
+
16
+ ### v0.15.0 / 2021-02-18
17
+
18
+ * BREAKING CHANGE: Streamline processor pipeline
19
+
20
+ * ADDED: Add instrumentation config validation
21
+ * FIXED: Streamline processor pipeline
22
+ * FIXED: OTEL_TRACE -> OTEL_TRACES env vars
23
+ * FIXED: Change limits from 1000 to 128
24
+ * FIXED: OTEL_TRACES_EXPORTER and OTEL_PROPAGATORS
25
+ * FIXED: Add thread error handling to the BSP
26
+ * DOCS: Clarify nil attribute values not allowed
27
+
28
+ ### v0.14.0 / 2021-02-03
29
+
30
+ * BREAKING CHANGE: Replace getter and setter callables and remove rack specific propagators
31
+
32
+ * ADDED: Replace getter and setter callables and remove rack specific propagators
33
+
34
+ ### v0.13.1 / 2021-02-01
35
+
36
+ * FIXED: Leaky test
37
+ * FIXED: Allow env var override of service.name
38
+
39
+ ### v0.13.0 / 2021-01-29
40
+
41
+ * BREAKING CHANGE: Remove MILLIS from BatchSpanProcessor vars
42
+
43
+ * ADDED: Process.runtime resource
44
+ * ADDED: Provide default resource in SDK
45
+ * ADDED: Add optional attributes to record_exception
46
+ * FIXED: Resource.merge consistency
47
+ * FIXED: Remove MILLIS from BatchSpanProcessor vars
48
+
3
49
  ### v0.12.1 / 2021-01-13
4
50
 
5
51
  * FIXED: Fix several BatchSpanProcessor errors related to fork safety
data/README.md CHANGED
@@ -56,7 +56,7 @@ For additional examples, see the [examples on github][examples-github].
56
56
 
57
57
  The `opentelemetry-sdk` gem source is [on github][repo-github], along with related gems including `opentelemetry-api`.
58
58
 
59
- The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special interest group (SIG). You can get involved by joining us on our [gitter channel][ruby-gitter] or attending our weekly meeting. See the [meeting calendar][community-meetings] for dates and times. For more information on this and other language SIGs, see the OpenTelemetry [community page][ruby-sig].
59
+ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special interest group (SIG). You can get involved by joining us in [GitHub Discussions][discussions-url] or attending our weekly meeting. See the [meeting calendar][community-meetings] for dates and times. For more information on this and other language SIGs, see the OpenTelemetry [community page][ruby-sig].
60
60
 
61
61
  ## License
62
62
 
@@ -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/master/LICENSE
70
- [examples-github]: https://github.com/open-telemetry/opentelemetry-ruby/tree/master/examples
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
- [ruby-gitter]: https://gitter.im/open-telemetry/opentelemetry-ruby
73
+ [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions
@@ -22,7 +22,7 @@ module OpenTelemetry
22
22
  # @param [optional Context] context The context to update with with new
23
23
  # modified baggage. Defaults to +Context.current+
24
24
  # @return [Context]
25
- def build_context(context: Context.current)
25
+ def build(context: Context.current)
26
26
  builder = Builder.new(baggage_for(context).dup)
27
27
  yield builder
28
28
  context.set_value(BAGGAGE_KEY, builder.entries)
@@ -15,19 +15,17 @@ module OpenTelemetry
15
15
 
16
16
  private_constant :USE_MODE_UNSPECIFIED, :USE_MODE_ONE, :USE_MODE_ALL
17
17
 
18
- attr_writer :logger, :http_extractors, :http_injectors, :text_map_extractors,
19
- :text_map_injectors, :error_handler, :id_generator
18
+ attr_writer :logger, :extractors, :injectors, :error_handler,
19
+ :id_generator
20
20
 
21
21
  def initialize
22
22
  @instrumentation_names = []
23
23
  @instrumentation_config_map = {}
24
- @http_extractors = nil
25
- @http_injectors = nil
26
- @text_map_extractors = nil
27
- @text_map_injectors = nil
24
+ @injectors = nil
25
+ @extractors = nil
28
26
  @span_processors = []
29
27
  @use_mode = USE_MODE_UNSPECIFIED
30
- @resource = Resources::Resource.telemetry_sdk
28
+ @resource = Resources::Resource.default
31
29
  @id_generator = OpenTelemetry::Trace
32
30
  end
33
31
 
@@ -46,7 +44,7 @@ module OpenTelemetry
46
44
  #
47
45
  # @param [Resource] new_resource The resource to be merged
48
46
  def resource=(new_resource)
49
- @resource = new_resource.merge(@resource)
47
+ @resource = @resource.merge(new_resource)
50
48
  end
51
49
 
52
50
  # Accepts a string that is merged in as the service.name resource attribute.
@@ -54,9 +52,9 @@ module OpenTelemetry
54
52
  # calls to this setter.
55
53
  # @param [String] service_name The value to be used as the service name
56
54
  def service_name=(service_name)
57
- @resource = OpenTelemetry::SDK::Resources::Resource.create(
55
+ self.resource = OpenTelemetry::SDK::Resources::Resource.create(
58
56
  OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:name] => service_name
59
- ).merge(@resource)
57
+ )
60
58
  end
61
59
 
62
60
  # Accepts a string that is merged in as the service.version resource attribute.
@@ -64,9 +62,9 @@ module OpenTelemetry
64
62
  # calls to this setter.
65
63
  # @param [String] service_version The value to be used as the service version
66
64
  def service_version=(service_version)
67
- @resource = OpenTelemetry::SDK::Resources::Resource.create(
65
+ self.resource = OpenTelemetry::SDK::Resources::Resource.create(
68
66
  OpenTelemetry::SDK::Resources::Constants::SERVICE_RESOURCE[:version] => service_version
69
- ).merge(@resource)
67
+ )
70
68
  end
71
69
 
72
70
  # Install an instrumentation with specificied optional +config+.
@@ -145,54 +143,67 @@ module OpenTelemetry
145
143
  end
146
144
 
147
145
  def configure_span_processors
148
- processors = @span_processors.empty? ? [default_span_processor] : @span_processors
146
+ processors = @span_processors.empty? ? [wrapped_exporter_from_env].compact : @span_processors
149
147
  processors.each { |p| tracer_provider.add_span_processor(p) }
150
148
  end
151
149
 
152
- def default_span_processor
153
- Trace::Export::SimpleSpanProcessor.new(
154
- Trace::Export::ConsoleSpanExporter.new
155
- )
150
+ def wrapped_exporter_from_env
151
+ exporter = ENV.fetch('OTEL_TRACES_EXPORTER', 'otlp')
152
+ case exporter
153
+ when 'none' then nil
154
+ when 'otlp' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::OTLP::Exporter')
155
+ when 'jaeger' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Jaeger::CollectorExporter')
156
+ when 'zipkin' then fetch_exporter(exporter, 'OpenTelemetry::Exporter::Zipkin::Exporter')
157
+ when 'console' then Trace::Export::SimpleSpanProcessor.new(Trace::Export::ConsoleSpanExporter.new)
158
+ else
159
+ OpenTelemetry.logger.warn "The #{exporter} exporter is unknown and cannot be configured, spans will not be exported"
160
+ nil
161
+ end
156
162
  end
157
163
 
158
- def configure_propagation
159
- OpenTelemetry.propagation.http = create_propagator(@http_injectors || default_http_injectors,
160
- @http_extractors || default_http_extractors)
161
- OpenTelemetry.propagation.text = create_propagator(@text_map_injectors || default_text_map_injectors,
162
- @text_map_extractors || default_text_map_extractors)
164
+ def configure_propagation # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
165
+ propagators = ENV.fetch('OTEL_PROPAGATORS', 'tracecontext,baggage').split(',')
166
+ injectors, extractors = propagators.uniq.collect do |propagator|
167
+ case propagator
168
+ when 'tracecontext'
169
+ [OpenTelemetry::Trace::Propagation::TraceContext.text_map_injector, OpenTelemetry::Trace::Propagation::TraceContext.text_map_extractor]
170
+ when 'baggage'
171
+ [OpenTelemetry::Baggage::Propagation.text_map_injector, OpenTelemetry::Baggage::Propagation.text_map_extractor]
172
+ when 'b3' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::B3::Single')
173
+ when 'b3multi' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::B3::Multi', 'b3')
174
+ when 'jaeger' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::Jaeger')
175
+ when 'xray' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::XRay')
176
+ when 'ottrace' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::OTTrace')
177
+ else
178
+ OpenTelemetry.logger.warn "The #{propagator} propagator is unknown and cannot be configured"
179
+ [Context::Propagation::NoopInjector.new, Context::Propagation::NoopExtractor.new]
180
+ end
181
+ end.transpose
182
+ OpenTelemetry.propagation = create_propagator(@injectors || injectors.compact,
183
+ @extractors || extractors.compact)
163
184
  end
164
185
 
165
186
  def create_propagator(injectors, extractors)
166
187
  if injectors.size > 1 || extractors.size > 1
167
188
  Context::Propagation::CompositePropagator.new(injectors, extractors)
168
189
  else
169
- Context::Propagation::Propagator.new(injectors, extractors)
190
+ Context::Propagation::Propagator.new(injectors.first, extractors.first)
170
191
  end
171
192
  end
172
193
 
173
- def default_http_injectors
174
- default_text_map_injectors
175
- end
176
-
177
- def default_http_extractors
178
- [
179
- OpenTelemetry::Trace::Propagation::TraceContext.rack_extractor,
180
- OpenTelemetry::Baggage::Propagation.rack_extractor
181
- ]
182
- end
183
-
184
- def default_text_map_injectors
185
- [
186
- OpenTelemetry::Trace::Propagation::TraceContext.text_map_injector,
187
- OpenTelemetry::Baggage::Propagation.text_map_injector
188
- ]
194
+ def fetch_propagator(name, class_name, gem_suffix = name)
195
+ propagator_class = Kernel.const_get(class_name)
196
+ [propagator_class.text_map_injector, propagator_class.text_map_extractor]
197
+ rescue NameError
198
+ OpenTelemetry.logger.warn "The #{name} propagator cannot be configured - please add opentelemetry-propagator-#{gem_suffix} to your Gemfile"
199
+ [nil, nil]
189
200
  end
190
201
 
191
- def default_text_map_extractors
192
- [
193
- OpenTelemetry::Trace::Propagation::TraceContext.text_map_extractor,
194
- OpenTelemetry::Baggage::Propagation.text_map_extractor
195
- ]
202
+ def fetch_exporter(name, class_name)
203
+ Trace::Export::BatchSpanProcessor.new(Kernel.const_get(class_name).new)
204
+ rescue NameError
205
+ OpenTelemetry.logger.warn "The #{name} exporter cannot be configured - please add opentelemetry-exporter-#{name} to your Gemfile, spans will not be exported"
206
+ nil
196
207
  end
197
208
  end
198
209
  end
@@ -67,14 +67,99 @@ module OpenTelemetry
67
67
  # The name of the cluster that the pod is running in.
68
68
  cluster_name: 'k8s.cluster.name',
69
69
 
70
+ # The name of the Node.
71
+ node_name: 'k8s.node.name',
72
+
73
+ # The UID of the Node.
74
+ node_uid: 'k8s.node.uid',
75
+
70
76
  # The name of the namespace that the pod is running in.
71
77
  namespace_name: 'k8s.namespace.name',
72
78
 
73
79
  # The name of the pod.
74
80
  pod_name: 'k8s.pod.name',
75
81
 
82
+ # The UID of the Pod.
83
+ pod_uid: 'k8s.pod.uid',
84
+
85
+ # The name of the Container in a Pod template.
86
+ container_name: 'k8s.container.name',
87
+
88
+ # The UID of the ReplicaSet.
89
+ replicaset_uid: 'k8s.replicaset.uid',
90
+
91
+ # The name of the ReplicaSet.
92
+ replicaset_name: 'k8s.replicaset.name',
93
+
94
+ # The UID of the Deployment.
95
+ deployment_uid: 'k8s.deployment.uid',
96
+
76
97
  # The name of the deployment.
77
- deployment_name: 'k8s.deployment.name'
98
+ deployment_name: 'k8s.deployment.name',
99
+
100
+ # The UID of the StatefulSet.
101
+ statefulset_uid: 'k8s.statefulset.uid',
102
+
103
+ # The name of the StatefulSet.
104
+ statefulset_name: 'k8s.statefulset.name',
105
+
106
+ # The UID of the DaemonSet.
107
+ daemonset_uid: 'k8s.daemonset.uid',
108
+
109
+ # The name of the DaemonSet.
110
+ daemonset_name: 'k8s.daemonset.name',
111
+
112
+ # The UID of the Job.
113
+ job_uid: 'k8s.job.uid',
114
+
115
+ # The name of the Job.
116
+ job_name: 'k8s.job.name',
117
+
118
+ # The UID of the CronJob.
119
+ cronjob_uid: 'k8s.cronjob.uid',
120
+
121
+ # The name of the CronJob.
122
+ cronjob_name: 'k8s.cronjob.name'
123
+ }.freeze
124
+
125
+ # Attributes defining an operating system process.
126
+ PROCESS_RESOURCE = {
127
+ # Process identifier (PID).
128
+ pid: 'process.pid',
129
+
130
+ # The name of the process executable.
131
+ executable_name: 'process.executable.name',
132
+
133
+ # The full path to the process executable.
134
+ executable_path: 'process.executable.path',
135
+
136
+ # The command used to launch the process (i.e. the command name).
137
+ command: 'process.command',
138
+
139
+ # The full command used to launch the process as a single string
140
+ # representing the full command.
141
+ command_line: 'process.command_line',
142
+
143
+ # All the command arguments (including the command/executable itself)
144
+ # as received by the process.
145
+ command_args: 'process.command_args',
146
+
147
+ # The username of the user that owns the process.
148
+ owner: 'process.owner'
149
+ }.freeze
150
+
151
+ # Attributes defining the single (language) runtime instance which is monitored.
152
+ PROCESS_RUNTIME_RESOURCE = {
153
+ # The name of the runtime of this process.
154
+ name: 'process.runtime.name',
155
+
156
+ # The version of the runtime of this process, as returned by the runtime
157
+ # without modification.
158
+ version: 'process.runtime.version',
159
+
160
+ # An additional description about the runtime of the process, for example
161
+ # a specific vendor customization of the runtime environment.
162
+ description: 'process.runtime.description'
78
163
  }.freeze
79
164
 
80
165
  # Attributes defining a computing instance (e.g. host).
@@ -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
- merged_attributes = attributes.merge(other.attributes) do |_, old_v, new_v|
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
@@ -33,9 +33,9 @@ module OpenTelemetry
33
33
  # @return [TraceConfig] with the desired values.
34
34
  # @raise [ArgumentError] if any of the max numbers are not positive.
35
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)),
36
+ max_attributes_count: Integer(ENV.fetch('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 128)),
37
+ max_events_count: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 128)),
38
+ max_links_count: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 128)),
39
39
  max_attributes_per_event: max_attributes_count,
40
40
  max_attributes_per_link: max_attributes_count)
41
41
  raise ArgumentError, 'max_attributes_count must be positive' unless max_attributes_count.positive?
@@ -56,13 +56,13 @@ module OpenTelemetry
56
56
  private
57
57
 
58
58
  def sampler_from_environment(default_sampler) # rubocop:disable Metrics/CyclomaticComplexity
59
- case ENV['OTEL_TRACE_SAMPLER']
59
+ case ENV['OTEL_TRACES_SAMPLER']
60
60
  when 'always_on' then Samplers::ALWAYS_ON
61
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)))
62
+ when 'traceidratio' then Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0)))
63
63
  when 'parentbased_always_on' then Samplers.parent_based(root: Samplers::ALWAYS_ON)
64
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))))
65
+ when 'parentbased_traceidratio' then Samplers.parent_based(root: Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0))))
66
66
  else default_sampler
67
67
  end
68
68
  rescue StandardError => e
@@ -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
- # schedule_delay_millis to the exporter pipeline in batches of
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
@@ -28,12 +28,13 @@ module OpenTelemetry
28
28
  class BatchSpanProcessor # rubocop:disable Metrics/ClassLength
29
29
  # Returns a new instance of the {BatchSpanProcessor}.
30
30
  #
31
- # @param [SpanExporter] exporter
32
- # @param [Numeric] exporter_timeout_millis the delay interval between two
33
- # consecutive exports. Defaults to the value of the OTEL_BSP_EXPORT_TIMEOUT_MILLIS
31
+ # @param [SpanExporter] exporter the (duck type) SpanExporter to where the
32
+ # recorded Spans are pushed after batching.
33
+ # @param [Numeric] exporter_timeout the delay interval between two
34
+ # consecutive exports. Defaults to the value of the OTEL_BSP_EXPORT_TIMEOUT
34
35
  # environment variable, if set, or 30,000 (30 seconds).
35
- # @param [Numeric] schedule_delay_millis the maximum allowed time to export data.
36
- # Defaults to the value of the OTEL_BSP_SCHEDULE_DELAY_MILLIS environment
36
+ # @param [Numeric] schedule_delay the maximum allowed time to export data.
37
+ # Defaults to the value of the OTEL_BSP_SCHEDULE_DELAY environment
37
38
  # variable, if set, or 5,000 (5 seconds).
38
39
  # @param [Integer] max_queue_size the maximum queue size in spans.
39
40
  # Defaults to the value of the OTEL_BSP_MAX_QUEUE_SIZE environment
@@ -43,9 +44,9 @@ module OpenTelemetry
43
44
  # variable, if set, or 512.
44
45
  #
45
46
  # @return a new instance of the {BatchSpanProcessor}.
46
- def initialize(exporter:,
47
- exporter_timeout_millis: Float(ENV.fetch('OTEL_BSP_EXPORT_TIMEOUT_MILLIS', 30_000)),
48
- schedule_delay_millis: Float(ENV.fetch('OTEL_BSP_SCHEDULE_DELAY_MILLIS', 5_000)),
47
+ def initialize(exporter,
48
+ exporter_timeout: Float(ENV.fetch('OTEL_BSP_EXPORT_TIMEOUT', 30_000)),
49
+ schedule_delay: Float(ENV.fetch('OTEL_BSP_SCHEDULE_DELAY', 5_000)),
49
50
  max_queue_size: Integer(ENV.fetch('OTEL_BSP_MAX_QUEUE_SIZE', 2048)),
50
51
  max_export_batch_size: Integer(ENV.fetch('OTEL_BSP_MAX_EXPORT_BATCH_SIZE', 512)),
51
52
  start_thread_on_boot: String(ENV['OTEL_RUBY_BSP_START_THREAD_ON_BOOT']) !~ /false/i,
@@ -53,12 +54,12 @@ module OpenTelemetry
53
54
  raise ArgumentError if max_export_batch_size > max_queue_size
54
55
 
55
56
  @exporter = exporter
56
- @exporter_timeout_seconds = exporter_timeout_millis / 1000.0
57
+ @exporter_timeout_seconds = exporter_timeout / 1000.0
57
58
  @mutex = Mutex.new
58
59
  @export_mutex = Mutex.new
59
60
  @condition = ConditionVariable.new
60
61
  @keep_running = true
61
- @delay_seconds = schedule_delay_millis / 1000.0
62
+ @delay_seconds = schedule_delay / 1000.0
62
63
  @max_queue_size = max_queue_size
63
64
  @batch_size = max_export_batch_size
64
65
  @metrics_reporter = metrics_reporter || OpenTelemetry::SDK::Trace::Export::MetricsReporter
@@ -113,7 +114,7 @@ module OpenTelemetry
113
114
  return result_code unless result_code == SUCCESS
114
115
  end
115
116
 
116
- SUCCESS
117
+ @exporter.force_flush(timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
117
118
  ensure
118
119
  # Unshift the remaining spans if we timed out. We drop excess spans from
119
120
  # the snapshot because they're older than any spans in the spans buffer.
@@ -176,6 +177,9 @@ module OpenTelemetry
176
177
  @pid = pid
177
178
  spans.clear
178
179
  @thread = restart_thread ? Thread.new { work } : nil
180
+ rescue ThreadError => e
181
+ @metrics_reporter.add_to_counter('otel.bsp.error', labels: { 'reason' => 'ThreadError' })
182
+ OpenTelemetry.handle_error(exception: e, message: 'unexpected error in BatchSpanProcessor#reset_on_fork')
179
183
  end
180
184
 
181
185
  def export_batch(batch, timeout: @exporter_timeout_seconds)
@@ -26,6 +26,10 @@ module OpenTelemetry
26
26
  SUCCESS
27
27
  end
28
28
 
29
+ def force_flush(timeout: nil)
30
+ SUCCESS
31
+ end
32
+
29
33
  def shutdown(timeout: nil)
30
34
  @stopped = true
31
35
  SUCCESS
@@ -72,6 +72,16 @@ module OpenTelemetry
72
72
  SUCCESS
73
73
  end
74
74
 
75
+ # Called when {TracerProvider#force_flush} is called, if this exporter is
76
+ # registered to a {TracerProvider} object.
77
+ #
78
+ # @param [optional Numeric] timeout An optional timeout in seconds.
79
+ # @return [Integer] SUCCESS if no error occurred, FAILURE if a
80
+ # non-specific failure occurred, TIMEOUT if a timeout occurred.
81
+ def force_flush(timeout: nil)
82
+ SUCCESS
83
+ end
84
+
75
85
  # Called when {TracerProvider#shutdown} is called, if this exporter is
76
86
  # registered to a {TracerProvider} object.
77
87
  #
@@ -36,6 +36,23 @@ module OpenTelemetry
36
36
  results.uniq.max || SUCCESS
37
37
  end
38
38
 
39
+ # Called when {TracerProvider#force_flush} is called, if this exporter is
40
+ # registered to a {TracerProvider} object.
41
+ #
42
+ # @param [optional Numeric] timeout An optional timeout in seconds.
43
+ # @return [Integer] SUCCESS if no error occurred, FAILURE if a
44
+ # non-specific failure occurred, TIMEOUT if a timeout occurred.
45
+ def force_flush(timeout: nil)
46
+ start_time = Time.now
47
+ results = @span_exporters.map do |processor|
48
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
49
+ return TIMEOUT if remaining_timeout&.zero?
50
+
51
+ processor.force_flush(timeout: remaining_timeout)
52
+ end
53
+ results.uniq.max || SUCCESS
54
+ end
55
+
39
56
  # Called when {TracerProvider#shutdown} is called, if this exporter is
40
57
  # registered to a {TracerProvider} object.
41
58
  #
@@ -31,6 +31,16 @@ module OpenTelemetry
31
31
  FAILURE
32
32
  end
33
33
 
34
+ # Called when {TracerProvider#force_flush} is called, if this exporter is
35
+ # registered to a {TracerProvider} object.
36
+ #
37
+ # @param [optional Numeric] timeout An optional timeout in seconds.
38
+ # @return [Integer] SUCCESS if no error occurred, FAILURE if a
39
+ # non-specific failure occurred, TIMEOUT if a timeout occurred.
40
+ def force_flush(timeout: nil)
41
+ SUCCESS
42
+ end
43
+
34
44
  # Called when {TracerProvider#shutdown} is called, if this exporter is
35
45
  # registered to a {TracerProvider} object.
36
46
  #
@@ -61,7 +61,7 @@ module OpenTelemetry
61
61
  end
62
62
 
63
63
  # Export all ended spans to the configured `Exporter` that have not yet
64
- # been exported.
64
+ # been exported, then call {Exporter#force_flush}.
65
65
  #
66
66
  # This method should only be called in cases where it is absolutely
67
67
  # necessary, such as when using some FaaS providers that may suspend
@@ -72,7 +72,7 @@ module OpenTelemetry
72
72
  # @return [Integer] SUCCESS if no error occurred, FAILURE if a
73
73
  # non-specific failure occurred, TIMEOUT if a timeout occurred.
74
74
  def force_flush(timeout: nil)
75
- SUCCESS
75
+ @span_exporter&.force_flush(timeout: timeout) || SUCCESS
76
76
  end
77
77
 
78
78
  # Called when {TracerProvider#shutdown} is called.
@@ -64,6 +64,9 @@ module OpenTelemetry
64
64
  #
65
65
  # @param [String] key
66
66
  # @param [String, Boolean, Numeric, Array<String, Numeric, Boolean>] value
67
+ # Values must be non-nil and (array of) string, boolean or numeric type.
68
+ # Array values must not contain nil elements and all elements must be of
69
+ # the same basic type (string, numeric, boolean).
67
70
  #
68
71
  # @return [self] returns itself
69
72
  def set_attribute(key, value)
@@ -82,6 +85,34 @@ module OpenTelemetry
82
85
  end
83
86
  alias []= set_attribute
84
87
 
88
+ # Add attributes
89
+ #
90
+ # Note that the OpenTelemetry project
91
+ # {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
92
+ # documents} certain "standard attributes" that have prescribed semantic
93
+ # meanings.
94
+ #
95
+ # @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
96
+ # Values must be non-nil and (array of) string, boolean or numeric type.
97
+ # Array values must not contain nil elements and all elements must be of
98
+ # the same basic type (string, numeric, boolean).
99
+ #
100
+ # @return [self] returns itself
101
+ def add_attributes(attributes)
102
+ super
103
+ @mutex.synchronize do
104
+ if @ended
105
+ OpenTelemetry.logger.warn('Calling add_attributes on an ended Span.')
106
+ else
107
+ @attributes ||= {}
108
+ @attributes.merge!(attributes)
109
+ trim_span_attributes(@attributes)
110
+ @total_recorded_attributes += attributes.size
111
+ end
112
+ end
113
+ self
114
+ end
115
+
85
116
  # Add an Event to a {Span}.
86
117
  #
87
118
  # Example:
@@ -96,7 +127,7 @@ module OpenTelemetry
96
127
  # @param [String] name Name of the event.
97
128
  # @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
98
129
  # One or more key:value pairs, where the keys must be strings and the
99
- # values may be string, boolean or numeric type.
130
+ # values may be (array of) string, boolean or numeric type.
100
131
  # @param [optional Time] timestamp Optional timestamp for the event.
101
132
  #
102
133
  # @return [self] returns itself
@@ -120,15 +151,20 @@ module OpenTelemetry
120
151
  # can be recorded on a span.
121
152
  #
122
153
  # @param [Exception] exception The exception to be recorded
154
+ # @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
155
+ # attributes One or more key:value pairs, where the keys must be
156
+ # strings and the values may be (array of) string, boolean or numeric
157
+ # type.
123
158
  #
124
159
  # @return [void]
125
- def record_exception(exception)
126
- add_event('exception',
127
- attributes: {
128
- 'exception.type' => exception.class.to_s,
129
- 'exception.message' => exception.message,
130
- 'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
131
- })
160
+ def record_exception(exception, attributes: nil)
161
+ event_attributes = {
162
+ 'exception.type' => exception.class.to_s,
163
+ 'exception.message' => exception.message,
164
+ 'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
165
+ }
166
+ event_attributes.merge!(attributes) unless attributes.nil?
167
+ add_event('exception', attributes: event_attributes)
132
168
  end
133
169
 
134
170
  # Sets the Status to the Span
@@ -42,7 +42,7 @@ module OpenTelemetry
42
42
  @mutex.synchronize { @registry[Key.new(name, version)] ||= Tracer.new(name, version, self) }
43
43
  end
44
44
 
45
- # Attempts to stop all the activity for this {Tracer}. Calls
45
+ # Attempts to stop all the activity for this {TracerProvider}. Calls
46
46
  # SpanProcessor#shutdown for all registered SpanProcessors.
47
47
  #
48
48
  # This operation may block until all the Spans are processed. Must be
@@ -63,12 +63,26 @@ module OpenTelemetry
63
63
  end
64
64
  end
65
65
 
66
- # Adds a new SpanProcessor to this {Tracer}.
66
+ # Immediately export all spans that have not yet been exported for all the
67
+ # registered SpanProcessors.
68
+ #
69
+ # This method should only be called in cases where it is absolutely
70
+ # necessary, such as when using some FaaS providers that may suspend
71
+ # the process after an invocation, but before the `Processor` exports
72
+ # the completed spans.
67
73
  #
68
- # Any registered processor causes overhead, consider to use an
69
- # async/batch processor especially for span exporting, and export to
70
- # multiple backends using the
71
- # {io.opentelemetry.sdk.trace.export.MultiSpanExporter}.
74
+ # @param [optional Numeric] timeout An optional timeout in seconds.
75
+ # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
76
+ # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
77
+ def force_flush(timeout: nil)
78
+ @mutex.synchronize do
79
+ return Export::SUCCESS if @stopped
80
+
81
+ @active_span_processor.force_flush(timeout: timeout)
82
+ end
83
+ end
84
+
85
+ # Adds a new SpanProcessor to this {Tracer}.
72
86
  #
73
87
  # @param span_processor the new SpanProcessor to be added.
74
88
  def add_span_processor(span_processor)
@@ -78,7 +92,11 @@ module OpenTelemetry
78
92
  return
79
93
  end
80
94
  @registered_span_processors << span_processor
81
- @active_span_processor = MultiSpanProcessor.new(@registered_span_processors.dup)
95
+ @active_span_processor = if @registered_span_processors.size == 1
96
+ span_processor
97
+ else
98
+ MultiSpanProcessor.new(@registered_span_processors.dup)
99
+ end
82
100
  end
83
101
  end
84
102
  end
@@ -7,6 +7,6 @@
7
7
  module OpenTelemetry
8
8
  module SDK
9
9
  ## Current OpenTelemetry version
10
- VERSION = '0.12.1'
10
+ VERSION = '0.16.0'
11
11
  end
12
12
  end
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.12.1
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-13 00:00:00.000000000 Z
11
+ date: 2021-03-22 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.12.0
19
+ version: 0.16.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.12.0
26
+ version: 0.16.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.12.0
33
+ version: 0.16.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.12.0
40
+ version: 0.16.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: opentelemetry-exporter-jaeger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.16.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.16.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -201,10 +215,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
201
215
  licenses:
202
216
  - Apache-2.0
203
217
  metadata:
204
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.12.1/file.CHANGELOG.html
205
- source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/master/sdk
218
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.16.0/file.CHANGELOG.html
219
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/sdk
206
220
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
207
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.12.1
221
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.16.0
208
222
  post_install_message:
209
223
  rdoc_options: []
210
224
  require_paths: