sentry-ruby 5.26.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -4
  3. data/lib/sentry/background_worker.rb +1 -4
  4. data/lib/sentry/breadcrumb.rb +1 -1
  5. data/lib/sentry/breadcrumb_buffer.rb +2 -2
  6. data/lib/sentry/check_in_event.rb +2 -2
  7. data/lib/sentry/client.rb +29 -89
  8. data/lib/sentry/configuration.rb +125 -78
  9. data/lib/sentry/cron/monitor_check_ins.rb +3 -3
  10. data/lib/sentry/cron/monitor_config.rb +2 -2
  11. data/lib/sentry/cron/monitor_schedule.rb +2 -2
  12. data/lib/sentry/debug_structured_logger.rb +94 -0
  13. data/lib/sentry/dsn.rb +32 -0
  14. data/lib/sentry/envelope/item.rb +1 -2
  15. data/lib/sentry/error_event.rb +3 -3
  16. data/lib/sentry/event.rb +4 -10
  17. data/lib/sentry/graphql.rb +1 -1
  18. data/lib/sentry/hub.rb +6 -5
  19. data/lib/sentry/interface.rb +1 -1
  20. data/lib/sentry/interfaces/exception.rb +2 -2
  21. data/lib/sentry/interfaces/request.rb +2 -0
  22. data/lib/sentry/interfaces/single_exception.rb +3 -3
  23. data/lib/sentry/interfaces/stacktrace.rb +3 -3
  24. data/lib/sentry/interfaces/stacktrace_builder.rb +0 -8
  25. data/lib/sentry/interfaces/threads.rb +2 -2
  26. data/lib/sentry/log_event.rb +19 -6
  27. data/lib/sentry/profiler.rb +4 -5
  28. data/lib/sentry/propagation_context.rb +55 -18
  29. data/lib/sentry/rspec.rb +1 -1
  30. data/lib/sentry/span.rb +2 -17
  31. data/lib/sentry/std_lib_logger.rb +6 -1
  32. data/lib/sentry/test_helper.rb +23 -0
  33. data/lib/sentry/transaction.rb +72 -95
  34. data/lib/sentry/transaction_event.rb +4 -9
  35. data/lib/sentry/transport/debug_transport.rb +70 -0
  36. data/lib/sentry/transport/dummy_transport.rb +1 -0
  37. data/lib/sentry/transport/http_transport.rb +9 -5
  38. data/lib/sentry/transport.rb +3 -5
  39. data/lib/sentry/utils/logging_helper.rb +8 -6
  40. data/lib/sentry/utils/sample_rand.rb +97 -0
  41. data/lib/sentry/vernier/profiler.rb +4 -3
  42. data/lib/sentry/version.rb +1 -1
  43. data/lib/sentry-ruby.rb +6 -30
  44. data/sentry-ruby-core.gemspec +1 -1
  45. data/sentry-ruby.gemspec +1 -1
  46. metadata +11 -18
  47. data/lib/sentry/metrics/aggregator.rb +0 -248
  48. data/lib/sentry/metrics/configuration.rb +0 -47
  49. data/lib/sentry/metrics/counter_metric.rb +0 -25
  50. data/lib/sentry/metrics/distribution_metric.rb +0 -25
  51. data/lib/sentry/metrics/gauge_metric.rb +0 -35
  52. data/lib/sentry/metrics/local_aggregator.rb +0 -53
  53. data/lib/sentry/metrics/metric.rb +0 -19
  54. data/lib/sentry/metrics/set_metric.rb +0 -28
  55. data/lib/sentry/metrics/timing.rb +0 -51
  56. data/lib/sentry/metrics.rb +0 -56
data/lib/sentry/span.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "securerandom"
4
- require "sentry/metrics/local_aggregator"
5
4
  require "sentry/utils/uuid"
6
5
 
7
6
  module Sentry
@@ -173,8 +172,8 @@ module Sentry
173
172
  end
