class Sentry::Transaction
def deep_dup
-
(Transaction)-
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
def finish(end_timestamp: nil)
-
(TransactionEvent)-
def finish(end_timestamp: nil) super(end_timestamp: 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
def generate_transaction_description
def generate_transaction_description result = op.nil? ? "" : "<#{@op}> " result += "transaction" result += " <#{@name}>" if @name result end
def get_baggage
-
(Baggage)-
def get_baggage populate_head_baggage if @baggage.nil? || @baggage.mutable @baggage end
def get_http_status_code
def get_http_status_code @data && @data[Span::DataConventions::HTTP_STATUS_CODE] end
def ignore_status_code?
def ignore_status_code? trace_ignore_status_codes = Sentry.configuration&.trace_ignore_status_codes return false unless trace_ignore_status_codes status_code = get_http_status_code return false unless status_code trace_ignore_status_codes.any? do |ignored| ignored.is_a?(Range) ? ignored.include?(status_code) : status_code == ignored end end
def init_profiler
def init_profiler hub = Sentry.get_current_hub return unless hub unless hub.profiler_running? @profiler = hub.configuration.profiler_class.new(hub.configuration) end end
def init_span_recorder(limit = 1000)
def init_span_recorder(limit = 1000) @span_recorder = SpanRecorder.new(limit) @span_recorder.add(self) end
def initialize(
def initialize( name: nil, source: :custom, parent_sampled: nil, baggage: nil, sample_rand: nil, **options ) super(transaction: self, **options) 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
def parent_sample_rate
def parent_sample_rate return unless @baggage&.items sample_rate_str = @baggage.items["sample_rate"] sample_rate_str&.to_f end
def populate_head_baggage
def populate_head_baggage configuration = Sentry.configuration items = { "trace_id" => trace_id, "sample_rate" => effective_sample_rate&.to_s, "sample_rand" => Utils::SampleRand.format(@sample_rand), "sampled" => sampled&.to_s, "environment" => configuration&.environment, "release" => configuration&.release, "public_key" => configuration&.dsn&.public_key, "org_id" => configuration&.effective_org_id } items["transaction"] = name unless source_low_quality? items.compact! @baggage = Baggage.new(items, mutable: false) end
def set_context(key, value)
-
(void)-
Parameters:
-
value(Object) -- -
key(String, Symbol) --
def set_context(key, value) @contexts[key] = value end
def set_initial_sample_decision(sampling_context:)
-
(void)-
Parameters:
-
sampling_context(Hash) -- a context Hash that'll be passed to `traces_sampler` (if provided).
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
def set_measurement(name, value, unit = "")
-
(void)-
Parameters:
-
unit(String) -- unit of the measurement -
value(Float) -- value of the measurement -
name(String) -- name of the measurement
def set_measurement(name, value, unit = "") @measurements[name] = { value: value, unit: unit } end
def set_name(name, source: :custom)
-
(void)-
Parameters:
-
source(Symbol) -- -
name(String) --
def set_name(name, source: :custom) @name = name @source = SOURCES.include?(source) ? source.to_sym : :custom end
def source_low_quality?
def source_low_quality? source == :url end
def start_profiler!
-
(void)-
def start_profiler! return unless profiler profiler.set_initial_sample_decision(sampled) profiler.start end
def to_h
-
(Hash)-
def to_h hash = super hash.merge!( name: @name, source: @source, sampled: @sampled, parent_sampled: @parent_sampled ) hash end