Class: Instana::Tracer
- Inherits:
-
Object
- Object
- Instana::Tracer
- Extended by:
- ThreadLocal
- Defined in:
- lib/instana/tracer.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#clear! ⇒ Object
Used in the test suite, this resets the tracer to non-tracing state.
-
#context ⇒ SpanContext
Retrieve the current context of the tracer.
-
#extract(format, carrier) ⇒ SpanContext
Extract a span from a carrier.
-
#inject(span_context, format, carrier) ⇒ Object
Inject a span into the given carrier.
-
#log_async_entry(name, kvs) ⇒ Hash
Starts a new asynchronous span on the current trace.
-
#log_async_error(e, span) ⇒ Object
Add an error to an asynchronous span.
-
#log_async_exit(_name, kvs, span) ⇒ Object
Closes out an asynchronous span.
-
#log_async_info(kvs, span) ⇒ Object
Add info to an asynchronous span.
-
#log_end(name, kvs = {}, end_time = ::Instana::Util.now_in_ms) ⇒ Object
Closes out the current span in the current trace and queues the trace for reporting.
-
#log_entry(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) ⇒ Object
Will establish a new span as a child of the current span in an existing trace.
-
#log_error(e) ⇒ Object
Add an error to the current span.
-
#log_exit(name, kvs = {}) ⇒ Object
Closes out the current span.
-
#log_info(kvs) ⇒ Object
Add info to the current span.
-
#log_start_or_continue(name, kvs = {}, incoming_context = nil) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
-
#span_id ⇒ Object
Returns the current [Span] ID for the active trace (if there is one), otherwise nil.
-
#span_id_header ⇒ String
Take the current span_id and convert it to a header compatible formate.
-
#start_or_continue_trace(name, kvs = {}, incoming_context = nil, &block) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
-
#start_span(operation_name, child_of: nil, start_time: ::Instana::Util.now_in_ms, tags: nil) ⇒ Span
Start a new span.
-
#trace(name, kvs = {}, &block) ⇒ Object
Trace a block of code within the context of the exiting trace.
-
#trace_id ⇒ Object
Returns the trace ID for the active trace (if there is one), otherwise nil.
-
#trace_id_header ⇒ String
Take the current trace_id and convert it to a header compatible format.
-
#tracing? ⇒ Boolean
Indicates if we’re are currently in the process of collecting a trace.
-
#tracing_span?(name) ⇒ Boolean
Indicates if we’re tracing and the current span name matches <name>.
Methods included from ThreadLocal
Class Method Details
Instance Method Details
#clear! ⇒ Object
Used in the test suite, this resets the tracer to non-tracing state.
388 389 390 |
# File 'lib/instana/tracer.rb', line 388 def clear! self.current_span = nil end |
#context ⇒ SpanContext
Retrieve the current context of the tracer.
339 340 341 342 |
# File 'lib/instana/tracer.rb', line 339 def context return unless self.current_span self.current_span.context end |
#extract(format, carrier) ⇒ SpanContext
Extract a span from a carrier
291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/instana/tracer.rb', line 291 def extract(format, carrier) case format when OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY ::Instana.logger.debug 'Unsupported extract format' when OpenTracing::FORMAT_RACK ::Instana::SpanContext.new(::Instana::Util.header_to_id(carrier['HTTP_X_INSTANA_T']), ::Instana::Util.header_to_id(carrier['HTTP_X_INSTANA_S'])) else ::Instana.logger.debug 'Unknown inject format' nil end end |
#inject(span_context, format, carrier) ⇒ Object
Inject a span into the given carrier
272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/instana/tracer.rb', line 272 def inject(span_context, format, carrier) case format when OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY ::Instana.logger.debug 'Unsupported inject format' when OpenTracing::FORMAT_RACK carrier['X-Instana-T'] = ::Instana::Util.id_to_header(span_context.trace_id) carrier['X-Instana-S'] = ::Instana::Util.id_to_header(span_context.span_id) else ::Instana.logger.debug 'Unknown inject format' end end |
#log_async_entry(name, kvs) ⇒ Hash
Starts a new asynchronous span on the current trace.
206 207 208 209 210 211 212 |
# File 'lib/instana/tracer.rb', line 206 def log_async_entry(name, kvs) return unless self.current_span new_span = Span.new(name, parent_ctx: self.current_span) new_span.(kvs) unless kvs.empty? new_span end |
#log_async_error(e, span) ⇒ Object
Add an error to an asynchronous span
228 229 230 |
# File 'lib/instana/tracer.rb', line 228 def log_async_error(e, span) span.add_error(e) end |
#log_async_exit(_name, kvs, span) ⇒ Object
Closes out an asynchronous span
238 239 240 241 |
# File 'lib/instana/tracer.rb', line 238 def log_async_exit(_name, kvs, span) span.(kvs) unless kvs.empty? span.close end |
#log_async_info(kvs, span) ⇒ Object
Add info to an asynchronous span
219 220 221 |
# File 'lib/instana/tracer.rb', line 219 def log_async_info(kvs, span) span.(kvs) end |
#log_end(name, kvs = {}, end_time = ::Instana::Util.now_in_ms) ⇒ Object
‘name` isn’t really required but helps keep sanity that
Closes out the current span in the current trace and queues the trace for reporting
we’re ending the span that we really want to close out.
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/instana/tracer.rb', line 179 def log_end(name, kvs = {}, end_time = ::Instana::Util.now_in_ms) return unless self.current_span if ENV.key?('INSTANA_DEBUG') || ENV.key?('INSTANA_TEST') unless self.current_span.name == name ::Instana.logger.debug "Span mismatch: Attempt to end #{name} span but #{self.current_span.name} is active." end end self.current_span.(kvs) self.current_span.close(end_time) self.current_span = nil end |
#log_entry(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) ⇒ Object
Will establish a new span as a child of the current span in an existing trace
113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/instana/tracer.rb', line 113 def log_entry(name, kvs = nil, start_time = ::Instana::Util.now_in_ms, child_of = nil) return unless self.current_span || child_of if child_of && (child_of.is_a?(::Instana::Span) || child_of.is_a?(::Instana::SpanContext)) new_span = Span.new(name, parent_ctx: child_of, start_time: start_time) else new_span = Span.new(name, parent_ctx: self.current_span, start_time: start_time) end new_span.(kvs) if kvs self.current_span = new_span end |
#log_error(e) ⇒ Object
Add an error to the current span
138 139 140 141 |
# File 'lib/instana/tracer.rb', line 138 def log_error(e) return unless self.current_span self.current_span.add_error(e) end |
#log_exit(name, kvs = {}) ⇒ Object
‘name` isn’t really required but helps keep sanity that
Closes out the current span
we’re closing out the span that we really want to close out.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/instana/tracer.rb', line 151 def log_exit(name, kvs = {}) return unless self.current_span if ENV.key?('INSTANA_DEBUG') || ENV.key?('INSTANA_TEST') unless self.current_span.name == name ::Instana.logger.debug "Span mismatch: Attempt to exit #{name} span but #{self.current_span.name} is active." end end self.current_span.(kvs) self.current_span.close if self.current_span.parent self.current_span = self.current_span.parent else self.current_span = nil end end |
#log_info(kvs) ⇒ Object
Add info to the current span
129 130 131 132 |
# File 'lib/instana/tracer.rb', line 129 def log_info(kvs) return unless self.current_span self.current_span.(kvs) end |
#log_start_or_continue(name, kvs = {}, incoming_context = nil) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/instana/tracer.rb', line 83 def log_start_or_continue(name, kvs = {}, incoming_context = nil) return if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled] ::Instana.logger.debug { "#{__method__} passed a block. Use `start_or_continue` instead!" } if block_given? # Handle the potential variations on `incoming_context` if incoming_context if incoming_context.is_a?(Hash) if !incoming_context.empty? parent_context = SpanContext.new(incoming_context[:trace_id], incoming_context[:span_id], incoming_context[:level]) end else parent_context = incoming_context end end if parent_context self.current_span = Span.new(name, parent_ctx: parent_context) else self.current_span = Span.new(name) end self.current_span.(kvs) unless kvs.empty? self.current_span end |
#span_id ⇒ Object
Returns the current [Span] ID for the active trace (if there is one), otherwise nil.
381 382 383 384 |
# File 'lib/instana/tracer.rb', line 381 def span_id self.current_span ? self.current_span.span_id : nil ::Instana.logger.debug("tracer.span_id will deprecated in a future version.") end |
#span_id_header ⇒ String
Take the current span_id and convert it to a header compatible formate.
362 363 364 365 366 367 368 |
# File 'lib/instana/tracer.rb', line 362 def span_id_header if self.current_span self.current_span.context.span_id_header else "" end end |
#start_or_continue_trace(name, kvs = {}, incoming_context = nil, &block) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
37 38 39 40 41 42 43 44 45 |
# File 'lib/instana/tracer.rb', line 37 def start_or_continue_trace(name, kvs = {}, incoming_context = nil, &block) log_start_or_continue(name, kvs, incoming_context) yield rescue Exception => e log_error(e) raise ensure log_end(name) end |
#start_span(operation_name, child_of: nil, start_time: ::Instana::Util.now_in_ms, tags: nil) ⇒ Span
Start a new span
256 257 258 259 260 261 262 263 264 |
# File 'lib/instana/tracer.rb', line 256 def start_span(operation_name, child_of: nil, start_time: ::Instana::Util.now_in_ms, tags: nil) if child_of && (child_of.is_a?(::Instana::Span) || child_of.is_a?(::Instana::SpanContext)) new_span = Span.new(operation_name, parent_ctx: child_of, start_time: start_time) else new_span = Span.new(operation_name, start_time: start_time) end new_span.() if new_span end |
#trace(name, kvs = {}, &block) ⇒ Object
Trace a block of code within the context of the exiting trace
Example usage:
::Instana.tracer.trace(:dbwork, { :db_name => @db.name }) do
@db.select(1)
end
58 59 60 61 62 63 64 65 66 |
# File 'lib/instana/tracer.rb', line 58 def trace(name, kvs = {}, &block) log_entry(name, kvs) yield rescue Exception => e log_error(e) raise ensure log_exit(name) end |
#trace_id ⇒ Object
Returns the trace ID for the active trace (if there is one), otherwise nil.
373 374 375 376 |
# File 'lib/instana/tracer.rb', line 373 def trace_id self.current_span ? self.current_span.id : nil ::Instana.logger.debug("tracer.trace_id will deprecated in a future version.") end |
#trace_id_header ⇒ String
Take the current trace_id and convert it to a header compatible format.
349 350 351 352 353 354 355 |
# File 'lib/instana/tracer.rb', line 349 def trace_id_header if self.current_span self.current_span.context.trace_id_header else "" end end |
#tracing? ⇒ Boolean
Indicates if we’re are currently in the process of collecting a trace. This is false when the host agent isn available.
314 315 316 317 318 319 |
# File 'lib/instana/tracer.rb', line 314 def tracing? # The non-nil value of this instance variable # indicates if we are currently tracing # in this thread or not. self.current_span ? true : false end |
#tracing_span?(name) ⇒ Boolean
Indicates if we’re tracing and the current span name matches <name>
328 329 330 331 332 333 |
# File 'lib/instana/tracer.rb', line 328 def tracing_span?(name) if self.current_span return self.current_span.name == name end false end |