174
173
 
175
174
  # @return [Hash]
176
- def to_hash
177
- hash = {
175
+ def to_h
176
+ {
178
177
  trace_id: @trace_id,
179
178
  span_id: @span_id,
180
179
  parent_span_id: @parent_span_id,
@@ -187,11 +186,6 @@ module Sentry
187
186
  data: @data,
188
187
  origin: @origin
189
188
  }
190
-
191
- summary = metrics_summary
192
- hash[:_metrics_summary] = summary if summary
193
-
194
- hash
195
189
  end
196
190
 
197
191
  # Returns the span's context that can be used to embed in an Event.
@@ -307,14 +301,5 @@ module Sentry
307
301
  def set_origin(origin)
308
302
  @origin = origin
309
303
  end
310
-
311
- # Collects gauge metrics on the span for metric summaries.
312
- def metrics_local_aggregator
313
- @metrics_local_aggregator ||= Sentry::Metrics::LocalAggregator.new
314
- end
315
-
316
- def metrics_summary
317
- @metrics_local_aggregator&.to_hash
318
- end
319
304
  end
320
305
  end
@@ -12,11 +12,16 @@ module Sentry
12
12
  4 => :fatal
13
13
  }.freeze
14
14
 
15
+ ORIGIN = "auto.log.ruby.std_logger"
16
+
15
17
  def add(severity, message = nil, progname = nil, &block)
16
18
  result = super
17
19
 
18
20
  return unless Sentry.initialized? && Sentry.get_current_hub
19
21
 
22
+ # Only process logs that meet or exceed the logger's level
23
+ return result if severity < level
24
+
20
25
  # exclude sentry SDK logs -- to prevent recursive log action,
21
26
  # do not process internal logs again
22
27
  if message.nil? && progname != Sentry::Logger::PROGNAME
@@ -32,7 +37,7 @@ module Sentry
32
37
  message = message.to_s.strip
33
38
 
34
39
  if !message.nil? && message != Sentry::Logger::PROGNAME && method = SEVERITY_MAP[severity]
35
- Sentry.logger.send(method, message)
40
+ Sentry.logger.send(method, message, origin: ORIGIN)
36
41
  end
37
42
  end
38
43
 
@@ -2,8 +2,13 @@
2
2
 
3
3
  module Sentry
4
4
  module TestHelper
5
+ module_function
6
+
5
7
  DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42"
6
8
 
9
+ # Not really real, but it will be resolved as a non-local for testing needs
10
+ REAL_DSN = "https://user:pass@getsentry.io/project/42"
11
+
7
12
  # Alters the existing SDK configuration with test-suitable options. Mainly:
8
13
  # - Sets a dummy DSN instead of `nil` or an actual DSN.
9
14
  # - Sets the transport to DummyTransport, which allows easy access to the captured events.
@@ -22,6 +27,7 @@ module Sentry
22
27
  # set transport to DummyTransport, so we can easily intercept the captured events
23
28
  dummy_config.transport.transport_class = Sentry::DummyTransport
24
29
  # make sure SDK allows sending under the current environment
30
+ dummy_config.enabled_environments ||= []
25
31
  dummy_config.enabled_environments += [dummy_config.environment] unless dummy_config.enabled_environments.include?(dummy_config.environment)
26
32
  # disble async event sending
27
33
  dummy_config.background_worker_threads = 0
@@ -46,6 +52,8 @@ module Sentry
46
52
  def teardown_sentry_test
47
53
  return unless Sentry.initialized?
48
54
 
55
+ clear_sentry_events
56
+
49
57
  # pop testing layer created by `setup_sentry_test`
50
58
  # but keep the base layer to avoid nil-pointer errors
51
59
  # TODO: find a way to notify users if they somehow popped the test layer before calling this method
@@ -55,6 +63,21 @@ module Sentry
55
63
  Sentry::Scope.global_event_processors.clear
