Class: Instana::Tracer
- Inherits:
-
Object
- Object
- Instana::Tracer
- Extended by:
- ThreadLocal
- Defined in:
- lib/instana/tracer.rb
Instance Method Summary collapse
-
#context ⇒ Object
Retrieve the current context of the tracer.
-
#header_to_id(header_id) ⇒ Integer
Convert a received header value into a valid ID.
-
#id_to_header(id) ⇒ String
Convert an ID to a value appropriate to pass in a header.
-
#log_async_entry(name, kvs, incoming_context = nil) ⇒ Hash
Starts a new asynchronous span on the current trace.
-
#log_async_error(e, ids) ⇒ Object
Add an error to an asynchronous span.
-
#log_async_exit(name, kvs, ids) ⇒ Object
Closes out an asynchronous span.
-
#log_async_info(kvs, ids) ⇒ Object
Add info to an asynchronous span.
-
#log_end(name, kvs = {}) ⇒ Object
Closes out the current span in the current trace and queues the trace for reporting.
-
#log_entry(name, kvs = {}) ⇒ 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 = {}) ⇒ 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 = {}, &block) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
-
#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.
Methods included from ThreadLocal
Instance Method Details
#context ⇒ Object
Retrieve the current context of the tracer.
251 252 253 254 |
# File 'lib/instana/tracer.rb', line 251 def context { :trace_id => self.current_trace.id, :span_id => self.current_trace.current_span_id } end |
#header_to_id(header_id) ⇒ Integer
Convert a received header value into a valid ID
297 298 299 300 301 302 303 304 305 306 |
# File 'lib/instana/tracer.rb', line 297 def header_to_id(header_id) if !header_id.is_a?(String) Instana.logger.debug "header_to_id received a #{header_id.class}: returning 0" return 0 end [header_id].pack("H*").unpack("q>")[0] rescue => e Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" Instana.logger.debug e.backtrace.join("\r\n") end |
#id_to_header(id) ⇒ String
Convert an ID to a value appropriate to pass in a header.
280 281 282 283 284 285 286 287 288 289 |
# File 'lib/instana/tracer.rb', line 280 def id_to_header(id) unless id.is_a?(Integer) || id.is_a?(String) Instana.logger.debug "id_to_header received a #{id.class}: returning empty string" return String.new end [id.to_i].pack('q>').unpack('H*')[0] rescue => e Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" Instana.logger.debug e.backtrace.join("\r\n") end |
#log_async_entry(name, kvs, incoming_context = nil) ⇒ Hash
Starts a new asynchronous span on the current trace.
159 160 161 162 |
# File 'lib/instana/tracer.rb', line 159 def log_async_entry(name, kvs, incoming_context = nil) return unless tracing? self.current_trace.new_async_span(name, kvs) end |
#log_async_error(e, ids) ⇒ Object
Add an error to an asynchronous span
192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/instana/tracer.rb', line 192 def log_async_error(e, ids) # Asynchronous spans can persist longer than the parent # trace. With the trace ID, we check the current trace # but otherwise, we search staged traces. if tracing? && self.current_trace.id == ids[:trace_id] self.current_trace.add_async_error(e, ids) else trace = ::Instana.processor.staged_trace(ids) trace.add_async_error(e, ids) end end |
#log_async_exit(name, kvs, ids) ⇒ Object
Closes out an asynchronous span
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/instana/tracer.rb', line 213 def log_async_exit(name, kvs, ids) # An asynchronous span can end after the current trace has # already completed so we make sure that we end the span # on the right trace. if tracing? && (self.current_trace.id == ids[:trace_id]) self.current_trace.end_async_span(kvs, ids) else # Different trace from current so find the staged trace # and close out the span on it. trace = ::Instana.processor.staged_trace(ids) if trace trace.end_async_span(kvs, ids) else ::Instana.logger.debug "log_async_exit: Couldn't find staged trace. #{ids.inspect}" end end end |
#log_async_info(kvs, ids) ⇒ Object
Add info to an asynchronous span
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/instana/tracer.rb', line 172 def log_async_info(kvs, ids) # Asynchronous spans can persist longer than the parent # trace. With the trace ID, we check the current trace # but otherwise, we search staged traces. if tracing? && self.current_trace.id == ids[:trace_id] self.current_trace.add_async_info(kvs, ids) else trace = ::Instana.processor.staged_trace(ids) trace.add_async_info(kvs, ids) end end |
#log_end(name, kvs = {}) ⇒ 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.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/instana/tracer.rb', line 129 def log_end(name, kvs = {}) return unless tracing? self.current_trace.finish(kvs) if !self.current_trace.has_async? || (self.current_trace.has_async? && self.current_trace.complete?) Instana.processor.add(self.current_trace) else # This trace still has outstanding/uncompleted asynchronous spans. # Put it in the staging queue until the async span closes out or # 5 minutes has passed. Whichever comes first. Instana.processor.stage(self.current_trace) end self.current_trace = nil end |
#log_entry(name, kvs = {}) ⇒ Object
Will establish a new span as a child of the current span in an existing trace
84 85 86 87 |
# File 'lib/instana/tracer.rb', line 84 def log_entry(name, kvs = {}) return unless tracing? self.current_trace.new_span(name, kvs) end |
#log_error(e) ⇒ Object
Add an error to the current span
102 103 104 105 |
# File 'lib/instana/tracer.rb', line 102 def log_error(e) return unless tracing? self.current_trace.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.
115 116 117 118 |
# File 'lib/instana/tracer.rb', line 115 def log_exit(name, kvs = {}) return unless tracing? self.current_trace.end_span(kvs) end |
#log_info(kvs) ⇒ Object
Add info to the current span
93 94 95 96 |
# File 'lib/instana/tracer.rb', line 93 def log_info(kvs) return unless tracing? self.current_trace.add_info(kvs) end |
#log_start_or_continue(name, kvs = {}, incoming_context = {}) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
73 74 75 76 |
# File 'lib/instana/tracer.rb', line 73 def log_start_or_continue(name, kvs = {}, incoming_context = {}) return unless ::Instana.agent.ready? self.current_trace = ::Instana::Trace.new(name, kvs, incoming_context) end |
#span_id ⇒ Object
Returns the current [Span] ID for the active trace (if there is one), otherwise nil.
318 319 320 |
# File 'lib/instana/tracer.rb', line 318 def span_id self.current_trace ? current_trace.current_span_id : nil end |
#span_id_header ⇒ String
Take the current span_id and convert it to a header compatible formate.
270 271 272 |
# File 'lib/instana/tracer.rb', line 270 def span_id_header id_to_header(span_id) end |
#start_or_continue_trace(name, kvs = {}, incoming_context = {}, &block) ⇒ Object
Will start a new trace or continue an on-going one (such as from incoming remote requests with context headers).
26 27 28 29 30 31 32 33 34 |
# File 'lib/instana/tracer.rb', line 26 def start_or_continue_trace(name, kvs = {}, incoming_context = {}, &block) log_start_or_continue(name, kvs, incoming_context) block.call rescue Exception => e log_error(e) raise ensure log_end(name) 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
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/instana/tracer.rb', line 47 def trace(name, kvs = {}, &block) log_entry(name, kvs) result = block.call result 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.
311 312 313 |
# File 'lib/instana/tracer.rb', line 311 def trace_id self.current_trace ? self.current_trace.id : nil end |
#trace_id_header ⇒ String
Take the current trace_id and convert it to a header compatible format.
261 262 263 |
# File 'lib/instana/tracer.rb', line 261 def trace_id_header id_to_header(trace_id) 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.
242 243 244 245 246 247 |
# File 'lib/instana/tracer.rb', line 242 def tracing? # The non-nil value of this instance variable # indicates if we are currently tracing # in this thread or not. self.current_trace ? true : false end |