Class: Instana::Trace
- Inherits:
-
Object
- Object
- Instana::Trace
- Defined in:
- lib/instana/tracing/trace.rb
Instance Attribute Summary collapse
-
#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 ⇒ Span
Get the current span.
-
#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 = Time.now) ⇒ Object
Close out the current span and set the parent as the current span.
-
#finish(kvs = {}, end_time = Time.now) ⇒ Object
Closes out the final span in this trace and runs any finalizer steps required.
-
#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 = Time.now) ⇒ 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 = Time.now, 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 = Time.now) ⇒ Trace
Initializes a new instance of Trace
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 |
# File 'lib/instana/tracing/trace.rb', line 20 def initialize(name, kvs = nil, incoming_context = {}, start_time = Time.now) # 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
#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
177 178 179 |
# File 'lib/instana/tracing/trace.rb', line 177 def add_async_error(e, span) span.add_error(e) end |
#add_async_info(kvs, span) ⇒ Object
Log info into an asynchronous span
167 168 169 |
# File 'lib/instana/tracing/trace.rb', line 167 def add_async_info(kvs, span) span.(kvs) end |
#add_error(e, span = nil) ⇒ Object
Log an error into the current span
108 109 110 111 112 113 114 |
# File 'lib/instana/tracing/trace.rb', line 108 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) span ||= @current_span span.add_error(e) end |
#add_info(kvs, span = nil) ⇒ Object
Add KVs to the current span
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/instana/tracing/trace.rb', line 82 def add_info(kvs, span = nil) span ||= @current_span if span.custom? if span[:data][:sdk].key?(:custom) span[:data][:sdk][:custom].merge!(kvs) else span[:data][:sdk][:custom] = kvs end else kvs.each_pair do |k,v| if !span[:data].key?(k) span[:data][k] = v elsif v.is_a?(Hash) && span[:data][k].is_a?(Hash) span[:data][k].merge!(v) else span[:data][k] = v end end end end |
#complete? ⇒ Boolean
Indicates if every span of this trace has completed. Useful when asynchronous spans potentially could run longer than the parent trace.
214 215 216 217 218 219 220 221 |
# File 'lib/instana/tracing/trace.rb', line 214 def complete? @spans.each do |span| if !span.duration return false end end true end |
#current_span ⇒ Span
Get the current span.
250 251 252 |
# File 'lib/instana/tracing/trace.rb', line 250 def current_span @current_span end |
#current_span_id ⇒ Integer
Get the ID of the current span for this trace. Used often to place in HTTP response headers.
259 260 261 |
# File 'lib/instana/tracing/trace.rb', line 259 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.
266 267 268 |
# File 'lib/instana/tracing/trace.rb', line 266 def current_span_name @current_span.name end |
#current_span_name?(name) ⇒ Boolean
Check if the current span has the name value of <name>
276 277 278 |
# File 'lib/instana/tracing/trace.rb', line 276 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.
286 287 288 289 290 291 292 293 |
# File 'lib/instana/tracing/trace.rb', line 286 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
188 189 190 191 |
# File 'lib/instana/tracing/trace.rb', line 188 def end_async_span(kvs = {}, span) span.(kvs) unless kvs.empty? span.close end |
#end_span(kvs = {}, end_time = Time.now) ⇒ Object
Close out the current span and set the parent as the current span
121 122 123 124 125 |
# File 'lib/instana/tracing/trace.rb', line 121 def end_span(kvs = {}, end_time = Time.now) @current_span.close(end_time) add_info(kvs) if kvs && !kvs.empty? @current_span = @current_span.parent unless @current_span.is_root? end |
#finish(kvs = {}, end_time = Time.now) ⇒ Object
Closes out the final span in this trace and runs any finalizer steps required. This should be called only when on the root span to end the trace.
133 134 135 |
# File 'lib/instana/tracing/trace.rb', line 133 def finish(kvs = {}, end_time = Time.now) end_span(kvs, end_time) end |
#has_async? ⇒ Boolean
Indicates whether this trace has any asynchronous spans.
225 226 227 |
# File 'lib/instana/tracing/trace.rb', line 225 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.
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/instana/tracing/trace.rb', line 235 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.
150 151 152 153 154 155 156 157 158 159 |
# File 'lib/instana/tracing/trace.rb', line 150 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[:async] = @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 = Time.now, child_of = nil) ⇒ Object
Start a new span as a child of @current_span
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/instana/tracing/trace.rb', line 59 def new_span(name, kvs = nil, start_time = Time.now, 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.
202 203 204 205 206 207 208 209 |
# File 'lib/instana/tracing/trace.rb', line 202 def valid? @spans.each do |span| unless span.key?(:d) return false end end true end |