sentry-rails 4.1.6 → 4.3.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: 577efe95018b382a927d9078662707a033c579fa37757467e9cbdbead6ddadb1
4
- data.tar.gz: d99a6385af1d142f446649bd4df596299c8ace976ca333313897335e3dabe44f
3
+ metadata.gz: 7f1aafc591c356c77484bf061be1d4f8968588270e083d6ee94ada2f80054282
4
+ data.tar.gz: 74e40b15bdc17962037fd2b78b6695de5a405335a186f373c644dcb61b75aab6
5
5
  SHA512:
6
- metadata.gz: 899fd5096e17f61dc6d0186cdcb87c93c555dce397bd5c4e4ade88fd704e320290e7fb2a7cbfebb9eaf21a188e6e3823d0f7e298db645eb438110d93831d7d1e
7
- data.tar.gz: 1f16fc8dd1e35c38d7a6b78449ae586bae30d9f611c98d43cb6f497f7a21accb84d6552f7eaddb41a0cb32adb01b597b67e41173266f27c562b8242a7291ae7d
6
+ metadata.gz: 279ad65af3f35928746b8365bc494bf0384fde465414c1211cb565289bb7cbf1157c0649da6c835e4bbb79b928005eebba2805f387a52a57170bba876279b0fb
7
+ data.tar.gz: 6bf36d990e2c7f3ab51d8e5bb6bd2ec6873d924f2baa72796145502b2b4f04eea055c8c22a06a6bb8f0cbe92b2c92b15a7e29262f21252fce98be579f7e3fc38
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
+ /spec/support/test_rails_app/db
8
9
  /tmp/
9
10
 
10
11
  # rspec failure tracking
