Class: Sentry::Transaction
- Includes:
- LoggingHelper
- Defined in:
- lib/sentry/transaction.rb
Defined Under Namespace
Classes: SpanRecorder
Constant Summary collapse
- UNLABELD_NAME =
"<unlabeled transaction>"- MESSAGE_PREFIX =
"[Tracing]"- SOURCES =
%i[custom url route view component task]
Constants inherited from Span
Span::DEFAULT_SPAN_ORIGIN, Span::STATUS_MAP
Instance Attribute Summary collapse
-
#baggage ⇒ Baggage?
readonly
The parsed incoming W3C baggage header.
-
#contexts ⇒ Hash
readonly
Additional contexts stored directly on the transaction object.
-
#effective_sample_rate ⇒ Float?
readonly
The effective sample rate at which this transaction was sampled.
-
#measurements ⇒ Hash
readonly
The measurements added to the transaction.
-
#name ⇒ String
readonly
The name of the transaction.
-
#parent_sampled ⇒ String
readonly
The sampling decision of the parent transaction, which will be considered when making the current transaction’s sampling decision.
-
#profiler ⇒ Profiler
readonly
The Profiler instance for this transaction.
-
#sample_rand ⇒ String
readonly
Sample rand value generated from trace_id.
-
#source ⇒ Symbol
readonly
The source of the transaction name.
Attributes inherited from Span
#data, #description, #op, #origin, #parent_span_id, #sampled, #span_id, #span_recorder, #start_timestamp, #status, #tags, #timestamp, #trace_id, #transaction
Instance Method Summary collapse
- #deep_dup ⇒ Transaction
-
#finish(end_timestamp: nil) ⇒ TransactionEvent
Finishes the transaction’s recording and send it to Sentry.
-
#get_baggage ⇒ Baggage
Get the existing frozen incoming baggage or populate one with sentry- items as the head SDK.
-
#initialize(name: nil, source: :custom, parent_sampled: nil, baggage: nil, sample_rand: nil, **options) ⇒ Transaction
constructor
A new instance of Transaction.
- #parent_sample_rate ⇒ Object
-
#set_context(key, value) ⇒ void
Set contexts directly on the transaction.
-
#set_initial_sample_decision(sampling_context:) ⇒ void
Sets initial sampling decision of the transaction.
-
#set_measurement(name, value, unit = "") ⇒ void
Sets a custom measurement on the transaction.
-
#set_name(name, source: :custom) ⇒ void
Set the transaction name directly.
-
#source_low_quality? ⇒ Boolean
These are high cardinality and thus bad.
-
#start_profiler! ⇒ void
Start the profiler.
- #to_h ⇒ Hash
Methods inherited from Span
#get_dynamic_sampling_context, #get_trace_context, #set_data, #set_description, #set_http_status, #set_op, #set_origin, #set_status, #set_tag, #set_timestamp, #start_child, #to_baggage, #to_sentry_trace, #with_child_span
Constructor Details
#initialize(name: nil, source: :custom, parent_sampled: nil, baggage: nil, sample_rand: nil, **options) ⇒ Transaction
Returns a new instance of Transaction.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sentry/transaction.rb', line 56 def initialize( name: nil, source: :custom, parent_sampled: nil, baggage: nil, sample_rand: nil, ** ) super(transaction: self, **) set_name(name, source: source) @parent_sampled = parent_sampled @baggage = baggage @effective_sample_rate = nil @contexts = {} @measurements = {} @sample_rand = sample_rand init_span_recorder init_profiler unless @sample_rand generator = Utils::SampleRand.new(trace_id: @trace_id) @sample_rand = generator.generate_from_trace_id end end |
Instance Attribute Details
#baggage ⇒ Baggage? (readonly)
The parsed incoming W3C baggage header. This is only for accessing the current baggage variable. Please use the #get_baggage method for interfacing outside this class.
34 35 36 |
# File 'lib/sentry/transaction.rb', line 34 def baggage @baggage end |
#contexts ⇒ Hash (readonly)
Additional contexts stored directly on the transaction object.
46 47 48 |
# File 'lib/sentry/transaction.rb', line 46 def contexts @contexts end |
#effective_sample_rate ⇒ Float? (readonly)
The effective sample rate at which this transaction was sampled.
42 43 44 |
# File 'lib/sentry/transaction.rb', line 42 def effective_sample_rate @effective_sample_rate end |
#measurements ⇒ Hash (readonly)
The measurements added to the transaction.
38 39 40 |
# File 'lib/sentry/transaction.rb', line 38 def measurements @measurements end |
#name ⇒ String (readonly)
The name of the transaction.
20 21 22 |
# File 'lib/sentry/transaction.rb', line 20 def name @name end |
#parent_sampled ⇒ String (readonly)
The sampling decision of the parent transaction, which will be considered when making the current transaction’s sampling decision.
28 29 30 |
# File 'lib/sentry/transaction.rb', line 28 def parent_sampled @parent_sampled end |
#profiler ⇒ Profiler (readonly)
The Profiler instance for this transaction.
50 51 52 |
# File 'lib/sentry/transaction.rb', line 50 def profiler @profiler end |
#sample_rand ⇒ String (readonly)
Sample rand value generated from trace_id
54 55 56 |
# File 'lib/sentry/transaction.rb', line 54 def sample_rand @sample_rand end |
#source ⇒ Symbol (readonly)
The source of the transaction name.
24 25 26 |
# File 'lib/sentry/transaction.rb', line 24 def source @source end |
Instance Method Details
#deep_dup ⇒ Transaction
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/sentry/transaction.rb', line 105 def deep_dup copy = super copy.init_span_recorder(@span_recorder.max_length) @span_recorder.spans.each do |span| # span_recorder's first span is the current span, which should not be added to the copy's spans next if span == self copy.span_recorder.add(span.dup) end copy end |
#finish(end_timestamp: nil) ⇒ TransactionEvent
Finishes the transaction’s recording and send it to Sentry.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/sentry/transaction.rb', line 192 def finish(end_timestamp: nil) super(end_timestamp: ) if @name.nil? @name = UNLABELD_NAME end hub = Sentry.get_current_hub return unless hub hub.stop_profiler!(self) if @sampled && ignore_status_code? @sampled = false status_code = get_http_status_code log_debug("#{MESSAGE_PREFIX} Discarding #{generate_transaction_description} due to ignored HTTP status code: #{status_code}") hub.current_client.transport.record_lost_event(:event_processor, "transaction") hub.current_client.transport.record_lost_event(:event_processor, "span") elsif @sampled event = hub.current_client.event_from_transaction(self) hub.capture_event(event) else is_backpressure = Sentry.backpressure_monitor&.downsample_factor&.positive? reason = is_backpressure ? :backpressure : :sample_rate hub.current_client.transport.record_lost_event(reason, "transaction") hub.current_client.transport.record_lost_event(reason, "span") end end |
#get_baggage ⇒ Baggage
Get the existing frozen incoming baggage or populate one with sentry- items as the head SDK.
226 227 228 229 |
# File 'lib/sentry/transaction.rb', line 226 def get_baggage populate_head_baggage if @baggage.nil? || @baggage.mutable @baggage end |
#parent_sample_rate ⇒ Object
97 98 99 100 101 102 |
# File 'lib/sentry/transaction.rb', line 97 def parent_sample_rate return unless @baggage&.items sample_rate_str = @baggage.items["sample_rate"] sample_rate_str&.to_f end |
#set_context(key, value) ⇒ void
This method returns an undefined value.
Set contexts directly on the transaction.
245 246 247 |
# File 'lib/sentry/transaction.rb', line 245 def set_context(key, value) @contexts[key] = value end |
#set_initial_sample_decision(sampling_context:) ⇒ void
This method returns an undefined value.
Sets initial sampling decision of the transaction.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/sentry/transaction.rb', line 130 def set_initial_sample_decision(sampling_context:) configuration = Sentry.configuration unless configuration && configuration.tracing_enabled? @sampled = false return end unless @sampled.nil? @effective_sample_rate = @sampled ? 1.0 : 0.0 return end sample_rate = if configuration.traces_sampler.is_a?(Proc) configuration.traces_sampler.call(sampling_context) elsif !sampling_context[:parent_sampled].nil? sampling_context[:parent_sampled] else configuration.traces_sample_rate end transaction_description = generate_transaction_description if [true, false].include?(sample_rate) @effective_sample_rate = sample_rate ? 1.0 : 0.0 elsif sample_rate.is_a?(Numeric) && sample_rate >= 0.0 && sample_rate <= 1.0 @effective_sample_rate = sample_rate.to_f else @sampled = false log_warn("#{MESSAGE_PREFIX} Discarding #{transaction_description} because of invalid sample_rate: #{sample_rate}") return end if sample_rate == 0.0 || sample_rate == false @sampled = false log_debug("#{MESSAGE_PREFIX} Discarding #{transaction_description} because traces_sampler returned 0 or false") return end if sample_rate == true @sampled = true else if Sentry.backpressure_monitor factor = Sentry.backpressure_monitor.downsample_factor @effective_sample_rate /= 2**factor end @sampled = @sample_rand < @effective_sample_rate end if @sampled log_debug("#{MESSAGE_PREFIX} Starting #{transaction_description}") else log_debug( "#{MESSAGE_PREFIX} Discarding #{transaction_description} because it's not included in the random sample (sampling rate = #{sample_rate})" ) end end |
#set_measurement(name, value, unit = "") ⇒ void
This method returns an undefined value.
Sets a custom measurement on the transaction.
123 124 125 |
# File 'lib/sentry/transaction.rb', line 123 def set_measurement(name, value, unit = "") @measurements[name] = { value: value, unit: unit } end |
#set_name(name, source: :custom) ⇒ void
This method returns an undefined value.
Set the transaction name directly. Considered internal api since it bypasses the usual scope logic.
236 237 238 239 |
# File 'lib/sentry/transaction.rb', line 236 def set_name(name, source: :custom) @name = name @source = SOURCES.include?(source) ? source.to_sym : :custom end |
#source_low_quality? ⇒ Boolean
These are high cardinality and thus bad
259 260 261 |
# File 'lib/sentry/transaction.rb', line 259 def source_low_quality? source == :url end |
#start_profiler! ⇒ void
This method returns an undefined value.
Start the profiler.
251 252 253 254 255 256 |
# File 'lib/sentry/transaction.rb', line 251 def start_profiler! return unless profiler profiler.set_initial_sample_decision(sampled) profiler.start end |
#to_h ⇒ Hash
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/sentry/transaction.rb', line 84 def to_h hash = super hash.merge!( name: @name, source: @source, sampled: @sampled, parent_sampled: @parent_sampled ) hash end |