56
64
  end
57
65
 
66
+ def clear_sentry_events
67
+ return unless Sentry.initialized?
68
+
69
+ sentry_transport.clear if sentry_transport.respond_to?(:clear)
70
+
71
+ if Sentry.configuration.enable_logs && sentry_logger.respond_to?(:clear)
72
+ sentry_logger.clear
73
+ end
74
+ end
75
+
76
+ # @return [Sentry::StructuredLogger, Sentry::DebugStructuredLogger]
77
+ def sentry_logger
78
+ Sentry.logger
79
+ end
80
+
58
81
  # @return [Transport]
59
82
  def sentry_transport
60
83
  Sentry.get_current_client.transport
@@ -2,13 +2,11 @@
2
2
 
3
3
  require "sentry/baggage"
4
4
  require "sentry/profiler"
5
+ require "sentry/utils/sample_rand"
5
6
  require "sentry/propagation_context"
6
7
 
7
8
  module Sentry
8
9
  class Transaction < Span
9
- # @deprecated Use Sentry::PropagationContext::SENTRY_TRACE_REGEXP instead.
10
- SENTRY_TRACE_REGEXP = PropagationContext::SENTRY_TRACE_REGEXP
11
-
12
10
  UNLABELD_NAME = "<unlabeled transaction>"
13
11
  MESSAGE_PREFIX = "[Tracing]"
14
12
 
@@ -39,12 +37,6 @@ module Sentry
39
37
  # @return [Hash]
40
38
  attr_reader :measurements
41
39
 
42
- # @deprecated Use Sentry.get_current_hub instead.
43
- attr_reader :hub
44
-
45
- # @deprecated Use Sentry.configuration instead.
46
- attr_reader :configuration
47
-
48
40
  # The effective sample rate at which this transaction was sampled.
49
41
  # @return [Float, nil]
50
42
  attr_reader :effective_sample_rate
@@ -57,90 +49,39 @@ module Sentry
57
49
  # @return [Profiler]
58
50
  attr_reader :profiler
59
51
 
52
+ # Sample rand value generated from trace_id
53
+ # @return [String]
54
+ attr_reader :sample_rand
55
+
60
56
  def initialize(
61
- hub:,
62
57
  name: nil,
63
58
  source: :custom,
64
59
  parent_sampled: nil,
65
60
  baggage: nil,
61
+ sample_rand: nil,
66
62
  **options
67
63
  )
68
64
  super(transaction: self, **options)
69
65
 
70
66
  set_name(name, source: source)
71
67
  @parent_sampled = parent_sampled
72
- @hub = hub
73
68
  @baggage = baggage
74
- @configuration = hub.configuration # to be removed
75
- @tracing_enabled = hub.configuration.tracing_enabled?
76
- @traces_sampler = hub.configuration.traces_sampler
77
- @traces_sample_rate = hub.configuration.traces_sample_rate
78
- @sdk_logger = hub.configuration.sdk_logger
79
- @release = hub.configuration.release
80
- @environment = hub.configuration.environment
81
- @dsn = hub.configuration.dsn
82
69
  @effective_sample_rate = nil
83
70
  @contexts = {}
84
71
  @measurements = {}
85
-
86
- unless @hub.profiler_running?
87
- @profiler = @configuration.profiler_class.new(@configuration)
88
- end
72
+ @sample_rand = sample_rand
89
73
 
90
74
  init_span_recorder
