sentry-ruby-core 4.1.6 → 4.2.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: 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