data/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.3.0
4
+
5
+ ### Features
6
+
7
+ - Support performance monitoring on ActiveJob execution [#1304](https://github.com/getsentry/sentry-ruby/pull/1304)
8
+
9
+ ### Bug Fixes
10
+
11
+ - Prevent background workers from holding ActiveRecord connections [#1320](https://github.com/getsentry/sentry-ruby/pull/1320)
12
+
13
+ ## 4.2.2
14
+
15
+ - Always define Sentry::SendEventJob to avoid eager load issues [#1286](https://github.com/getsentry/sentry-ruby/pull/1286)
16
+ - Fixes [#1283](https://github.com/getsentry/sentry-ruby/issues/1283)
17
+
18
+ ## 4.2.1
19
+
20
+ - Add additional checks to SendEventJob's definition [#1275](https://github.com/getsentry/sentry-ruby/pull/1275)
21
+ - Fixes [#1270](https://github.com/getsentry/sentry-ruby/issues/1270)
22
+ - Fixes [#1277](https://github.com/getsentry/sentry-ruby/issues/1277)
23
+
24
+ ## 4.2.0
25
+
26
+ ### Features
27
+
28
+ - Make sentry-rails a Rails engine and provide default job class for async [#1181](https://github.com/getsentry/sentry-ruby/pull/1181)
29
+
30
+ `sentry-rails` now provides a default ActiveJob class for sending events asynchronously. You can use it directly without define your own one:
31
+
32
+ ```ruby
33
+ config.async = lambda { |event, hint| Sentry::SendEventJob.perform_later(event, hint) }
34
+ ```
35
+
36
+ - Add configuration option for trusted proxies [#1126](https://github.com/getsentry/sentry-ruby/pull/1126)
37
+
38
+ `sentry-rails` now injects `Rails.application.config.action_dispatch.trusted_proxies` into `Sentry.configuration.trusted_proxies` automatically.
39
+
40
+ - Allow users to configure ActiveJob adapters to ignore [#1256](https://github.com/getsentry/sentry-ruby/pull/1256)
41
+
42
+ ```ruby
43
+ # sentry-rails will skip active_job reporting for jobs that use ActiveJob::QueueAdapters::SidekiqAdapter
44
+ # you should use this option when:
45
+ # - you don't want to see events from a certain adapter
46
+ # - you already have a better reporting setup for the adapter (like having `sentry-sidekiq` installed)
47
+ config.rails.skippable_job_adapters = ["ActiveJob::QueueAdapters::SidekiqAdapter"]
48
+ ```
49
+
50
+ - Tag `job_id` and `provider_job_id` on ActiveJob events [#1259](https://github.com/getsentry/sentry-ruby/pull/1259)
51
+
52
+ <img width="1330" alt="example of tagged event" src="https://user-images.githubusercontent.com/5079556/106389781-3a03f100-6420-11eb-810c-a99869eb26dd.png">
53
+
54
+ - Use another method for post initialization callback [#1261](https://github.com/getsentry/sentry-ruby/pull/1261)
55
+
56
+ ### Bug Fixes
57
+
58
+ - Inspect exception cause by default & don't exclude ActiveJob::DeserializationError [#1180](https://github.com/getsentry/sentry-ruby/pull/1180)
59
+ - Fixes [#1071](https://github.com/getsentry/sentry-ruby/issues/1071)
60
+
61
+ ## 4.1.7
62
+
63
+ - Use env to carry original transaction name [#1255](https://github.com/getsentry/sentry-ruby/pull/1255)
64
+ - Fix duration of tracing event in Rails 5 [#1254](https://github.com/getsentry/sentry-ruby/pull/1254) (by @abcang)
65
+ - Filter out static file transaction [#1247](https://github.com/getsentry/sentry-ruby/pull/1247)
66
+
3
67
  ## 4.1.6
4
68
 
5
69
  - Prevent exceptions app from overriding event's transaction name [#1230](https://github.com/getsentry/sentry-ruby/pull/1230)
@@ -69,4 +133,3 @@ Release test
69
133
  ## 0.1.0
70
134
 
71
135
  First version
72
-
data/Gemfile CHANGED
@@ -8,15 +8,24 @@ rails_version = "6.1.0" if rails_version.nil?
8
8
 
9
9
  gem 'activerecord-jdbcmysql-adapter', platform: :jruby
10
10
  gem "jdbc-sqlite3", platform: :jruby
11
- gem "sqlite3", platform: :ruby
11
+
12
+ if rails_version.to_f < 6
13
+ gem "sqlite3", "~> 1.3.0", platform: :ruby
14
+ else
15
+ gem "sqlite3", platform: :ruby
16
+ end
12
17
 
13
18
  gem "rails", "~> #{rails_version}"
19
+ gem "sprockets-rails"
14
20
  gem "rspec-rails", "~> 4.0"
15
21
  gem "codecov", "0.2.12"
16
22
 
17
23
  gem "rake", "~> 12.0"
18
24
  gem "rspec", "~> 3.0"
19
25
 
26
+ # TODO: Remove this if https://github.com/jruby/jruby/issues/6547 is addressed
27
+ gem "i18n", "<= 1.8.7"
28
+
20
29
  gem "sidekiq"
21
30
 
22
31
  gem "sentry-ruby", path: "../sentry-ruby"
@@ -0,0 +1,34 @@
1
+ if defined?(ActiveJob)
2
+ module Sentry
3
+ parent_job =
4
+ if defined?(::ApplicationJob) && ::ApplicationJob.ancestors.include?(::ActiveJob::Base)
5
+ ::ApplicationJob
6
+ else
7
+ ::ActiveJob::Base
8
+ end
9
+
10
+ class SendEventJob < parent_job
11
+ # the event argument is usually large and creates noise
12
+ self.log_arguments = false if respond_to?(:log_arguments=)
13
+
14
+ # this will prevent infinite loop when there's an issue deserializing SentryJob
15
+ if respond_to?(:discard_on)
16
+ discard_on ActiveJob::DeserializationError
17
+ else
18
+ # mimic what discard_on does for Rails 5.0
19
+ rescue_from ActiveJob::DeserializationError do
20
+ logger.error "Discarded #{self.class} due to a #{exception}. The original exception was #{error.cause.inspect}."
21
+ end
22
+ end
23
+
24
+ def perform(event, hint = {})
25
+ Sentry.send_event(event, hint)
26
+ end
27
+ end
28
+ end
29
+ else
30
+ module Sentry
31
+ class SendEventJob; end
32
+ end
33
+ end
34
+
data/lib/sentry/rails.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "sentry-ruby"
2
2
  require "sentry/integrable"
3
+ require "sentry/rails/background_worker"
3
4
  require "sentry/rails/configuration"
5
+ require "sentry/rails/engine"
4
6
  require "sentry/rails/railtie"
5
7
  require "sentry/rails/tracing"
6
8
 
@@ -1,10 +1,6 @@
1
1
  module Sentry
2
2
  module Rails
3
3
  module ActiveJobExtensions
4
- ALREADY_SUPPORTED_SENTRY_ADAPTERS = %w(
5
- ActiveJob::QueueAdapters::SidekiqAdapter
6
- ).freeze
7
-
8
4
  def self.included(base)
9
5
  base.class_eval do
10
6
  around_perform do |job, block|
@@ -12,8 +8,8 @@ module Sentry
12
8
  if already_supported_by_specific_integration?(job)
13
9
  block.call
14
10
  else
15
- Sentry.with_scope do
16
- capture_and_reraise_with_sentry(job, block)
11
+ Sentry.with_scope do |scope|
12
+ capture_and_reraise_with_sentry(job, scope, block)
17
13
  end
18
14
  end
19
15
  else
@@ -23,34 +19,51 @@ module Sentry
23
19
  end
24
20
  end
25
21
 
26
- def capture_and_reraise_with_sentry(job, block)
22
+ def capture_and_reraise_with_sentry(job, scope, block)
23
+ scope.set_transaction_name(job.class.name)
24
+ transaction = Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
25
+
26
+ scope.set_span(transaction) if transaction
27
+
27
28
  block.call
29
+
30
+ finish_transaction(transaction, 200)
28
31
  rescue Exception => e # rubocop:disable Lint/RescueException
29
32
  rescue_handler_result = rescue_with_handler(e)
33
+ finish_transaction(transaction, 500)
30
34
  return rescue_handler_result if rescue_handler_result
31
35
 
32
- Sentry::Rails.capture_exception(e, extra: sentry_context(job))
36
+ Sentry::Rails.capture_exception(
37
+ e,
38
+ extra: sentry_context(job),
39
+ tags: {
40
+ job_id: job.job_id,
41
+ provider_job_id: job.provider_job_id
42
+ }
43
+ )
33
44
  raise e
34
45
  end
35
46
 
47
+ def finish_transaction(transaction, status)
48
+ return unless transaction
49
+
50
+ transaction.set_http_status(status)
51
+ transaction.finish
52
+ end
53
+
36
54
  def already_supported_by_specific_integration?(job)
37
- ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.class.to_s)
55
+ Sentry.configuration.rails.skippable_job_adapters.include?(job.class.queue_adapter.class.to_s)
38
56
  end
39
57
 
40
58
  def sentry_context(job)
41
- ctx = {
42
- :active_job => job.class.name,
43
- :arguments => job.arguments,
44
- :scheduled_at => job.scheduled_at,
45
- :job_id => job.job_id,
46
- :locale => job.locale
59
+ {
60
+ active_job: job.class.name,
61
+ arguments: job.arguments,
62
+ scheduled_at: job.scheduled_at,
63
+ job_id: job.job_id,
64
+ provider_job_id: job.provider_job_id,
65
+ locale: job.locale
47
66
  }
48
- # Add provider_job_id details if Rails 5
49
- if job.respond_to?(:provider_job_id)
50
- ctx[:provider_job_id] = job.provider_job_id
51
- end
52
-
53
- ctx
54
67
  end
55
68
  end
56
69
  end
@@ -0,0 +1,14 @@
1
+ module Sentry
2
+ class BackgroundWorker
3
+ alias_method :original_perform, :perform
4
+
5
+ def perform(&block)
6
+ @executor.post do
7
+ # make sure the background worker returns AR connection if it accidentally acquire one during serialization
8
+ ActiveRecord::Base.connection_pool.with_connection do
9
+ block.call
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,6 +1,14 @@
1
1
  module Sentry
2
2
  module Rails
3
3
  class CaptureExceptions < Sentry::Rack::CaptureExceptions
4
+ def initialize(app)
5
+ super
6
+
7
+ if defined?(::Sprockets::Rails)
8
+ @assets_regex = %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
9
+ end
10
+ end
11
+
4
12
  private
5
13
 
6
14
  def collect_exception(env)
@@ -12,8 +20,26 @@ module Sentry
12
20
  end
13
21
 
14
22
  def capture_exception(exception)
23
+ current_scope = Sentry.get_current_scope
24
+
25
+ if original_transaction = current_scope.rack_env["sentry.original_transaction"]
26
+ current_scope.set_transaction_name(original_transaction)
27
+ end
28
+
15
29
  Sentry::Rails.capture_exception(exception)
16
30
  end
31
+
32
+ def start_transaction(env, scope)
33
+ transaction = super
34
+
35
+ return unless transaction
36
+
37
+ if @assets_regex && transaction.name.match?(@assets_regex)
38
+ transaction.instance_variable_set(:@sampled, false)
39
+ end
40
+
41
+ transaction
42
+ end
17
43
  end
18
44
  end
19
45
  end
@@ -2,7 +2,7 @@ module Sentry
2
2
  class Configuration
3
3
  attr_reader :rails
4
4
 
5
- def post_initialization_callback
5
+ add_post_initialization_callback do
6
6
  @rails = Sentry::Rails::Configuration.new
7
7
  @excluded_exceptions = @excluded_exceptions.concat(Sentry::Rails::IGNORE_DEFAULT)
8
8
  end
@@ -23,7 +23,6 @@ module Sentry
23
23
  'ActionDispatch::Http::MimeNegotiation::InvalidType',
24
24
  'ActionController::UnknownHttpMethod',
25
25
  'ActionDispatch::Http::Parameters::ParseError',
26
- 'ActiveJob::DeserializationError', # Can cause infinite loops
27
26
  'ActiveRecord::RecordNotFound'
28
27
  ].freeze
29
28
  class Configuration
@@ -33,8 +32,14 @@ module Sentry
33
32
  # will report exceptions even when they are rescued by these middlewares.
34
33
  attr_accessor :report_rescued_exceptions
35
34
 
35
+ # Some adapters, like sidekiq, already have their own sentry integration.
36
+ # In those cases, we should skip ActiveJob's reporting to avoid duplicated reports.
37
+ attr_accessor :skippable_job_adapters
38
+
36
39
  def initialize
37
40
  @report_rescued_exceptions = true
41
+ # TODO: Remove this in 4.2.0
42
+ @skippable_job_adapters = []
38
43
  end
39
44
  end
40
45
  end
@@ -0,0 +1,5 @@
1
+ module Sentry
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Sentry
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ module Sentry
2
+ module Rails
3
+ module Overrides
4
+ module FileHandler
5
+ def serve(*args)
6
+ if Sentry.initialized? && current_transaction = Sentry.get_current_scope.span
7
+ # we don't want to expose a setter for @sampled just for this case
8
+ current_transaction.instance_variable_set(:@sampled, false)
9
+ end
10
+
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,6 +5,7 @@ require "sentry/rails/backtrace_cleaner"
5
5
  require "sentry/rails/controller_methods"
6
6
  require "sentry/rails/controller_transaction"
7
7
  require "sentry/rails/overrides/streaming_reporter"
8
+ require "sentry/rails/overrides/file_handler"
8
9
 
9
10
  module Sentry
10
11
  class Railtie < ::Rails::Railtie
@@ -16,14 +17,16 @@ module Sentry
16
17
  app.config.middleware.use(Sentry::Rails::RescuedExceptionInterceptor)
17
18
  end
18
19
 
19
- config.after_initialize do
20
+ config.after_initialize do |app|
20
21
  next unless Sentry.initialized?
21
22
 
22
23
  configure_project_root
23
24
  configure_sentry_logger
25
+ configure_trusted_proxies
24
26
  extend_controller_methods
25
27
  extend_active_job if defined?(ActiveJob)
26
28
  override_streaming_reporter
29
+ override_file_handler if app.config.public_file_server.enabled
27
30
  setup_backtrace_cleanup_callback
28
31
  inject_breadcrumbs_logger
29
32
  activate_tracing
@@ -37,6 +40,10 @@ module Sentry
37
40
  Sentry.configuration.logger = ::Rails.logger
38
41
  end
39
42
 
43
+ def configure_trusted_proxies
44
+ Sentry.configuration.trusted_proxies += Array(::Rails.application.config.action_dispatch.trusted_proxies)
45
+ end
46
+
40
47
  def extend_active_job
41
48
  require "sentry/rails/active_job"
42
49
  ActiveJob::Base.send(:prepend, Sentry::Rails::ActiveJobExtensions)
@@ -71,6 +78,12 @@ module Sentry
71
78
  end
72
79
  end
73
80
 
81
+ def override_file_handler
82
+ ActiveSupport.on_load :action_controller do
83
+ ActionDispatch::FileHandler.send(:prepend, Sentry::Rails::Overrides::FileHandler)
84
+ end
85
+ end
86
+
74
87
  def activate_tracing
75
88
  if Sentry.configuration.tracing_enabled?
76
89
  Sentry::Rails::Tracing.subscribe_tracing_events
@@ -17,14 +17,9 @@ module Sentry
17
17
  # so we need to hold a copy of env to report the accurate data (like request's url)
18
18
  if request.show_exceptions?
19
19
  scope = Sentry.get_current_scope
20
- scope.set_rack_env(scope.rack_env.dup)
21
- transaction = scope.transaction_name
22
-
23
- # we also need to make sure the transaction name won't be overridden by the exceptions app
24
- scope.add_event_processor do |event, hint|
25
- event.transaction = transaction
26
- event
27
- end
20
+ copied_env = scope.rack_env.dup
21
+ copied_env["sentry.original_transaction"] = scope.transaction_name
22
+ scope.set_rack_env(copied_env)
28
23
  end
29
24
 
30
25
  env["sentry.rescued_exception"] = e if Sentry.configuration.rails.report_rescued_exceptions
@@ -14,11 +14,11 @@ module Sentry
14
14
 
15
15
  def subscribe_to_event(event_name)
16
16
  if ::Rails.version.to_i == 5
17
- ActiveSupport::Notifications.subscribe(event_name) do |_, start, finish, _, payload|
17
+ ActiveSupport::Notifications.subscribe(event_name) do |*args|
18
18
  next unless Tracing.get_current_transaction
19
19
 
20
- duration = finish.to_f - start.to_f
21
- yield(event_name, duration, payload)
20
+ event = ActiveSupport::Notifications::Event.new(*args)
21
+ yield(event_name, event.duration, event.payload)
22
22
  end
23
23
  else
24
24
  ActiveSupport::Notifications.subscribe(event_name) do |event|
@@ -1,5 +1,5 @@
1
1
  module Sentry
2
2
  module Rails
3
- VERSION = "4.1.6"
3
+ VERSION = "4.3.0"
4
4
  end
5
5
  end
data/sentry-rails.gemspec CHANGED
@@ -23,5 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "rails", ">= 5.0"
26
- spec.add_dependency "sentry-ruby-core", "~> 4.1.2"
26
+ spec.add_dependency "sentry-ruby-core", "~> 4.3.0"
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.6
4
+ version: 4.3.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-01-28 00:00:00.000000000 Z
11
+ date: 2021-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.1.2
33
+ version: 4.3.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.1.2
40
+ version: 4.3.0
41
41
  description: A gem that provides Rails integration for the Sentry error logger
42
42
  email: accounts@sentry.io
43
43
  executables: []
@@ -56,17 +56,21 @@ files:
56
56
  - Makefile
57
57
  - README.md
58
58
  - Rakefile
59
+ - app/jobs/sentry/send_event_job.rb
59
60
  - bin/console
60
61
  - bin/setup
61
62
  - lib/sentry-rails.rb
62
63
  - lib/sentry/rails.rb
63
64
  - lib/sentry/rails/active_job.rb
65
+ - lib/sentry/rails/background_worker.rb
64
66
  - lib/sentry/rails/backtrace_cleaner.rb
65
67
  - lib/sentry/rails/breadcrumb/active_support_logger.rb
66
68
  - lib/sentry/rails/capture_exceptions.rb
67
69
  - lib/sentry/rails/configuration.rb
68
70
  - lib/sentry/rails/controller_methods.rb
69
71
  - lib/sentry/rails/controller_transaction.rb
72
+ - lib/sentry/rails/engine.rb
73
+ - lib/sentry/rails/overrides/file_handler.rb
70
74
  - lib/sentry/rails/overrides/streaming_reporter.rb
71
75
  - lib/sentry/rails/railtie.rb
72
76
  - lib/sentry/rails/rescued_exception_interceptor.rb