From 12befb7eaf9407ba3af878d5221a9d1720ad1a49 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Thu, 27 Jul 2023 14:32:31 +0200 Subject: [PATCH] Add new trace_propagation_targets configuration to set outgoing targets for trace header propagation --- CHANGELOG.md | 7 +++++++ sentry-ruby/lib/sentry/configuration.rb | 8 ++++++++ sentry-ruby/lib/sentry/net/http.rb | 18 +++++++++++------- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec6fd7db..fc9fa589b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ ### Features - Make `:value` in `SingleExceptionInterface` writable, so that it can be modified in `before_send` under `event.exception.values[n].value` [#2072](https://github.com/getsentry/sentry-ruby/pull/2072) +- Add new `config.trace_propagation_targets` option to set targets for which headers are propagated in outgoing HTTP requests [#2079](https://github.com/getsentry/sentry-ruby/pull/2079) + + ```rb + # takes an array of strings or regexps + config.trace_propagation_targets = [/.*/] # default is to all targets + config.trace_propagation_targets = [/example.com/, 'foobar.org'] + ``` ## 5.10.0 diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index fb619adcb..11c2ce3bd 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -243,6 +243,11 @@ def capture_exception_frame_locals=(value) # @return [Boolean] attr_accessor :auto_session_tracking + # Allowlist of outgoing request targets to which sentry-trace and baggage headers are attached. + # Default is all (/.*/) + # @return [Array] + attr_accessor :trace_propagation_targets + # The instrumenter to use, :sentry or :otel # @return [Symbol] attr_reader :instrumenter @@ -290,6 +295,8 @@ def capture_exception_frame_locals=(value) INSTRUMENTERS = [:sentry, :otel] + PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze + class << self # Post initialization callbacks are called at the end of initialization process # allowing extending the configuration of sentry-ruby by multiple extensions @@ -332,6 +339,7 @@ def initialize self.dsn = ENV['SENTRY_DSN'] self.server_name = server_name_from_env self.instrumenter = :sentry + self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL] self.before_send = nil self.before_send_transaction = nil diff --git a/sentry-ruby/lib/sentry/net/http.rb b/sentry-ruby/lib/sentry/net/http.rb index 470d1a796..e1170dc23 100644 --- a/sentry-ruby/lib/sentry/net/http.rb +++ b/sentry-ruby/lib/sentry/net/http.rb @@ -30,13 +30,13 @@ def request(req, body = nil, &block) return super if from_sentry_sdk? Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f) do |sentry_span| - set_sentry_trace_header(req, sentry_span) + request_info = extract_request_info(req) + set_sentry_trace_header(req, sentry_span, request_info) super.tap do |res| - record_sentry_breadcrumb(req, res) + record_sentry_breadcrumb(req, res, request_info) if sentry_span - request_info = extract_request_info(req) sentry_span.set_description("#{request_info[:method]} #{request_info[:url]}") sentry_span.set_data('url', request_info[:url]) sentry_span.set_data('http.method', request_info[:method]) @@ -49,10 +49,12 @@ def request(req, body = nil, &block) private - def set_sentry_trace_header(req, sentry_span) + def set_sentry_trace_header(req, sentry_span, request_info) return unless sentry_span client = Sentry.get_current_client + return unless client + return unless propagate_trace?(request_info[:url], client.configuration.trace_propagation_targets) trace = client.generate_sentry_trace(sentry_span) req[SENTRY_TRACE_HEADER_NAME] = trace if trace @@ -61,11 +63,9 @@ def set_sentry_trace_header(req, sentry_span) req[BAGGAGE_HEADER_NAME] = baggage if baggage && !baggage.empty? end - def record_sentry_breadcrumb(req, res) + def record_sentry_breadcrumb(req, res, request_info) return unless Sentry.initialized? && Sentry.configuration.breadcrumbs_logger.include?(:http_logger) - request_info = extract_request_info(req) - crumb = Sentry::Breadcrumb.new( level: :info, category: BREADCRUMB_CATEGORY, @@ -96,6 +96,10 @@ def extract_request_info(req) result end + + def propagate_trace?(url, trace_propagation_targets) + url && trace_propagation_targets.any? { |target| url.match?(target) } + end end end end