Class: Instana::Trace
- Inherits:
-
Object
- Object
- Instana::Trace
- Defined in:
- lib/instana/tracing/trace.rb
Instance Attribute Summary collapse
-
#current_span ⇒ Object
readonly
The currently active span.
-
#id ⇒ Integer
readonly
The ID for this trace.
-
#spans ⇒ Set
readonly
The collection of ‘Span` for this trace.
Instance Method Summary collapse
-
#add_async_error(e, span) ⇒ Object
Log an error into an asynchronous span.
-
#add_async_info(kvs, span) ⇒ Object
Log info into an asynchronous span.
-
#add_error(e, span = nil) ⇒ Object
Log an error into the current span.
-
#add_info(kvs, span = nil) ⇒ Object
Add KVs to the current span.
-
#complete? ⇒ Boolean
Indicates if every span of this trace has completed.
-
#current_span_id ⇒ Integer
Get the ID of the current span for this trace.
-
#current_span_name ⇒ Object
Get the name of the current span.
-
#current_span_name?(name) ⇒ Boolean
Check if the current span has the name value of <name>.
-
#discard? ⇒ Boolean
For traces that have asynchronous spans, this method indicates whether we have hit the timeout on waiting for those async spans to close out.
-
#end_async_span(kvs = {}, span) ⇒ Object
End an asynchronous span.
-
#end_span(kvs = {}, end_time = ::Instana::Util.now_in_ms) ⇒ Object
(also: #finish)
Close out the current span and set the parent as the current span.
-
#has_async? ⇒ Boolean
Indicates whether this trace has any asynchronous spans.
-
#has_error? ⇒ Boolean
Searches the set of spans and indicates if there is an error logged in one of them.
-
#initialize(name, kvs = nil, incoming_context = {}, start_time = ::Instana::Util.now_in_ms) ⇒ Trace
constructor
Initializes a new instance of Trace.
-
#new_async_span(name, kvs = {}) ⇒ Object
Start a new asynchronous span.
-
#new_span(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) ⇒ Object
Start a new span as a child of @current_span.
-
#valid? ⇒ Boolean
Indicates whether all seems ok with this trace in it’s current state.
Constructor Details
#initialize(name, kvs = nil, incoming_context = {}, start_time = ::Instana::Util.now_in_ms) ⇒ Trace
Initializes a new instance of Trace
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 |
# File 'lib/instana/tracing/trace.rb', line 23 def initialize(name, kvs = nil, incoming_context = {}, start_time = ::Instana::Util.now_in_ms) # The collection of spans that make # up this trace. @spans = Set.new # Generate a random 64bit ID for this trace @id = ::Instana::Util.generate_id # Indicates the time when this trace was started. Used to timeout # traces that have asynchronous spans that never close out. @started_at = Time.now # Indicates if this trace has any asynchronous spans within it @has_async = false # This is a new trace so open the first span with the proper # root span IDs. @current_span = Span.new(name, @id, start_time: start_time) @current_span.(kvs) if kvs # Handle potential incoming context if !incoming_context || incoming_context.empty? # No incoming context. Set trace ID the same # as this first span. @current_span[:s] = @id else @id = incoming_context[:trace_id] @current_span[:t] = incoming_context[:trace_id] @current_span[:p] = incoming_context[:span_id] end @spans.add(@current_span) end |
Instance Attribute Details
#current_span ⇒ Object (readonly)
The currently active span
11 12 13 |
# File 'lib/instana/tracing/trace.rb', line 11 def current_span @current_span end |
#id ⇒ Integer (readonly)
Returns the ID for this trace.
4 5 6 |
# File 'lib/instana/tracing/trace.rb', line 4 def id @id end |
#spans ⇒ Set (readonly)
The collection of ‘Span` for this trace
8 9 10 |
# File 'lib/instana/tracing/trace.rb', line 8 def spans @spans end |
Instance Method Details
#add_async_error(e, span) ⇒ Object
Log an error into an asynchronous span
160 161 162 |
# File 'lib/instana/tracing/trace.rb', line 160 def add_async_error(e, span) span.add_error(e) end |
#add_async_info(kvs, span) ⇒ Object
Log info into an asynchronous span
150 151 152 |
# File 'lib/instana/tracing/trace.rb', line 150 def add_async_info(kvs, span) span.(kvs) end |
#add_error(e, span = nil) ⇒ Object
Log an error into the current span
98 99 100 101 102 103 104 |
# File 'lib/instana/tracing/trace.rb', line 98 def add_error(e, span = nil) # Return if we've already logged this exception and it # is just propogating up the spans. return if e && e.instance_variable_get(:@instana_logged) || @current_span.nil? span ||= @current_span span.add_error(e) end |
#add_info(kvs, span = nil) ⇒ Object
Add KVs to the current span
85 86 87 88 89 90 91 92 |
# File 'lib/instana/tracing/trace.rb', line 85 def add_info(kvs, span = nil) return unless @current_span span ||= @current_span # Pass on to the OT span interface which will properly # apply KVs based on span type span.(kvs) end |
#complete? ⇒ Boolean
Indicates if every span of this trace has completed. Useful when asynchronous spans potentially could run longer than the parent trace.
197 198 199 200 201 202 203 204 |
# File 'lib/instana/tracing/trace.rb', line 197 def complete? @spans.each do |span| if !span.duration return false end end true end |
#current_span_id ⇒ Integer
Get the ID of the current span for this trace. Used often to place in HTTP response headers.
234 235 236 |
# File 'lib/instana/tracing/trace.rb', line 234 def current_span_id @current_span.id end |
#current_span_name ⇒ Object
Get the name of the current span. Supports both registered spans and custom sdk spans.
241 242 243 |
# File 'lib/instana/tracing/trace.rb', line 241 def current_span_name @current_span.name end |
#current_span_name?(name) ⇒ Boolean
Check if the current span has the name value of <name>
251 252 253 |
# File 'lib/instana/tracing/trace.rb', line 251 def current_span_name?(name) @current_span.name == name end |
#discard? ⇒ Boolean
For traces that have asynchronous spans, this method indicates whether we have hit the timeout on waiting for those async spans to close out.
261 262 263 264 265 266 267 268 |
# File 'lib/instana/tracing/trace.rb', line 261 def discard? # If this trace has async spans that have not closed # out in 5 minutes, then it's discarded. if has_async? && (Time.now.to_i - @started_at.to_i) > 601 return true end false end |
#end_async_span(kvs = {}, span) ⇒ Object
End an asynchronous span
171 172 173 174 |
# File 'lib/instana/tracing/trace.rb', line 171 def end_async_span(kvs = {}, span) span.(kvs) unless kvs.empty? span.close end |
#end_span(kvs = {}, end_time = ::Instana::Util.now_in_ms) ⇒ Object Also known as: finish
Close out the current span and set the parent as the current span
111 112 113 114 115 116 117 |
# File 'lib/instana/tracing/trace.rb', line 111 def end_span(kvs = {}, end_time = ::Instana::Util.now_in_ms) return unless @current_span @current_span.close(end_time) add_info(kvs) if kvs && !kvs.empty? @current_span = @current_span.parent unless @current_span.is_root? end |
#has_async? ⇒ Boolean
Indicates whether this trace has any asynchronous spans.
208 209 210 |
# File 'lib/instana/tracing/trace.rb', line 208 def has_async? @has_async end |
#has_error? ⇒ Boolean
Searches the set of spans and indicates if there is an error logged in one of them.
218 219 220 221 222 223 224 225 226 227 |
# File 'lib/instana/tracing/trace.rb', line 218 def has_error? @spans.each do |s| if s.key?(:error) if s[:error] == true return true end end end false end |
#new_async_span(name, kvs = {}) ⇒ Object
Start a new asynchronous span
The major differentiator between this method and simple new_span is that this method doesn’t affect @current_trace and instead returns an ID pair that can be used later to close out the created async span.
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/instana/tracing/trace.rb', line 133 def new_async_span(name, kvs = {}) new_span = Span.new(name, @id, parent_id: @current_span.id) new_span.(kvs) unless kvs.empty? new_span.parent = @current_span new_span[:deferred] = @has_async = true # Add the new span to the span collection @spans.add(new_span) new_span end |
#new_span(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) ⇒ Object
Start a new span as a child of @current_span
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/instana/tracing/trace.rb', line 62 def new_span(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) return unless @current_span if child_of && child_of.is_a?(::Instana::Span) new_span = Span.new(name, @id, parent_id: child_of.id, start_time: start_time) new_span.parent = child_of new_span.baggage = child_of.baggage.dup else new_span = Span.new(name, @id, parent_id: @current_span.id, start_time: start_time) new_span.parent = @current_span new_span.baggage = @current_span.baggage.dup end new_span.(kvs) if kvs @spans.add(new_span) @current_span = new_span end |
#valid? ⇒ Boolean
Indicates whether all seems ok with this trace in it’s current state. Should be only called on finished traces.
185 186 187 188 189 190 191 192 |
# File 'lib/instana/tracing/trace.rb', line 185 def valid? @spans.each do |span| unless span.key?(:d) return false end end true end |