lib/opentelemetry/sdk/trace/span.rb in opentelemetry-sdk-1.0.0.rc1 vs lib/opentelemetry/sdk/trace/span.rb in opentelemetry-sdk-1.0.0.rc2
- old
+ new
@@ -8,17 +8,17 @@
module SDK
module Trace
# Implementation of {OpenTelemetry::Trace::Span} that records trace events.
#
# This implementation includes reader methods intended to allow access to
- # internal state by SpanProcessors (see {NoopSpanProcessor} for the interface).
+ # internal state by {SpanProcessor}s.
# Instrumentation should use the API provided by {OpenTelemetry::Trace::Span}
# and should consider {Span} to be write-only.
#
# rubocop:disable Metrics/ClassLength
class Span < OpenTelemetry::Trace::Span
- DEFAULT_STATUS = OpenTelemetry::Trace::Status.new(OpenTelemetry::Trace::Status::UNSET)
+ DEFAULT_STATUS = OpenTelemetry::Trace::Status.unset
EMPTY_ATTRIBUTES = {}.freeze
private_constant :DEFAULT_STATUS, :EMPTY_ATTRIBUTES
# The following readers are intended for the use of SpanProcessors and
@@ -157,32 +157,35 @@
# @return [void]
def record_exception(exception, attributes: nil)
event_attributes = {
'exception.type' => exception.class.to_s,
'exception.message' => exception.message,
- 'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
+ 'exception.stacktrace' => exception.full_message(highlight: false, order: :top).encode('UTF-8', invalid: :replace, undef: :replace, replace: '�')
}
event_attributes.merge!(attributes) unless attributes.nil?
add_event('exception', attributes: event_attributes)
end
# Sets the Status to the Span
#
- # If used, this will override the default Span status. Default is OK.
+ # If used, this will override the default Span status. Default has code = Status::UNSET.
#
- # Only the value of the last call will be recorded, and implementations
- # are free to ignore previous calls.
+ # An attempt to set the status with code == Status::UNSET is ignored.
+ # If the status is set with code == Status::OK, any further attempt to set the status
+ # is ignored.
#
# @param [Status] status The new status, which overrides the default Span
- # status, which is OK.
+ # status, which has code = Status::UNSET.
#
# @return [void]
def status=(status)
+ return if status.code == OpenTelemetry::Trace::Status::UNSET
+
@mutex.synchronize do
if @ended
OpenTelemetry.logger.warn('Calling status= on an ended Span.')
- else
+ elsif @status.code != OpenTelemetry::Trace::Status::OK
@status = status
end
end
end
@@ -233,11 +236,11 @@
@end_timestamp = wall_clock(end_timestamp)
@attributes = validated_attributes(@attributes).freeze
@events.freeze
@ended = true
end
- @span_processor.on_finish(self)
+ @span_processors.each { |processor| processor.on_finish(self) }
self
end
# @api private
#
@@ -271,18 +274,18 @@
context.tracestate
)
end
# @api private
- def initialize(context, parent_context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
+ 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
super(span_context: context)
@mutex = Mutex.new
@name = name
@kind = kind
@parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
- @trace_config = trace_config
- @span_processor = span_processor
+ @span_limits = span_limits
+ @span_processors = span_processors
@resource = resource
@instrumentation_library = instrumentation_library
@ended = false
@status = DEFAULT_STATUS
@total_recorded_events = 0
@@ -291,12 +294,12 @@
@start_timestamp = wall_clock(start_timestamp)
@end_timestamp = nil
@attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
trim_span_attributes(@attributes)
@events = nil
- @links = trim_links(links, trace_config.max_links_count, trace_config.max_attributes_per_link)
- @span_processor.on_start(self, parent_context)
+ @links = trim_links(links, span_limits.link_count_limit, span_limits.attribute_per_link_count_limit)
+ @span_processors.each { |processor| processor.on_start(self, parent_context) }
end
# TODO: Java implementation overrides finalize to log if a span isn't finished.
private
@@ -308,63 +311,63 @@
end
def trim_span_attributes(attrs)
return if attrs.nil?
- excess = attrs.size - @trace_config.max_attributes_count
+ excess = attrs.size - @span_limits.attribute_count_limit
excess.times { attrs.shift } if excess.positive?
truncate_attribute_values(attrs)
nil
end
def truncate_attribute_values(attrs)
return EMPTY_ATTRIBUTES if attrs.nil?
- max_attributes_length = @trace_config.max_attributes_length
- attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value, max_attributes_length) } if max_attributes_length
+ attribute_length_limit = @span_limits.attribute_length_limit
+ attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value, attribute_length_limit) } if attribute_length_limit
attrs
end
- def trim_links(links, max_links_count, max_attributes_per_link) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
+ def trim_links(links, link_count_limit, attribute_per_link_count_limit) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# Fast path (likely) common cases.
return nil if links.nil?
- if links.size <= max_links_count &&
- links.all? { |link| link.attributes.size <= max_attributes_per_link && Internal.valid_attributes?(name, 'link', link.attributes) }
+ if links.size <= link_count_limit &&
+ links.all? { |link| link.attributes.size <= attribute_per_link_count_limit && Internal.valid_attributes?(name, 'link', link.attributes) }
return links.frozen? ? links : links.clone.freeze
end
# Slow path: trim attributes for each Link.
- links.last(max_links_count).map! do |link|
+ links.last(link_count_limit).map! do |link|
attrs = Hash[link.attributes] # link.attributes is frozen, so we need an unfrozen copy to adjust.
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
- excess = attrs.size - max_attributes_per_link
+ excess = attrs.size - attribute_per_link_count_limit
excess.times { attrs.shift } if excess.positive?
OpenTelemetry::Trace::Link.new(link.span_context, attrs)
end.freeze
end
def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
- max_events_count = @trace_config.max_events_count
- max_attributes_per_event = @trace_config.max_attributes_per_event
+ event_count_limit = @span_limits.event_count_limit
+ attribute_per_event_count_limit = @span_limits.attribute_per_event_count_limit
valid_attributes = Internal.valid_attributes?(name, 'event', event.attributes)
# Fast path (likely) common case.
- if events.size < max_events_count &&
- event.attributes.size <= max_attributes_per_event &&
+ if events.size < event_count_limit &&
+ event.attributes.size <= attribute_per_event_count_limit &&
valid_attributes
return events << event
end
# Slow path.
- excess = events.size + 1 - max_events_count
+ excess = events.size + 1 - event_count_limit
events.shift(excess) if excess.positive?
- excess = event.attributes.size - max_attributes_per_event
+ excess = event.attributes.size - attribute_per_event_count_limit
if excess.positive? || !valid_attributes
attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
- excess = attrs.size - max_attributes_per_event
+ excess = attrs.size - attribute_per_event_count_limit
excess.times { attrs.shift } if excess.positive?
event = Event.new(event.name, attrs.freeze, event.timestamp)
end
events << event
end