Class: AllStak::Modules::Tracing
- Inherits:
-
Object
- Object
- AllStak::Modules::Tracing
- Defined in:
- lib/allstak/modules/tracing.rb
Overview
Distributed tracing — spans with parent-child hierarchy via Thread-local state.
Constant Summary collapse
- PATH =
"/ingest/v1/spans".freeze
- VALID_STATUSES =
%w[ok error timeout].freeze
Instance Method Summary collapse
- #active_span_count ⇒ Object
- #active_trace_count ⇒ Object
- #buffer_count ⇒ Object
- #captured_count ⇒ Object
- #current_span_id ⇒ Object
- #current_trace_id ⇒ Object
-
#current_trace_sampled? ⇒ Boolean
Sampling decision for the CURRENT trace.
- #dropped_count ⇒ Object
- #flush ⇒ Object
-
#in_span(operation, description: "", tags: nil) ⇒ Object
Block-form helper: automatically finishes the span on return, on raise, or on non-local flow (e.g. Sinatra’s ‘throw :halt`).
-
#initialize(transport, config, logger) ⇒ Tracing
constructor
A new instance of Tracing.
- #reset_trace ⇒ Object
- #set_parent_span_id(span_id) ⇒ Object
- #set_trace_id(trace_id) ⇒ Object
- #shutdown ⇒ Object
- #start_span(operation, description: "", tags: nil) ⇒ Object
Constructor Details
#initialize(transport, config, logger) ⇒ Tracing
Returns a new instance of Tracing.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/allstak/modules/tracing.rb', line 12 def initialize(transport, config, logger) @transport = transport @config = config @logger = logger @captured_count = 0 @dropped_count = 0 @buffer = Transport::FlushBuffer.new( name: "tracing", max_size: config.buffer_size, interval_ms: config.flush_interval_ms, flush_proc: method(:flush_batch), logger: logger ) end |
Instance Method Details
#active_span_count ⇒ Object
124 125 126 127 128 129 |
# File 'lib/allstak/modules/tracing.rb', line 124 def active_span_count stack = Thread.current[:allstak_span_stack] stack.respond_to?(:length) ? stack.length : 0 rescue StandardError 0 end |
#active_trace_count ⇒ Object
131 132 133 134 135 |
# File 'lib/allstak/modules/tracing.rb', line 131 def active_trace_count Thread.current[:allstak_trace_id].nil? ? 0 : 1 rescue StandardError 0 end |
#buffer_count ⇒ Object
112 113 114 |
# File 'lib/allstak/modules/tracing.rb', line 112 def buffer_count @buffer.count end |
#captured_count ⇒ Object
120 121 122 |
# File 'lib/allstak/modules/tracing.rb', line 120 def captured_count @captured_count end |
#current_span_id ⇒ Object
40 41 42 43 |
# File 'lib/allstak/modules/tracing.rb', line 40 def current_span_id stack = Thread.current[:allstak_span_stack] stack&.last end |
#current_trace_id ⇒ Object
27 28 29 |
# File 'lib/allstak/modules/tracing.rb', line 27 def current_trace_id Thread.current[:allstak_trace_id] ||= SecureRandom.hex(16) end |
#current_trace_sampled? ⇒ Boolean
Sampling decision for the CURRENT trace. Decided once (at the first span of the trace) and cached thread-locally so every span and the propagated traceparent flag agree. When ‘traces_sample_rate` is nil (the default), tracing is unsampled-mode-off: everything is kept and the traceparent sampled flag stays “01” (historical behavior).
56 57 58 59 60 61 62 63 |
# File 'lib/allstak/modules/tracing.rb', line 56 def current_trace_sampled? decided = Thread.current[:allstak_trace_sampled] return decided unless decided.nil? rate = @config.traces_sample_rate decided = rate.nil? ? true : Sampling.sampled?(rate) Thread.current[:allstak_trace_sampled] = decided decided end |
#dropped_count ⇒ Object
116 117 118 |
# File 'lib/allstak/modules/tracing.rb', line 116 def dropped_count @dropped_count + @buffer.dropped_count end |
#flush ⇒ Object
104 105 106 |
# File 'lib/allstak/modules/tracing.rb', line 104 def flush @buffer.flush end |
#in_span(operation, description: "", tags: nil) ⇒ Object
Block-form helper: automatically finishes the span on return, on raise, or on non-local flow (e.g. Sinatra’s ‘throw :halt`).
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/allstak/modules/tracing.rb', line 91 def in_span(operation, description: "", tags: nil) span = start_span(operation, description: description, tags: ) status = "ok" begin return yield(span) rescue => e status = "error" raise ensure span.finish(status) unless span.finished? end end |
#reset_trace ⇒ Object
45 46 47 48 49 |
# File 'lib/allstak/modules/tracing.rb', line 45 def reset_trace Thread.current[:allstak_trace_id] = nil Thread.current[:allstak_span_stack] = nil Thread.current[:allstak_trace_sampled] = nil end |
#set_parent_span_id(span_id) ⇒ Object
35 36 37 38 |
# File 'lib/allstak/modules/tracing.rb', line 35 def set_parent_span_id(span_id) return unless AllStak::Propagation.valid_span_id?(span_id) Thread.current[:allstak_span_stack] = [span_id.to_s.downcase] end |
#set_trace_id(trace_id) ⇒ Object
31 32 33 |
# File 'lib/allstak/modules/tracing.rb', line 31 def set_trace_id(trace_id) Thread.current[:allstak_trace_id] = AllStak::Propagation.normalize_trace_id(trace_id) end |
#shutdown ⇒ Object
108 109 110 |
# File 'lib/allstak/modules/tracing.rb', line 108 def shutdown @buffer.shutdown end |
#start_span(operation, description: "", tags: nil) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/allstak/modules/tracing.rb', line 65 def start_span(operation, description: "", tags: nil) trace_id = current_trace_id sampled = current_trace_sampled? span_id = SecureRandom.hex(8) parent = current_span_id || "" Thread.current[:allstak_span_stack] ||= [] Thread.current[:allstak_span_stack] << span_id Span.new( trace_id: trace_id, span_id: span_id, parent_span_id: parent, operation: operation, description: description, service: @config.service_name, environment: @config.environment || "", release: (@config.respond_to?(:release) ? @config.release : nil) || "", tags: || {}, start_time_millis: (Time.now.to_f * 1000).to_i, sampled: sampled, on_finish: method(:on_span_finish) ) end |