sentry-rails 4.1.6 → 4.3.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: 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