91
- end
92
-
93
- # @deprecated use Sentry.continue_trace instead.
94
- #
95
- # Initalizes a Transaction instance with a Sentry trace string from another transaction (usually from an external request).
96
- #
97
- # The original transaction will become the parent of the new Transaction instance. And they will share the same `trace_id`.
98
- #
99
- # The child transaction will also store the parent's sampling decision in its `parent_sampled` attribute.
100
- # @param sentry_trace [String] the trace string from the previous transaction.
101
- # @param baggage [String, nil] the incoming baggage header string.
102
- # @param hub [Hub] the hub that'll be responsible for sending this transaction when it's finished.
103
- # @param options [Hash] the options you want to use to initialize a Transaction instance.
104
- # @return [Transaction, nil]
105
- def self.from_sentry_trace(sentry_trace, baggage: nil, hub: Sentry.get_current_hub, **options)
106
- return unless hub.configuration.tracing_enabled?
107
- return unless sentry_trace
108
-
109
- sentry_trace_data = extract_sentry_trace(sentry_trace)
110
- return unless sentry_trace_data
111
-
112
- trace_id, parent_span_id, parent_sampled = sentry_trace_data
113
-
114
- baggage =
115
- if baggage && !baggage.empty?
116
- Baggage.from_incoming_header(baggage)
117
- else
118
- # If there's an incoming sentry-trace but no incoming baggage header,
119
- # for instance in traces coming from older SDKs,
120
- # baggage will be empty and frozen and won't be populated as head SDK.
121
- Baggage.new({})
122
- end
75
+ init_profiler
123
76
 
124
- baggage.freeze!
125
-
126
- new(
127
- trace_id: trace_id,
128
- parent_span_id: parent_span_id,
129
- parent_sampled: parent_sampled,
130
- hub: hub,
131
- baggage: baggage,
132
- **options
133
- )
134
- end
135
-
136
- # @deprecated Use Sentry::PropagationContext.extract_sentry_trace instead.
137
- # @return [Array, nil]
138
- def self.extract_sentry_trace(sentry_trace)
139
- PropagationContext.extract_sentry_trace(sentry_trace)
77
+ unless @sample_rand
78
+ generator = Utils::SampleRand.new(trace_id: @trace_id)
79
+ @sample_rand = generator.generate_from_trace_id
80
+ end
140
81
  end
141
82
 
142
83
  # @return [Hash]
143
- def to_hash
84
+ def to_h
144
85
  hash = super
145
86
 
