sentry-ruby 5.7.0 → 5.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a60b754ccac4d1fd8cf47cd94d8896c46dc8232f87d06132681a19ed223ac14c
4
- data.tar.gz: 923f906cd698d18f2fcb419bfeb2d1262c4165e6a8ffe2484de7027a90e69644
3
+ metadata.gz: 2ced2a96562a5dc27766fb35a62e43f302dd46eeabd16eae2a52106cc2151ee0
4
+ data.tar.gz: 14f4b9a532cc0d1f401ee0bcb942787951f107358e9fbfadc2b1c655d00da3b2
5
5
  SHA512:
6
- metadata.gz: 7d46f719bd4e0abb6f9fcd254b6e6321c9796c2278bc31fa5f86dc541cc0ce54a4f6cc10078d6d0277c89ff0cd4896e2a0ec0aa04e3052214b01b85cb2aa115c
7
- data.tar.gz: 14b28401b32d9ce9ee7ac0351de736d0d9f11221010e61091e4976b71a58b1fef61ca4e282ec31a714e040148197c5fab46f0a0e39e475ea1f6dd0196b5f104d
6
+ metadata.gz: 8816a3439fd547d260e538d16c3db3f440bbdae35ec8108e2338ccd712497cbca0413ce1a365862ab510a787f5d3cae8a58eab2273dd06588284d77a5afac898
7
+ data.tar.gz: 4d5e8d3fe56644431b33fbec3eeaf4ceec01eb85b21bd2abfa5a0d8bc4c812aef9beb06b89048525186f00170677b160154414d5cb9b8972725532ba35277130
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --format documentation
2
2
  --color
3
- --require spec_helper
data/Gemfile CHANGED
@@ -7,12 +7,14 @@ rack_version = ENV["RACK_VERSION"]
7
7
  rack_version = "3.0.0" if rack_version.nil?
8
8
  gem "rack", "~> #{Gem::Version.new(rack_version)}" unless rack_version == "0"
9
9
 
10
+ redis_rb_version = ENV.fetch("REDIS_RB_VERSION", "5.0")
11
+ gem "redis", "~> #{redis_rb_version}"
12
+
10
13
  gem "rake", "~> 12.0"
11
14
  gem "rspec", "~> 3.0"
12
15
  gem "rspec-retry"
13
- gem "fakeredis"
14
16
  gem "timecop"
15
- gem 'simplecov'
17
+ gem "simplecov"
16
18
  gem "simplecov-cobertura", "~> 1.4"
17
19
  gem "rexml"
18
20
 
@@ -25,4 +27,5 @@ gem "benchmark_driver"
25
27
  gem "benchmark-ipsa"
26
28
  gem "benchmark-memory"
27
29
 
28
- gem "yard", "~> 0.9.27"
30
+ gem "yard", github: "lsegal/yard"
31
+ gem "webrick"
data/lib/sentry/client.rb CHANGED
@@ -122,6 +122,16 @@ module Sentry
122
122
  end
123
123
  end
124
124
 
125
+ if event_type == TransactionEvent::TYPE && configuration.before_send_transaction
126
+ event = configuration.before_send_transaction.call(event, hint)
127
+
128
+ if event.nil?
129
+ log_info("Discarded event because before_send_transaction returned nil")
130
+ transport.record_lost_event(:before_send, 'transaction')
131
+ return
132
+ end
133
+ end
134
+
125
135
  transport.send_event(event)
126
136
 
127
137
  event
@@ -72,6 +72,19 @@ module Sentry
72
72
  # @return [Proc]
73
73
  attr_reader :before_send
74
74
 
75
+ # Optional Proc, called before sending an event to the server
76
+ # @example
77
+ # config.before_send_transaction = lambda do |event, hint|
78
+ # # skip unimportant transactions or strip sensitive data
79
+ # if event.transaction == "/healthcheck/route"
80
+ # nil
81
+ # else
82
+ # event
83
+ # end
84
+ # end
85
+ # @return [Proc]
86
+ attr_reader :before_send_transaction
87
+
75
88
  # An array of breadcrumbs loggers to be used. Available options are:
76
89
  # - :sentry_logger
77
90
  # - :http_logger
@@ -84,10 +97,6 @@ module Sentry
84
97
  # @return [Array<Symbol>]
85
98
  attr_reader :breadcrumbs_logger
86
99
 
87
- # Whether to capture local variables from the raised exception's frame. Default is false.
88
- # @return [Boolean]
89
- attr_accessor :capture_exception_frame_locals
90
-
91
100
  # Max number of breadcrumbs a breadcrumb buffer can hold
92
101
  # @return [Integer]
93
102
  attr_accessor :max_breadcrumbs
@@ -127,6 +136,22 @@ module Sentry
127
136
  attr_accessor :inspect_exception_causes_for_exclusion
128
137
  alias inspect_exception_causes_for_exclusion? inspect_exception_causes_for_exclusion
129
138
 
139
+ # Whether to capture local variables from the raised exception's frame. Default is false.
140
+ # @return [Boolean]
141
+ attr_accessor :include_local_variables
142
+
143
+ # @deprecated Use {#include_local_variables} instead.
144
+ alias_method :capture_exception_frame_locals, :include_local_variables
145
+
146
+ # @deprecated Use {#include_local_variables=} instead.
147
+ def capture_exception_frame_locals=(value)
148
+ log_warn <<~MSG
149
+ `capture_exception_frame_locals` is now deprecated in favor of `include_local_variables`.
150
+ MSG
151
+
152
+ self.include_local_variables = value
153
+ end
154
+
130
155
  # You may provide your own LineCache for matching paths with source files.
131
156
  # This may be useful if you need to get source code from places other than the disk.
132
157
  # @see LineCache
@@ -243,9 +268,18 @@ module Sentry
243
268
 
244
269
  INSTRUMENTERS = [:sentry, :otel]
245
270
 
246
- # Post initialization callbacks are called at the end of initialization process
247
- # allowing extending the configuration of sentry-ruby by multiple extensions
248
- @@post_initialization_callbacks = []
271
+ class << self
272
+ # Post initialization callbacks are called at the end of initialization process
273
+ # allowing extending the configuration of sentry-ruby by multiple extensions
274
+ def post_initialization_callbacks
275
+ @post_initialization_callbacks ||= []
276
+ end
277
+
278
+ # allow extensions to add their hooks to the Configuration class
279
+ def add_post_initialization_callback(&block)
280
+ post_initialization_callbacks << block
281
+ end
282
+ end
249
283
 
250
284
  def initialize
251
285
  self.app_dirs_pattern = nil
@@ -255,7 +289,7 @@ module Sentry
255
289
  self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
256
290
  self.breadcrumbs_logger = []
257
291
  self.context_lines = 3
258
- self.capture_exception_frame_locals = false
292
+ self.include_local_variables = false
259
293
  self.environment = environment_from_env
260
294
  self.enabled_environments = []
261
295
  self.exclude_loggers = []
@@ -278,6 +312,7 @@ module Sentry
278
312
  self.instrumenter = :sentry
279
313
 
280
314
  self.before_send = nil
315
+ self.before_send_transaction = nil
281
316
  self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
282
317
  self.traces_sample_rate = nil
283
318
  self.traces_sampler = nil
@@ -329,6 +364,12 @@ module Sentry
329
364
  @before_send = value
330
365
  end
331
366
 
367
+ def before_send_transaction=(value)
368
+ check_callable!("before_send_transaction", value)
369
+
370
+ @before_send_transaction = value
371
+ end
372
+
332
373
  def before_breadcrumb=(value)
333
374
  check_callable!("before_breadcrumb", value)
334
375
 
@@ -498,16 +539,5 @@ module Sentry
498
539
  instance_eval(&hook)
499
540
  end
500
541
  end
501
-
502
- # allow extensions to add their hooks to the Configuration class
503
- def self.add_post_initialization_callback(&block)
504
- self.post_initialization_callbacks << block
505
- end
506
-
507
- protected
508
-
509
- def self.post_initialization_callbacks
510
- @@post_initialization_callbacks
511
- end
512
542
  end
513
543
  end
