From 48cc2bd6f7ae91db08b05dfbc03ec60089871941 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Thu, 10 Aug 2023 14:47:01 +0200 Subject: [PATCH] Implement Sentry.continue_trace and deprecate Sentry.from_sentry_trace --- sentry-ruby/lib/sentry-ruby.rb | 9 ++++++++ sentry-ruby/lib/sentry/hub.rb | 18 +++++++++++++++ sentry-ruby/lib/sentry/propagation_context.rb | 22 ++++++++++++++----- .../lib/sentry/rack/capture_exceptions.rb | 5 +---- sentry-ruby/lib/sentry/transaction.rb | 2 ++ 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index 03edc0a08..daed11803 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -516,6 +516,15 @@ def get_trace_propagation_headers get_current_hub.get_trace_propagation_headers end + # Continue an incoming trace from a rack env like hash. + # + # @param env [Hash] + # @return [Transaction, nil] + def continue_trace(env, **options) + return nil unless initialized? + get_current_hub.continue_trace(env, **options) + end + ##### Helpers ##### # @!visibility private diff --git a/sentry-ruby/lib/sentry/hub.rb b/sentry-ruby/lib/sentry/hub.rb index 2bece1b03..b8cd02c8e 100644 --- a/sentry-ruby/lib/sentry/hub.rb +++ b/sentry-ruby/lib/sentry/hub.rb @@ -252,6 +252,24 @@ def get_trace_propagation_headers }.compact end + def continue_trace(env, **options) + configure_scope { |s| s.generate_propagation_context(env) } + + return nil unless configuration.tracing_enabled? + + propagation_context = current_scope.propagation_context + return nil unless propagation_context.incoming_trace + + Transaction.new( + hub: self, + trace_id: propagation_context.trace_id, + parent_span_id: propagation_context.parent_span_id, + parent_sampled: propagation_context.parent_sampled, + baggage: propagation_context.baggage, + **options + ) + end + private def current_layer diff --git a/sentry-ruby/lib/sentry/propagation_context.rb b/sentry-ruby/lib/sentry/propagation_context.rb index a5f99b822..62f3a40a8 100644 --- a/sentry-ruby/lib/sentry/propagation_context.rb +++ b/sentry-ruby/lib/sentry/propagation_context.rb @@ -20,23 +20,35 @@ class PropagationContext # @return [String] attr_reader :span_id # Span parent's span_id. - # @return [String] + # @return [String, nil] attr_reader :parent_span_id + # The sampling decision of the parent transaction. + # @return [Boolean, nil] + attr_reader :parent_sampled + # Is there an incoming trace or not? + # @return [Boolean] + attr_reader :incoming_trace + # This is only for accessing the current baggage variable. + # Please use the #get_baggage method for interfacing outside this class. + # @return [Baggage, nil] + attr_reader :baggage def initialize(scope, env = nil) @scope = scope @parent_span_id = nil + @parent_sampled = nil @baggage = nil + @incoming_trace = false if env sentry_trace_header = env["HTTP_SENTRY_TRACE"] baggage_header = env["HTTP_BAGGAGE"] if sentry_trace_header - sentry_trace_data = extract_sentry_trace(sentry_trace_header) + sentry_trace_data = self.class.extract_sentry_trace(sentry_trace_header) if sentry_trace_data - @trace_id, @parent_span_id, _ = sentry_trace_data + @trace_id, @parent_span_id, @parent_sampled = sentry_trace_data @baggage = if baggage_header && !baggage_header.empty? Baggage.from_incoming_header(baggage_header) @@ -48,6 +60,7 @@ def initialize(scope, env = nil) end @baggage.freeze! + @incoming_trace = true end end end @@ -70,7 +83,6 @@ def self.extract_sentry_trace(sentry_trace) [trace_id, parent_span_id, parent_sampled] end - # Returns the trace context that can be used to embed in an Event. # @return [Hash] def get_trace_context @@ -87,7 +99,7 @@ def get_traceparent "#{trace_id}-#{span_id}" end - # Returns the Baggage from the propagation context. + # Returns the Baggage from the propagation context or populates as head SDK if empty. # @return [Baggage, nil] def get_baggage populate_head_baggage if @baggage.nil? || @baggage.mutable diff --git a/sentry-ruby/lib/sentry/rack/capture_exceptions.rb b/sentry-ruby/lib/sentry/rack/capture_exceptions.rb index 36c8b1848..2248799a3 100644 --- a/sentry-ruby/lib/sentry/rack/capture_exceptions.rb +++ b/sentry-ruby/lib/sentry/rack/capture_exceptions.rb @@ -62,11 +62,8 @@ def capture_exception(exception, env) end def start_transaction(env, scope) - sentry_trace = env["HTTP_SENTRY_TRACE"] - baggage = env["HTTP_BAGGAGE"] - options = { name: scope.transaction_name, source: scope.transaction_source, op: transaction_op } - transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, baggage: baggage, **options) if sentry_trace + transaction = Sentry.continue_trace(env, **options) Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options) end diff --git a/sentry-ruby/lib/sentry/transaction.rb b/sentry-ruby/lib/sentry/transaction.rb index abdb73b53..c64f9863e 100644 --- a/sentry-ruby/lib/sentry/transaction.rb +++ b/sentry-ruby/lib/sentry/transaction.rb @@ -89,6 +89,8 @@ def initialize( init_span_recorder end + # @deprecated use Sentry.continue_trace instead. + # # Initalizes a Transaction instance with a Sentry trace string from another transaction (usually from an external request). # # The original transaction will become the parent of the new Transaction instance. And they will share the same `trace_id`.