Class: Instana::Span
- Inherits:
-
OpenTelemetry::Trace::Span
- Object
- OpenTelemetry::Trace::Span
- Instana::Span
- Includes:
- SpanKind
- Defined in:
- lib/instana/trace/span.rb
Constant Summary
Constants included from SpanKind
Instana::SpanKind::CLIENT, Instana::SpanKind::CONSUMER, Instana::SpanKind::ENTRY, Instana::SpanKind::ENTRY_SPANS, Instana::SpanKind::EXIT, Instana::SpanKind::EXIT_SPANS, Instana::SpanKind::HTTP_SPANS, Instana::SpanKind::INTERMEDIATE, Instana::SpanKind::INTERNAL, Instana::SpanKind::PRODUCER, Instana::SpanKind::REGISTERED_SPANS, Instana::SpanKind::SERVER
Instance Attribute Summary collapse
-
#baggage ⇒ Object
Returns the value of attribute baggage.
-
#context ⇒ Instana::SpanContext
Retrieve the context of this span.
-
#is_root ⇒ Object
Returns the value of attribute is_root.
-
#parent ⇒ Object
Returns the value of attribute parent.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Hash accessor to the internal @attributes hash.
-
#[]=(key, value) ⇒ Object
Hash setter to the internal @attributes hash.
-
#add_attributes(attributes) ⇒ self
Add attributes.
-
#add_event(_name, attributes: nil, timestamp: nil) ⇒ self
Add an event to a Span.
-
#add_link(_link) ⇒ self
Add a link to a Span.
-
#add_stack(limit: 30, stack: Kernel.caller) ⇒ Object
Adds a backtrace to this span.
-
#close(end_time = ::Instana::Util.now_in_ms) ⇒ Span
Closes out the span.
-
#configure_custom(name) ⇒ Object
Configure this span to be a custom span per the SDK generic span type.
-
#custom? ⇒ Boolean
Indicates whether this span is a custom or registered Span.
-
#duration ⇒ Integer
Get the duration value for this Span.
-
#exit_span? ⇒ Boolean
Check to see if the current span indicates an exit from application code and into an external service.
-
#finish(end_time = ::Instana::Util.now_in_ms) ⇒ Object
Finish the Span Spec: OpenTracing API.
-
#get_baggage_item(key) ⇒ Object
Get a baggage item Spec: OpenTracing API.
-
#id ⇒ Integer
Retrieve the ID for this span.
-
#initialize(name, parent_ctx = nil, _context = nil, parent_span = nil, _kind = nil, parent_span_id = nil, _span_limits = nil, _span_processors = nil, attributes = nil, _links = nil, start_timestamp = ::Instana::Util.now_in_ms, _resource = nil, _instrumentation_scope = nil) ⇒ Span
constructor
rubocop:disable Lint/MissingSuper, Metrics/ParameterLists, Layout/LineLength.
- #inspect ⇒ Object
-
#key?(key) ⇒ Boolean
Hash key query to the internal @attributes hash.
-
#log(event = nil, timestamp = Time.now, **fields) ⇒ Object
Add a log entry to this span Spec: OpenTracing API.
-
#name ⇒ String
Get the name (operation) of this Span.
-
#name=(name) ⇒ Object
Set the name (operation) for this Span.
-
#operation_name=(name) ⇒ Object
Set the name of the operation Spec: OpenTracing API.
-
#parent_id ⇒ Integer
Retrieve the parent ID of this span.
-
#parent_id=(id) ⇒ Integer
Set the parent ID of this span.
-
#raw ⇒ Object
Get the raw @attributes hash that summarizes this span.
-
#record_exception(error) ⇒ Object
Log an error into the span.
-
#recording? ⇒ Boolean
Return the flag whether this span is recording events.
-
#set_attribute(key, value) ⇒ self
Set attribute.
-
#set_baggage_item(key, value) ⇒ Object
Set a baggage item on the span Spec: OpenTracing API.
-
#set_tag(key, value) ⇒ Object
Set a tag value on this span Spec: OpenTracing API.
-
#set_tags(tags) ⇒ Span
Helper method to add multiple tags to this span.
-
#status=(status) ⇒ void
Sets the Status to the Span.
-
#tags(key = nil) ⇒ Object
Retrieve the hash of tags for this span.
-
#trace_id ⇒ Integer
Retrieve the Trace ID for this span.
Constructor Details
#initialize(name, parent_ctx = nil, _context = nil, parent_span = nil, _kind = nil, parent_span_id = nil, _span_limits = nil, _span_processors = nil, attributes = nil, _links = nil, start_timestamp = ::Instana::Util.now_in_ms, _resource = nil, _instrumentation_scope = nil) ⇒ Span
rubocop:disable Lint/MissingSuper, Metrics/ParameterLists, Layout/LineLength
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/instana/trace/span.rb', line 12 def initialize(name, parent_ctx = nil, _context = nil, parent_span = nil, _kind = nil, parent_span_id = nil, _span_limits = nil, _span_processors = nil, attributes = nil, _links = nil, = ::Instana::Util.now_in_ms, _resource = nil, _instrumentation_scope = nil) # rubocop:disable Lint/MissingSuper, Metrics/ParameterLists, Layout/LineLength @attributes = {} @ended = false if parent_span.is_a?(::Instana::Span) @parent = parent_span end if parent_ctx.is_a?(::Instana::Span) @parent = parent_ctx parent_ctx = parent_ctx.context end if parent_ctx.is_a?(::Instana::SpanContext) @is_root = false # If we have a parent trace, link to it if parent_ctx.trace_id @attributes[:t] = parent_ctx.trace_id # Trace ID @attributes[:p] = parent_span_id || parent_ctx.span_id # Parent ID else @attributes[:t] = ::Instana::Trace.generate_trace_id end @attributes[:s] = ::Instana::Trace.generate_span_id # Span ID @baggage = parent_ctx.baggage.dup @level = parent_ctx.level else # No parent specified so we're starting a new Trace - this will be the root span @is_root = true @level = 1 id = ::Instana::Trace.generate_span_id @attributes[:t] = id # Trace ID @attributes[:s] = id # Span ID end @attributes[:data] = {} if ENV.key?('INSTANA_SERVICE_NAME') @attributes[:data][:service] = ENV['INSTANA_SERVICE_NAME'] end # Entity Source @attributes[:f] = ::Instana.agent.source # Start time @attributes[:ts] = if .is_a?(Time) ::Instana::Util.time_to_ms() else end # Check for custom tracing if REGISTERED_SPANS.include?(name&.to_sym) # Todo remove the safe & operator once all the tests are adapted to new init structure @attributes[:n] = name.to_sym else configure_custom(name) end (attributes) ::Instana.processor.on_start(self) # Attach a backtrace to all exit spans add_stack if ::Instana.config[:collect_backtraces] && exit_span? end |
Instance Attribute Details
#baggage ⇒ Object
Returns the value of attribute baggage.
10 11 12 |
# File 'lib/instana/trace/span.rb', line 10 def baggage @baggage end |
#context ⇒ Instana::SpanContext
Retrieve the context of this span.
184 185 186 |
# File 'lib/instana/trace/span.rb', line 184 def context @context end |
#is_root ⇒ Object
Returns the value of attribute is_root.
10 11 12 |
# File 'lib/instana/trace/span.rb', line 10 def is_root @is_root end |
#parent ⇒ Object
Returns the value of attribute parent.
10 11 12 |
# File 'lib/instana/trace/span.rb', line 10 def parent @parent end |
Instance Method Details
#[](key) ⇒ Object
Hash accessor to the internal @attributes hash
248 249 250 |
# File 'lib/instana/trace/span.rb', line 248 def [](key) @attributes[key.to_sym] end |
#[]=(key, value) ⇒ Object
Hash setter to the internal @attributes hash
254 255 256 |
# File 'lib/instana/trace/span.rb', line 254 def []=(key, value) @attributes[key.to_sym] = value end |
#add_attributes(attributes) ⇒ self
Add attributes
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
468 469 470 471 472 |
# File 'lib/instana/trace/span.rb', line 468 def add_attributes(attributes) @attributes ||= {} @attributes.merge!(attributes) self end |
#add_event(_name, attributes: nil, timestamp: nil) ⇒ self
Add an event to a Instana::Span.
Example:
span.add_event('event', attributes: {'eager' => true})
Note that the OpenTelemetry project documents certain “standard event names and keys” which have prescribed semantic meanings.
Todo Add the vent logic later
517 518 519 |
# File 'lib/instana/trace/span.rb', line 517 def add_event(_name, attributes: nil, timestamp: nil) # rubocop:disable Lint/UnusedMethodArgument self end |
#add_link(_link) ⇒ self
Add a link to a Instana::Span.
Adding links at span creation using the ‘links` option is preferred to calling add_link later, because head sampling decisions can only consider information present during span creation.
Example:
span.add_link(OpenTelemetry::Trace::Link.new(span_to_link_from.context))
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
Todo add link logic later
493 494 495 |
# File 'lib/instana/trace/span.rb', line 493 def add_link(_link) self end |
#add_stack(limit: 30, stack: Kernel.caller) ⇒ Object
Adds a backtrace to this span
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/instana/trace/span.rb', line 80 def add_stack(limit: 30, stack: Kernel.caller) cleaner = ::Instana.config[:backtrace_cleaner] stack = cleaner.call(stack) if cleaner @attributes[:stack] = stack .map do |call| file, line, *method = call.split(':') { c: file, n: line, m: method.join(' ') } end.take(limit > 40 ? 40 : limit) end |
#close(end_time = ::Instana::Util.now_in_ms) ⇒ Span
Closes out the span. This difference between this and the finish method tells us how the tracing is being performed (with OpenTracing or Instana default)
161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/instana/trace/span.rb', line 161 def close(end_time = ::Instana::Util.now_in_ms) result = ::Instana::SpanFiltering.filter_span(self) if end_time.is_a?(Time) end_time = ::Instana::Util.time_to_ms(end_time) end @attributes[:d] = end_time - @attributes[:ts] @ended = true if result.nil? # Add this span to the queue for reporting ::Instana.processor.on_finish(self) end self end |
#configure_custom(name) ⇒ Object
Configure this span to be a custom span per the SDK generic span type.
Default to an intermediate kind span. Can be overridden by setting a span.kind tag.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/instana/trace/span.rb', line 138 def configure_custom(name) @attributes[:n] = :sdk @attributes[:data] = { :sdk => { :name => name&.to_sym } } # Todo remove safe operator once other tests adapt to new init structure @attributes[:data][:sdk][:custom] = { :tags => {}, :logs => {} } if @is_root # For custom root spans (via SDK or opentracing), default to entry type @attributes[:k] = 1 @attributes[:data][:sdk][:type] = :entry else @attributes[:k] = 3 @attributes[:data][:sdk][:type] = :intermediate end self end |
#custom? ⇒ Boolean
Indicates whether this span is a custom or registered Span
271 272 273 |
# File 'lib/instana/trace/span.rb', line 271 def custom? @attributes[:n] == :sdk end |
#duration ⇒ Integer
Get the duration value for this Span
242 243 244 |
# File 'lib/instana/trace/span.rb', line 242 def duration @attributes[:d] end |
#exit_span? ⇒ Boolean
Check to see if the current span indicates an exit from application code and into an external service
281 282 283 |
# File 'lib/instana/trace/span.rb', line 281 def exit_span? EXIT_SPANS.include?(@attributes[:n]) end |
#finish(end_time = ::Instana::Util.now_in_ms) ⇒ Object
Finish the Instana::Span Spec: OpenTracing API
419 420 421 422 423 |
# File 'lib/instana/trace/span.rb', line 419 def finish(end_time = ::Instana::Util.now_in_ms) close(end_time) ::Instana.tracer.current_span = ::Instana.tracer.current_span&.parent || nil self end |
#get_baggage_item(key) ⇒ Object
Get a baggage item Spec: OpenTracing API
380 381 382 |
# File 'lib/instana/trace/span.rb', line 380 def get_baggage_item(key) @baggage[key] end |
#id ⇒ Integer
Retrieve the ID for this span
191 192 193 |
# File 'lib/instana/trace/span.rb', line 191 def id @attributes[:s] end |
#inspect ⇒ Object
275 276 277 |
# File 'lib/instana/trace/span.rb', line 275 def inspect @attributes.inspect end |
#key?(key) ⇒ Boolean
Hash key query to the internal @attributes hash
260 261 262 |
# File 'lib/instana/trace/span.rb', line 260 def key?(key) @attributes.key?(key.to_sym) end |
#log(event = nil, timestamp = Time.now, **fields) ⇒ Object
Add a log entry to this span Spec: OpenTracing API
402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/instana/trace/span.rb', line 402 def log(event = nil, = Time.now, **fields) ts = ::Instana::Util.time_to_ms().to_s if custom? @attributes[:data][:sdk][:custom][:logs][ts] = fields @attributes[:data][:sdk][:custom][:logs][ts][:event] = event else (:log => fields) end rescue StandardError => e Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" } end |
#name ⇒ String
Get the name (operation) of this Span
219 220 221 222 223 224 225 |
# File 'lib/instana/trace/span.rb', line 219 def name if custom? @attributes[:data][:sdk][:name] else @attributes[:n] end end |
#name=(name) ⇒ Object
Set the name (operation) for this Span
231 232 233 234 235 236 237 |
# File 'lib/instana/trace/span.rb', line 231 def name=(name) if custom? @attributes[:data][:sdk][:name] = name else @attributes[:n] = name end end |
#operation_name=(name) ⇒ Object
Set the name of the operation Spec: OpenTracing API
294 295 296 |
# File 'lib/instana/trace/span.rb', line 294 def operation_name=(name) @attributes[:n] = name end |
#parent_id ⇒ Integer
Retrieve the parent ID of this span
205 206 207 |
# File 'lib/instana/trace/span.rb', line 205 def parent_id @attributes[:p] end |
#parent_id=(id) ⇒ Integer
Set the parent ID of this span
212 213 214 |
# File 'lib/instana/trace/span.rb', line 212 def parent_id=(id) @attributes[:p] = id end |
#raw ⇒ Object
Get the raw @attributes hash that summarizes this span
266 267 268 |
# File 'lib/instana/trace/span.rb', line 266 def raw @attributes end |
#record_exception(error) ⇒ Object
Log an error into the span
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/instana/trace/span.rb', line 100 def record_exception(error) @attributes[:error] = true @attributes[:ec] = if @attributes.key?(:ec) @attributes[:ec] + 1 else 1 end # If a valid exception has been passed in, log the information about it # In case of just logging an error for things such as HTTP client 5xx # responses, an exception/backtrace may not exist. if error if error.backtrace.is_a?(Array) add_stack(stack: error.backtrace) end if HTTP_SPANS.include?(@attributes[:n]) (:http => { :error => "#{error.class}: #{error.message}" }) elsif @attributes[:n] == :activerecord @attributes[:data][:activerecord][:error] = error. else log(:error, Time.now, message: error., parameters: error.class.to_s) end error.instance_variable_set(:@instana_logged, true) end self end |
#recording? ⇒ Boolean
Return the flag whether this span is recording events
430 431 432 |
# File 'lib/instana/trace/span.rb', line 430 def recording? !@ended end |
#set_attribute(key, value) ⇒ self
Set attribute
Note that the OpenTelemetry project documents certain “standard attributes” that have prescribed semantic meanings.
448 449 450 451 452 |
# File 'lib/instana/trace/span.rb', line 448 def set_attribute(key, value) @attributes ||= {} @attributes[key] = value self end |
#set_baggage_item(key, value) ⇒ Object
Set a baggage item on the span Spec: OpenTracing API
Todo Evalute if baggage is used anywhere in instana
361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/instana/trace/span.rb', line 361 def set_baggage_item(key, value) @baggage ||= {} @baggage[key] = value # Init/Update the SpanContext item if @context @context.baggage = @baggage else @context ||= ::Instana::SpanContext.new(trace_id: @attributes[:t], span_id: @attributes[:s], level: @level, baggage: @baggage) end self end |
#set_tag(key, value) ⇒ Object
Set a tag value on this span Spec: OpenTracing API
a String, Numeric, or Boolean it will be encoded with to_s
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/instana/trace/span.rb', line 305 def set_tag(key, value) unless [Symbol, String].include?(key.class) key = key.to_s end # If <value> is not a Symbol, String, Array, Hash or Numeric - convert to string if ![Symbol, String, Array, TrueClass, FalseClass, Hash].include?(value.class) && !value.is_a?(Numeric) value = value.to_s end if custom? @attributes[:data][:sdk][:custom] ||= {} @attributes[:data][:sdk][:custom][:tags] ||= {} @attributes[:data][:sdk][:custom][:tags][key] = value if key.to_sym == :'span.kind' case value.to_sym when ENTRY, SERVER, CONSUMER @attributes[:data][:sdk][:type] = ENTRY @attributes[:k] = 1 when EXIT, CLIENT, PRODUCER @attributes[:data][:sdk][:type] = EXIT @attributes[:k] = 2 else @attributes[:data][:sdk][:type] = INTERMEDIATE @attributes[:k] = 3 end end elsif value.is_a?(Hash) && @attributes[:data][key].is_a?(Hash) @attributes[:data][key].merge!(value) else @attributes[:data][key] = value end self end |
#set_tags(tags) ⇒ Span
Helper method to add multiple tags to this span
346 347 348 349 350 351 352 353 |
# File 'lib/instana/trace/span.rb', line 346 def () # rubocop:disable Naming return unless .is_a?(Hash) .each do |k, v| set_tag(k, v) end self end |
#status=(status) ⇒ void
This method returns an undefined value.
Sets the Status to the Span
If used, this will override the default Span status. Default status is unset.
Only the value of the last call will be recorded, and implementations are free to ignore previous calls.
532 |
# File 'lib/instana/trace/span.rb', line 532 def status=(status); end |
#tags(key = nil) ⇒ Object
Retrieve the hash of tags for this span
386 387 388 389 390 391 392 393 |
# File 'lib/instana/trace/span.rb', line 386 def (key = nil) = if custom? @attributes[:data][:sdk][:custom][:tags] else @attributes[:data] end key ? [key] : end |
#trace_id ⇒ Integer
Retrieve the Trace ID for this span
198 199 200 |
# File 'lib/instana/trace/span.rb', line 198 def trace_id @attributes[:t] end |