data/lib/sentry/redis.rb CHANGED
@@ -54,7 +54,8 @@ module Sentry
54
54
  def parsed_commands
55
55
  commands.map do |statement|
56
56
  command, key, *arguments = statement
57
- command_set = { command: command.to_s.upcase, key: key }
57
+ command_set = { command: command.to_s.upcase }
58
+ command_set[:key] = key if Utils::EncodingHelper.valid_utf_8?(key)
58
59
 
59
60
  if Sentry.configuration.send_default_pii
60
61
  command_set[:arguments] = arguments
@@ -70,19 +71,37 @@ module Sentry
70
71
  "#{host}:#{port}/#{db}"
71
72
  end
72
73
 
73
- module Client
74
+ module OldClientPatch
74
75
  def logging(commands, &block)
75
- Sentry::Redis.new(commands, host, port, db).instrument do
76
- super
77
- end
76
+ Sentry::Redis.new(commands, host, port, db).instrument { super }
77
+ end
78
+ end
79
+
80
+ module GlobalRedisInstrumentation
81
+ def call(command, redis_config)
82
+ Sentry::Redis
83
+ .new([command], redis_config.host, redis_config.port, redis_config.db)
84
+ .instrument { super }
85
+ end
86
+
87
+ def call_pipelined(commands, redis_config)
88
+ Sentry::Redis
89
+ .new(commands, redis_config.host, redis_config.port, redis_config.db)
90
+ .instrument { super }
78
91
  end
79
92
  end
80
93
  end
81
94
  end
82
95
 
83
96
  if defined?(::Redis::Client)
84
- Sentry.register_patch do
85
- patch = Sentry::Redis::Client
86
- Redis::Client.prepend(patch) unless Redis::Client.ancestors.include?(patch)
97
+ if Gem::Version.new(::Redis::VERSION) < Gem::Version.new("5.0")
98
+ Sentry.register_patch do
99
+ patch = Sentry::Redis::OldClientPatch
100
+ unless Redis::Client.ancestors.include?(patch)
101
+ Redis::Client.prepend(patch)
102
+ end
103
+ end
104
+ elsif defined?(RedisClient)
105
+ RedisClient.register(Sentry::Redis::GlobalRedisInstrumentation)
87
106
  end
88
107
  end
data/lib/sentry/scope.rb CHANGED
@@ -58,8 +58,10 @@ module Sentry
58
58
  event.breadcrumbs = breadcrumbs
59
59
  event.rack_env = rack_env if rack_env
60
60
 
61
- unless @event_processors.empty?
62
- @event_processors.each do |processor_block|
61
+ all_event_processors = self.class.global_event_processors + @event_processors
62
+
63
+ unless all_event_processors.empty?
64
+ all_event_processors.each do |processor_block|
63
65
  event = processor_block.call(event, hint)
64
66
  end
65
67
  end
@@ -315,6 +317,22 @@ module Sentry
315
317
  version: RUBY_DESCRIPTION || Sentry.sys_command("ruby -v")
316
318
  }
317
319
  end
320
+
321
+ # Returns the global event processors array.
322
+ # @return [Array<Proc>]
323
+ def global_event_processors
324
+ @global_event_processors ||= []
325
+ end
326
+
327
+ # Adds a new global event processor [Proc].
328
+ # Sometimes we need a global event processor without needing to configure scope.
329
+ # These run before scope event processors.
330
+ #
331
+ # @param block [Proc]
332
+ # @return [void]
333
+ def add_global_event_processor(&block)
334
+ global_event_processors << block
335
+ end
318
336
  end
319
337
 
320
338
  end
data/lib/sentry/span.rb CHANGED
@@ -169,6 +169,10 @@ module Sentry
169
169
  yield(child_span)
170
170
 
171
171
  child_span.finish
172
+ rescue
173
+ child_span.set_http_status(500)
174
+ child_span.finish
175
+ raise
172
176
  end
173
177
 
174
178
  def deep_dup
@@ -25,7 +25,7 @@ module Sentry
25
25
  copied_config.background_worker_threads = 0
26
26
 
27
27
  # user can overwrite some of the configs, with a few exceptions like:
28
- # - capture_exception_frame_locals
28
+ # - include_local_variables
29
29
  # - auto_session_tracking
30
30
  block&.call(copied_config)
31
31
 
@@ -37,6 +37,10 @@ module Sentry
37
37
  # @return [Baggage, nil]
38
38
  attr_reader :baggage
39
39
 
40
+ # The measurements added to the transaction.
41
+ # @return [Hash]
42
+ attr_reader :measurements
43
+
40
44
  # @deprecated Use Sentry.get_current_hub instead.
41
45
  attr_reader :hub
42
46
 
@@ -78,6 +82,7 @@ module Sentry
78
82
  @dsn = hub.configuration.dsn
79
83
  @effective_sample_rate = nil
80
84
  @contexts = {}
85
+ @measurements = {}
81
86
  init_span_recorder
82
87
  end
83
88
 
@@ -163,6 +168,15 @@ module Sentry
163
168
  copy
164
169
  end
165
170
 
171
+ # Sets a custom measurement on the transaction.
172
+ # @param name [String] name of the measurement
173
+ # @param value [Float] value of the measurement
174
+ # @param unit [String] unit of the measurement
175
+ # @return [void]
176
+ def set_measurement(name, value, unit = "")
177
+ @measurements[name] = { value: value, unit: unit }
178
+ end
179
+
166
180
  # Sets initial sampling decision of the transaction.
167
181
  # @param sampling_context [Hash] a context Hash that'll be passed to `traces_sampler` (if provided).
168
182
  # @return [void]
@@ -11,6 +11,9 @@ module Sentry
11
11
  # @return [Hash, nil]
12
12
  attr_accessor :dynamic_sampling_context
13
13
 
14
+ # @return [Hash]
15
+ attr_accessor :measurements
16
+
14
17
  # @return [Float, nil]
15
18
  attr_reader :start_timestamp
16
19
 
@@ -25,6 +28,7 @@ module Sentry
25
28
  self.start_timestamp = transaction.start_timestamp
26
29
  self.tags = transaction.tags
27
30
  self.dynamic_sampling_context = transaction.get_baggage.dynamic_sampling_context
31
+ self.measurements = transaction.measurements
28
32
 
29
33
  finished_spans = transaction.span_recorder.spans.select { |span| span.timestamp && span != transaction }
30
34
  self.spans = finished_spans.map(&:to_hash)
@@ -42,6 +46,7 @@ module Sentry
42
46
  data = super
43
47
  data[:spans] = @spans.map(&:to_hash) if @spans
44
48
  data[:start_timestamp] = @start_timestamp
49
+ data[:measurements] = @measurements
45
50
  data
46
51
  end
47
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.7.0"
4
+ VERSION = "5.8.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -212,7 +212,7 @@ module Sentry
212
212
  nil
213
213
  end
214
214
 
215
- if config.capture_exception_frame_locals
215
+ if config.include_local_variables
216
216
  exception_locals_tp.enable
217
217
  end
218
218
 
@@ -234,7 +234,7 @@ module Sentry
234
234
  @session_flusher = nil
235
235
  end
236
236
 
237
- if configuration&.capture_exception_frame_locals
237
+ if configuration&.include_local_variables
238
238
  exception_locals_tp.disable
239
239
  end
240
240
 
@@ -462,6 +462,23 @@ module Sentry
462
462
  !!exc.instance_variable_get(CAPTURED_SIGNATURE)
463
463
  end
464
464
 
465
+ # Add a global event processor [Proc].
466
+ # These run before scope event processors.
467
+ #
468
+ # @yieldparam event [Event]
469
+ # @yieldparam hint [Hash, nil]
470
+ # @return [void]
471
+ #
472
+ # @example
473
+ # Sentry.add_global_event_processor do |event, hint|
474
+ # event.tags = { foo: 42 }
475
+ # event
476
+ # end
477
+ #
478
+ def add_global_event_processor(&block)
479
+ Scope.add_global_event_processor(&block)
480
+ end
481
+
465
482
  ##### Helpers #####
466
483
 
467
484
  # @!visibility private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.7.0
4
+ version: 5.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2023-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby