sentry-ruby-core 4.1.6 → 4.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 584f6d4758f8c7756443aa2f242e0c8c8d8f34b49089863714ae52b76b18c4af
4
- data.tar.gz: 4a0c8fc92d430a1b8b0726d2cee9c96d4ddc918f99702081c93b5af9b75a53a3
3
+ metadata.gz: f228cdc7c08c8c6de173c997a1e21b28008026280c9d4680b786be20c9d8590e
4
+ data.tar.gz: 871d6e1ba2c6799e18ee4c2c89ce0807ebc79a6018e074f5007e955fc2a5dd78
5
5
  SHA512:
6
- metadata.gz: d1ebaf29b9c6712e7f23ef91cad67e0ddb50fcd2849b45e1fba31e7e7e58acdacbf1f64cb6abb50c1269aa4dedf0e8dd1bd5df7cc8ea83a0be223c2124ab2652
7
- data.tar.gz: 3f2e9ff72da83a8644de0e2ca6cc85b3febaa7a3bd9b84abf10e91047207debfcf83e446ee63216dbfc097947b874cd605ffa89947e162331f33f103b599ae36
6
+ metadata.gz: 4155d1944e86ed17387643ce2325f0fae3c2ea8a9dfd9a020b4bb68e36390b5ef3b5fd74c2b79e68847bc5f7c636e59310d57d8819eaf0a62059e8663358821c
7
+ data.tar.gz: 7d09d5d45d2eb284fc9539d956db09dcf38a42546ccdf1e047872ec7eafdfa052656b13d4ea2cdc523dd1ff069a749f1f3963ab76398587378f2020f995e0c7c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.2.0
4
+
5
+ ### Features
6
+
7
+ - Add configuration option for trusted proxies [#1126](https://github.com/getsentry/sentry-ruby/pull/1126)
8
+
9
+ ```ruby
10
+ config.trusted_proxies = ["2.2.2.2"] # this ip address will be skipped when computing users' ip addresses
11
+ ```
12
+
13
+ - Add ThreadsInterface [#1178](https://github.com/getsentry/sentry-ruby/pull/1178)
14
+
15
+ <img width="1029" alt="an exception event that has the new threads interface" src="https://user-images.githubusercontent.com/5079556/103459223-98b64c00-4d48-11eb-9ebb-ee58f15e647e.png">
16
+
17
+ - Support `config.before_breadcrumb` [#1253](https://github.com/getsentry/sentry-ruby/pull/1253)
18
+
19
+ ```ruby
20
+ # this will be called before every breadcrumb is added to the breadcrumb buffer
21
+ # you can use it to
22
+ # - remove the data you don't want to send
23
+ # - add additional info to the data
24
+ config.before_breadcrumb = lambda do |breadcrumb, hint|
25
+ breadcrumb.message = "foo"
26
+ breadcrumb
27
+ end
28
+ ```
29
+
30
+ - Add ability to have many post initialization callbacks [#1261](https://github.com/getsentry/sentry-ruby/pull/1261)
31
+
32
+ ### Bug Fixes
33
+
34
+ - Inspect exception cause by default & don't exclude ActiveJob::DeserializationError [#1180](https://github.com/getsentry/sentry-ruby/pull/1180)
35
+ - Fixes [#1071](https://github.com/getsentry/sentry-ruby/issues/1071)
36
+
3
37
  ## 4.1.6
4
38
 
5
39
  - Don't detect project root for Rails apps [#1243](https://github.com/getsentry/sentry-ruby/pull/1243)
@@ -140,4 +174,3 @@ Fix require reference
140
174
  ## 0.1.0
141
175
 
142
176
  First version
143
-
data/README.md CHANGED
@@ -160,6 +160,7 @@ config.async = lambda { |event, hint| SentryJob.perform_later(event, hint) }
160
160
 
161
161
  class SentryJob < ActiveJob::Base
162
162
  queue_as :default
163
+ discard_on ActiveJob::DeserializationError # this will prevent infinite loop when there's an issue deserializing SentryJob
163
164
 
164
165
  def perform(event, hint)
165
166
  Sentry.send_event(event, hint)
@@ -167,8 +168,13 @@ class SentryJob < ActiveJob::Base
167
168
  end
168
169
  ```
169
170
 
171
+ If you also use `sentry-rails`, you can directly use the job we defined for you:
170
172
 
171
- **After version 4.1.0**, `sentry-ruby` sends events asynchronously by default. The functionality works like this:
173
+ ```ruby
174
+ config.async = lambda { |event, hint| Sentry::SendEventJob.perform_later(event, hint) }
175
+ ```
176
+
177
+ **After version 4.1.0**, `sentry-ruby` sends events asynchronously by default. The functionality works like this:
172
178
 
173
179
  1. When the SDK is initialized, a `Sentry::BackgroundWorker` will be initialized too.
174
180
  2. When an event is passed to `Client#capture_event`, instead of sending it directly with `Client#send_event`, we'll let the worker do it.
data/lib/sentry/client.rb CHANGED
@@ -60,12 +60,15 @@ module Sentry
60
60
 
61
61
  Event.new(configuration: configuration, integration_meta: integration_meta).tap do |event|
62
62
  event.add_exception_interface(exception)
63
+ event.add_threads_interface(crashed: true)
63
64
  end
64
65
  end
65
66
 
66
67
  def event_from_message(message, hint = {})
67
68
  integration_meta = Sentry.integrations[hint[:integration]]
68
- Event.new(configuration: configuration, integration_meta: integration_meta, message: message)
69
+ event = Event.new(configuration: configuration, integration_meta: integration_meta, message: message)
70
+ event.add_threads_interface(backtrace: caller)
71
+ event
69
72
  end
70
73
 
71
74
  def event_from_transaction(transaction)
@@ -38,10 +38,19 @@ module Sentry
38
38
  #
39
39
  attr_accessor :backtrace_cleanup_callback
40
40
 
41
+ # Optional Proc, called before adding the breadcrumb to the current scope
42
+ # E.g.: lambda { |breadcrumb, hint| breadcrumb }
43
+ # E.g.: lambda { |breadcrumb, hint| nil }
44
+ # E.g.: lambda { |breadcrumb, hint|
45
+ # breadcrumb.message = 'a'
46
+ # breadcrumb
47
+ # }
48
+ attr_reader :before_breadcrumb
49
+
41
50
  # Optional Proc, called before sending an event to the server/
42
- # E.g.: lambda { |event| event }
43
- # E.g.: lambda { |event| nil }
44
- # E.g.: lambda { |event|
51
+ # E.g.: lambda { |event, hint| event }
52
+ # E.g.: lambda { |event, hint| nil }
53
+ # E.g.: lambda { |event, hint|
45
54
  # event[:message] = 'a'
46
55
  # event
47
56
  # }
@@ -109,6 +118,9 @@ module Sentry
109
118
  # will not be sent to Sentry.
110
119
  attr_accessor :send_default_pii
111
120
 
121
+ # IP ranges for trusted proxies that will be skipped when calculating IP address.
122
+ attr_accessor :trusted_proxies
123
+
112
124
  attr_accessor :server_name
113
125
 
114
126
  # Return a Transport::Configuration object for transport-related configurations.
@@ -153,6 +165,10 @@ module Sentry
153
165
 
154
166
  AVAILABLE_BREADCRUMBS_LOGGERS = [:sentry_logger, :active_support_logger].freeze
155
167
 
168
+ # Post initialization callbacks are called at the end of initialization process
169
+ # allowing extending the configuration of sentry-ruby by multiple extensions
170
+ @@post_initialization_callbacks = []
171
+
156
172
  def initialize
157
173
  self.background_worker_threads = Concurrent.processor_count
158
174
  self.breadcrumbs_logger = []
@@ -161,7 +177,7 @@ module Sentry
161
177
  self.enabled_environments = []
162
178
  self.exclude_loggers = []
163
179
  self.excluded_exceptions = IGNORE_DEFAULT.dup
164
- self.inspect_exception_causes_for_exclusion = false
180
+ self.inspect_exception_causes_for_exclusion = true
165
181
  self.linecache = ::Sentry::LineCache.new
166
182
  self.logger = ::Sentry::Logger.new(STDOUT)
167
183
  self.project_root = Dir.pwd
@@ -170,6 +186,7 @@ module Sentry
170
186
  self.sample_rate = 1.0
171
187
  self.send_modules = true
172
188
  self.send_default_pii = false
189
+ self.trusted_proxies = []
173
190
  self.dsn = ENV['SENTRY_DSN']
174
191
  self.server_name = server_name_from_env
175
192
 
@@ -178,7 +195,7 @@ module Sentry
178
195
 
179
196
  @transport = Transport::Configuration.new
180
197
  @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
181
- post_initialization_callback
198
+ run_post_initialization_callbacks
182
199
  end
183
200
 
184
201
  def dsn=(value)
@@ -223,6 +240,14 @@ module Sentry
223
240
  @before_send = value
224
241
  end
225
242
 
243
+ def before_breadcrumb=(value)
244
+ unless value.nil? || value.respond_to?(:call)
245
+ raise ArgumentError, "before_breadcrumb must be callable (or nil to disable)"
246
+ end
247
+
248
+ @before_breadcrumb = value
249
+ end
250
+
226
251
  def environment=(environment)
227
252
  @environment = environment.to_s
228
253
  end
@@ -382,7 +407,21 @@ module Sentry
382
407
  end
383
408
  end
384
409
 
385
- # allow extensions to extend the Configuration class
386
- def post_initialization_callback; end
410
+ def run_post_initialization_callbacks
411
+ self.class.post_initialization_callbacks.each do |hook|
412
+ instance_eval(&hook)
413
+ end
414
+ end
415
+
416
+ # allow extensions to add their hooks to the Configuration class
417
+ def self.add_post_initialization_callback(&block)
418
+ self.post_initialization_callbacks << block
419
+ end
420
+
421
+ protected
422
+
423
+ def self.post_initialization_callbacks
424
+ @@post_initialization_callbacks
425
+ end
387
426
  end
388
427
  end
data/lib/sentry/event.rb CHANGED
@@ -20,7 +20,7 @@ module Sentry
20
20
  MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8
21
21
 
22
22
  attr_accessor(*ATTRIBUTES)
23
- attr_reader :configuration, :request, :exception, :stacktrace
23
+ attr_reader :configuration, :request, :exception, :stacktrace, :threads
24
24
 
25
25
  def initialize(configuration:, integration_meta: nil, message: nil)
26
26
  # this needs to go first because some setters rely on configuration
@@ -102,6 +102,7 @@ module Sentry
102
102
  data[:stacktrace] = stacktrace.to_hash if stacktrace
103
103
  data[:request] = request.to_hash if request
104
104
  data[:exception] = exception.to_hash if exception
105
+ data[:threads] = threads.to_hash if threads
105
106
 
106
107
  data
107
108
  end
@@ -114,6 +115,11 @@ module Sentry
114
115
  @request = Sentry::RequestInterface.from_rack(env)
115
116
  end
116
117
 
118
+ def add_threads_interface(backtrace: nil, **options)
119
+ @threads = ThreadsInterface.new(**options)
120
+ @threads.stacktrace = initialize_stacktrace_interface(backtrace) if backtrace
121
+ end
122
+
117
123
  def add_exception_interface(exc)
118
124
  if exc.respond_to?(:sentry_context)
119
125
  @extra.merge!(exc.sentry_context)
@@ -166,7 +172,8 @@ module Sentry
166
172
  :remote_addr => env["REMOTE_ADDR"],
167
173
  :client_ip => env["HTTP_CLIENT_IP"],
168
174
  :real_ip => env["HTTP_X_REAL_IP"],
169
- :forwarded_for => env["HTTP_X_FORWARDED_FOR"]
175
+ :forwarded_for => env["HTTP_X_FORWARDED_FOR"],
176
+ :trusted_proxies => configuration.trusted_proxies
170
177
  ).calculate_ip
171
178
  end
172
179
  end
data/lib/sentry/hub.rb CHANGED
@@ -120,7 +120,13 @@ module Sentry
120
120
  event
121
121
  end
122
122
 
123
- def add_breadcrumb(breadcrumb)
123
+ def add_breadcrumb(breadcrumb, hint: {})
124
+ if before_breadcrumb = current_client.configuration.before_breadcrumb
125
+ breadcrumb = before_breadcrumb.call(breadcrumb, hint)
126
+ end
127
+
128
+ return unless breadcrumb
129
+
124
130
  current_scope.add_breadcrumb(breadcrumb)
125
131
  end
126
132
 
@@ -20,3 +20,4 @@ require "sentry/interfaces/exception"
20
20
  require "sentry/interfaces/request"
21
21
  require "sentry/interfaces/single_exception"
22
22
  require "sentry/interfaces/stacktrace"
23
+ require "sentry/interfaces/threads"
@@ -0,0 +1,26 @@
1
+ module Sentry
2
+ class ThreadsInterface
3
+ attr_accessor :stacktrace
4
+
5
+ def initialize(crashed: false)
6
+ @id = Thread.current.object_id
7
+ @name = Thread.current.name
8
+ @current = true
9
+ @crashed = crashed
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ values: [
15
+ {
16
+ id: @id,
17
+ name: @name,
18
+ crashed: @crashed,
19
+ current: @current,
20
+ stacktrace: @stacktrace&.to_hash
21
+ }
22
+ ]
23
+ }
24
+ end
25
+ end
26
+ end
@@ -13,8 +13,8 @@ module Sentry
13
13
  "fc00::/7", # private IPv6 range fc00::/7
14
14
  "10.0.0.0/8", # private IPv4 range 10.x.x.x
15
15
  "172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255
16
- "192.168.0.0/16" # private IPv4 range 192.168.x.x
17
- ].map { |proxy| IPAddr.new(proxy) }
16
+ "192.168.0.0/16", # private IPv4 range 192.168.x.x
17
+ ]
18
18
 
19
19
  attr_reader :ip
20
20
 
@@ -22,12 +22,14 @@ module Sentry
22
22
  remote_addr: nil,
23
23
  client_ip: nil,
24
24
  real_ip: nil,
25
- forwarded_for: nil
25
+ forwarded_for: nil,
26
+ trusted_proxies: []
26
27
  )
27
28
  @remote_addr = remote_addr
28
29
  @client_ip = client_ip
29
30
  @real_ip = real_ip
30
31
  @forwarded_for = forwarded_for
32
+ @trusted_proxies = (LOCAL_ADDRESSES + Array(trusted_proxies)).map { |proxy| IPAddr.new(proxy) }.uniq
31
33
  end
32
34
 
33
35
  def calculate_ip
@@ -37,12 +39,16 @@ module Sentry
37
39
  # Could be a CSV list and/or repeated headers that were concatenated.
38
40
  client_ips = ips_from(@client_ip)
39
41
  real_ips = ips_from(@real_ip)
40
- forwarded_ips = ips_from(@forwarded_for)
42
+
43
+ # The first address in this list is the original client, followed by
44
+ # the IPs of successive proxies. We want to search starting from the end
45
+ # until we find the first proxy that we do not trust.
46
+ forwarded_ips = ips_from(@forwarded_for).reverse
41
47
 
42
48
  ips = [client_ips, real_ips, forwarded_ips, remote_addr].flatten.compact
43
49
 
44
50
  # If every single IP option is in the trusted list, just return REMOTE_ADDR
45
- @ip = filter_local_addresses(ips).first || remote_addr
51
+ @ip = filter_trusted_proxy_addresses(ips).first || remote_addr
46
52
  end
47
53
 
48
54
  protected
@@ -62,8 +68,8 @@ module Sentry
62
68
  end
63
69
  end
64
70
 
65
- def filter_local_addresses(ips)
66
- ips.reject { |ip| LOCAL_ADDRESSES.any? { |proxy| proxy === ip } }
71
+ def filter_trusted_proxy_addresses(ips)
72
+ ips.reject { |ip| @trusted_proxies.any? { |proxy| proxy === ip } }
67
73
  end
68
74
  end
69
75
  end
@@ -1,3 +1,3 @@
1
1
  module Sentry
2
- VERSION = "4.1.6"
2
+ VERSION = "4.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.6
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-02 00:00:00.000000000 Z
11
+ date: 2021-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -78,6 +78,7 @@ files:
78
78
  - lib/sentry/interfaces/request.rb
79
79
  - lib/sentry/interfaces/single_exception.rb
80
80
  - lib/sentry/interfaces/stacktrace.rb
81
+ - lib/sentry/interfaces/threads.rb
81
82
  - lib/sentry/linecache.rb
82
83
  - lib/sentry/logger.rb
83
84
  - lib/sentry/rack.rb