146
87
  hash.merge!(
@@ -153,6 +94,13 @@ module Sentry
153
94
  hash
154
95
  end
155
96
 
97
+ def parent_sample_rate
98
+ return unless @baggage&.items
99
+
100
+ sample_rate_str = @baggage.items["sample_rate"]
101
+ sample_rate_str&.to_f
102
+ end
103
+
156
104
  # @return [Transaction]
157
105
  def deep_dup
158
106
  copy = super
@@ -180,7 +128,9 @@ module Sentry
180
128
  # @param sampling_context [Hash] a context Hash that'll be passed to `traces_sampler` (if provided).
181
129
  # @return [void]
182
130
  def set_initial_sample_decision(sampling_context:)
183
- unless @tracing_enabled
131
+ configuration = Sentry.configuration
132
+
133
+ unless configuration && configuration.tracing_enabled?
184
134
  @sampled = false
185
135
  return
186
136
  end
@@ -191,12 +141,12 @@ module Sentry
191
141
  end
192
142
 
193
143
  sample_rate =
194
- if @traces_sampler.is_a?(Proc)
195
- @traces_sampler.call(sampling_context)
144
+ if configuration.traces_sampler.is_a?(Proc)
145
+ configuration.traces_sampler.call(sampling_context)
196
146
  elsif !sampling_context[:parent_sampled].nil?
197
147
  sampling_context[:parent_sampled]
198
148
  else
199
- @traces_sample_rate
149
+ configuration.traces_sample_rate
200
150
  end
201
151
 
202
152
  transaction_description = generate_transaction_description
@@ -225,7 +175,7 @@ module Sentry
225
175
  @effective_sample_rate /= 2**factor
226
176
  end
227
177
 
228
- @sampled = Random.rand < @effective_sample_rate
178
+ @sampled = @sample_rand < @effective_sample_rate
229
179
  end
230
180
 
231
181
  if @sampled
@@ -238,29 +188,28 @@ module Sentry
238
188
  end
239
189
 
240
190
  # Finishes the transaction's recording and send it to Sentry.
241
- # @param hub [Hub] the hub that'll send this transaction. (Deprecated)
242
191
  # @return [TransactionEvent]
243
- def finish(hub: nil, end_timestamp: nil)
244
- if hub
245
- log_warn(
246
- <<~MSG
247
- Specifying a different hub in `Transaction#finish` will be deprecated in version 5.0.
248
- Please use `Hub#start_transaction` with the designated hub.
249
- MSG
250
- )
251
- end
252
-
253
- hub ||= @hub
254
-
192
+ def finish(end_timestamp: nil)
255
193
  super(end_timestamp: end_timestamp)
256
194
 
257
195
  if @name.nil?
258
196
  @name = UNLABELD_NAME
259
197
  end
260
198
 
261
- @hub.stop_profiler!(self)
199
+ hub = Sentry.get_current_hub
200
+ return unless hub
262
201
 
263
- if @sampled
202
+ hub.stop_profiler!(self)
203
+
204
+ if @sampled && ignore_status_code?
205
+ @sampled = false
206
+
207
+ status_code = get_http_status_code
208
+ log_debug("#{MESSAGE_PREFIX} Discarding #{generate_transaction_description} due to ignored HTTP status code: #{status_code}")
209
+
210
+ hub.current_client.transport.record_lost_event(:event_processor, "transaction")
211
+ hub.current_client.transport.record_lost_event(:event_processor, "span")
212
+ elsif @sampled
264
213
  event = hub.current_client.event_from_transaction(self)
265
214
  hub.capture_event(event)
266
215
  else
@@ -318,6 +267,15 @@ module Sentry
318
267
  @span_recorder.add(self)
319
268
  end
320
269
 
270
+ def init_profiler
271
+ hub = Sentry.get_current_hub
272
+ return unless hub
273
+
274
+ unless hub.profiler_running?
275
+ @profiler = hub.configuration.profiler_class.new(hub.configuration)
276
+ end
277
+ end
278
+
321
279
  private
322
280
 
323
281
  def generate_transaction_description
@@ -328,13 +286,16 @@ module Sentry
328
286
  end
329
287
 
330
288
  def populate_head_baggage
289
+ configuration = Sentry.configuration
290
+
331
291
  items = {
332
292
  "trace_id" => trace_id,
333
293
  "sample_rate" => effective_sample_rate&.to_s,
294
+ "sample_rand" => Utils::SampleRand.format(@sample_rand),
334
295
  "sampled" => sampled&.to_s,
335
- "environment" => @environment,
336
- "release" => @release,
337
- "public_key" => @dsn&.public_key
296
+ "environment" => configuration&.environment,
297
+ "release" => configuration&.release,
298
+ "public_key" => configuration&.dsn&.public_key
338
299
  }
339
300
 
340
301
  items["transaction"] = name unless source_low_quality?
@@ -343,6 +304,22 @@ module Sentry
343
304
  @baggage = Baggage.new(items, mutable: false)
344
305
  end
345
306
 
307
+ def ignore_status_code?
308
+ trace_ignore_status_codes = Sentry.configuration&.trace_ignore_status_codes
309
+ return false unless trace_ignore_status_codes
310
+
311
+ status_code = get_http_status_code
312
+ return false unless status_code
313
+
314
+ trace_ignore_status_codes.any? do |ignored|
315
+ ignored.is_a?(Range) ? ignored.include?(status_code) : status_code == ignored
316
+ end
317
+ end
318
+
319
+ def get_http_status_code
320
+ @data && @data[Span::DataConventions::HTTP_STATUS_CODE]
321
+ end
322
+
346
323
  class SpanRecorder
347
324
  attr_reader :max_length, :spans
348
325
 
@@ -17,9 +17,6 @@ module Sentry
17
17
  # @return [Hash, nil]
18
18
  attr_accessor :profile
19
19
 
20
- # @return [Hash, nil]
21
- attr_accessor :metrics_summary
22
-
23
20
  def initialize(transaction:, **options)
24
21
  super(**options)
25
22
 
@@ -32,10 +29,9 @@ module Sentry
32
29
  self.tags = transaction.tags
33
30
  self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
34
31
  self.measurements = transaction.measurements
35
- self.metrics_summary = transaction.metrics_summary
36
32
 
37
33
  finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
38
- self.spans = finished_spans.map(&:to_hash)
34
+ self.spans = finished_spans.map(&:to_h)
39
35
 
40
36
  populate_profile(transaction)
41
37
  end
@@ -48,12 +44,11 @@ module Sentry
48
44
  end
49
45
 
50
46
  # @return [Hash]
51
- def to_hash
47
+ def to_h
52
48
  data = super
53
- data[:spans] = @spans.map(&:to_hash) if @spans
49
+ data[:spans] = @spans.map(&:to_h) if @spans
54
50
  data[:start_timestamp] = @start_timestamp
55
51
  data[:measurements] = @measurements
56
- data[:_metrics_summary] = @metrics_summary if @metrics_summary
57
52
  data
58
53
  end
59
54
 
@@ -62,7 +57,7 @@ module Sentry
62
57
  EMPTY_PROFILE = {}.freeze
63
58
 
64
59
  def populate_profile(transaction)
65
- profile_hash = transaction.profiler&.to_hash || EMPTY_PROFILE
60
+ profile_hash = transaction.profiler&.to_h || EMPTY_PROFILE
66
61
 
67
62
  return if profile_hash.empty?
68
63
 
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "fileutils"
5
+ require "pathname"
6
+ require "delegate"
7
+
8
+ module Sentry
9
+ # DebugTransport is a transport that logs events to a file for debugging purposes.
10
+ #
11
+ # It can optionally also send events to Sentry via HTTP transport if a real DSN
12
+ # is provided.
13
+ class DebugTransport < SimpleDelegator
14
+ DEFAULT_LOG_FILE_PATH = File.join("log", "sentry_debug_events.log")
15
+
16
+ attr_reader :log_file, :backend
17
+
18
+ def initialize(configuration)
19
+ @log_file = initialize_log_file(configuration)
20
+ @backend = initialize_backend(configuration)
21
+
22
+ super(@backend)
23
+ end
24
+
25
+ def send_event(event)
26
+ log_envelope(envelope_from_event(event))
27
+ backend.send_event(event)
28
+ end
29
+
30
+ def log_envelope(envelope)
31
+ envelope_json = {
32
+ timestamp: Time.now.utc.iso8601,
33
+ envelope_headers: envelope.headers,
34
+ items: envelope.items.map do |item|
35
+ { headers: item.headers, payload: item.payload }
36
+ end
37
+ }
38
+
39
+ File.open(log_file, "a") { |file| file << JSON.dump(envelope_json) << "\n" }
40
+ end
41
+
42
+ def logged_envelopes
43
+ return [] unless File.exist?(log_file)
44
+
45
+ File.readlines(log_file).map do |line|
46
+ JSON.parse(line)
47
+ end
48
+ end
49
+
50
+ def clear
51
+ File.write(log_file, "")
52
+ log_debug("DebugTransport: Cleared events from #{log_file}")
53
+ end
54
+
55
+ private
56
+
57
+ def initialize_backend(configuration)
58
+ backend = configuration.dsn.local? ? DummyTransport : HTTPTransport
59
+ backend.new(configuration)
60
+ end
61
+
62
+ def initialize_log_file(configuration)
63
+ log_file = Pathname(configuration.sdk_debug_transport_log_file || DEFAULT_LOG_FILE_PATH)
64
+
65
+ FileUtils.mkdir_p(log_file.dirname) unless log_file.dirname.exist?
66
+
67
+ log_file
68
+ end
69
+ end
70
+ end
@@ -12,6 +12,7 @@ module Sentry
12
12
 
13
13
  def send_event(event)
14
14
  @events << event
15
+ super
15
16
  end
16
17
 
17
18
  def send_envelope(envelope)
@@ -45,11 +45,7 @@ module Sentry
45
45
  auth_header = generate_auth_header
46
46
  headers["X-Sentry-Auth"] = auth_header if auth_header
47
47
 
48
- response = conn.start do |http|
49
- request = ::Net::HTTP::Post.new(endpoint, headers)
50
- request.body = data
51
- http.request(request)
52
- end
48
+ response = do_request(endpoint, headers, data)
53
49
 
54
50
  if response.code.match?(/\A2\d{2}/)
55
51
  handle_rate_limited_response(response) if has_rate_limited_header?(response)
@@ -111,6 +107,14 @@ module Sentry
111
107
  connection
112
108
  end
113
109
 
110
+ def do_request(endpoint, headers, body)
111
+ conn.start do |http|
112
+ request = ::Net::HTTP::Post.new(endpoint, headers)
113
+ request.body = body
114
+ http.request(request)
115
+ end
116
+ end
117
+
114
118
  private
115
119
 
116
120
  def has_rate_limited_header?(headers)
@@ -113,7 +113,7 @@ module Sentry
113
113
 
114
114
  def envelope_from_event(event)
115
115
  # Convert to hash
116
- event_payload = event.to_hash
116
+ event_payload = event.to_h
117
117
  event_id = event_payload[:event_id] || event_payload["event_id"]
118
118
  item_type = event_payload[:type] || event_payload["type"]
119
119
 
@@ -124,10 +124,7 @@ module Sentry
124
124
  sent_at: Sentry.utc_now.iso8601
125
125
  }
126
126
 
127
- if event.is_a?(Event) && event.dynamic_sampling_context
128
- envelope_headers[:trace] = event.dynamic_sampling_context
129
- end
130
-
127
+ envelope_headers[:trace] = event.dynamic_sampling_context if event.dynamic_sampling_context
131
128
  envelope = Envelope.new(envelope_headers)
132
129
 
133
130
  if event.is_a?(LogEvent)
@@ -223,3 +220,4 @@ end
223
220
  require "sentry/transport/dummy_transport"
224
221
  require "sentry/transport/http_transport"
225
222
  require "sentry/transport/spotlight_transport"
223
+ require "sentry/transport/debug_transport"
@@ -3,27 +3,29 @@
3
3
  module Sentry
4
4
  # @private
5
5
  module LoggingHelper
6
- # @!visibility private
7
- attr_reader :sdk_logger
8
-
9
6
  # @!visibility private
10
7
  def log_error(message, exception, debug: false)
11
8
  message = "#{message}: #{exception.message}"
12
9
  message += "\n#{exception.backtrace.join("\n")}" if debug
13
10
 
14
- sdk_logger.error(LOGGER_PROGNAME) do
11
+ sdk_logger&.error(LOGGER_PROGNAME) do
15
12
  message
16
13
  end
17
14
  end
18
15
 
19
16
  # @!visibility private
20
17
  def log_debug(message)
21
- sdk_logger.debug(LOGGER_PROGNAME) { message }
18
+ sdk_logger&.debug(LOGGER_PROGNAME) { message }
22
19
  end
23
20
 
24
21
  # @!visibility private
25
22
  def log_warn(message)
26
- sdk_logger.warn(LOGGER_PROGNAME) { message }
23
+ sdk_logger&.warn(LOGGER_PROGNAME) { message }
24
+ end
25
+
26
+ # @!visibility private
27
+ def sdk_logger
28
+ @sdk_logger ||= Sentry.sdk_logger
27
29
  end
28
30
  end
29
31
  end