sentry-rails 4.9.2 → 5.4.2

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: 6da9817b3be6ac851ff62a6da80d638fc75d4c170825e9a925a7e5be5f973cb1
4
- data.tar.gz: 7f5f80ab0dbf75bbe9773aef1ac180ab014b0f3b19b33983dd3ab38c20ec0f8c
3
+ metadata.gz: 92b1952096935f672e03a41883297d867b70e433c92434b24420062c37d2325f
4
+ data.tar.gz: 3cdfb19c85436bdc509e00512734fe6eb11880bdbe22ef50e6d99908f38daf16
5
5
  SHA512:
6
- metadata.gz: 2e1650da3dc176bb53ff5e47d919996bc8445e80973cb8baef071fcfdf30f237bc73ade309e45d94396926d9f0138c3b2ed4563f8c9cc2238ea00c7204bac032
7
- data.tar.gz: b59164c5df42130717d2217358cf7f072c0fa9fbda35c5361a87ed96a83abf41b32c94ffd3430031c3fe22354e24ee637ebff390651e360bdb328375a3e354da
6
+ metadata.gz: 2271053cd6e6d9f04ba55258d177347f8df8ce74d6c15bdb3083eef6cc3cd1b8f4847c448071c8e03b33d90498acc04f384c4cfe3730c792af046a1860a76a53
7
+ data.tar.gz: 345700856d420c3e562201cedb88d18d396d4f60487bb945f262bffba028ca7f9b12aa481deeebad7607e8f9baa0c4db30308d97a856b45bd7fd0e3f75e06258
data/.gitignore CHANGED
@@ -5,7 +5,7 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
- /spec/support/test_rails_app/db
8
+ /spec/dummy/test_rails_app/db
9
9
  /tmp/
10
10
 
11
11
  # rspec failure tracking
data/Gemfile CHANGED
@@ -1,11 +1,12 @@
1
1
  source "https://rubygems.org"
2
+ git_source(:github) { |name| "https://github.com/#{name}.git" }
2
3
 
3
4
  # Specify your gem's dependencies in sentry-ruby.gemspec
4
5
  gemspec
5
6
  gem "sentry-ruby", path: "../sentry-ruby"
6
7
 
7
8
  rails_version = ENV["RAILS_VERSION"]
8
- rails_version = "6.1.0" if rails_version.nil?
9
+ rails_version = "7.0.0" if rails_version.nil?
9
10
  rails_version = Gem::Version.new(rails_version)
10
11
 
11
12
  gem 'activerecord-jdbcmysql-adapter', platform: :jruby
@@ -17,12 +18,14 @@ else
17
18
  gem "sqlite3", platform: :ruby
18
19
  end
19
20
 
20
- if rails_version >= Gem::Version.new("7.0.0")
21
- gem "rails", github: "rails/rails", branch: "7-0-stable"
21
+ if rails_version > Gem::Version.new("7.0.0")
22
+ gem "rails", github: "rails/rails"
22
23
  else
23
24
  gem "rails", "~> #{rails_version}"
24
25
  end
25
26
 
27
+ gem "mini_magick"
28
+
26
29
  gem "sprockets-rails"
27
30
 
28
31
  gem "sidekiq"
@@ -5,64 +5,81 @@ module Sentry
5
5
  if !Sentry.initialized? || already_supported_by_sentry_integration?
6
6
  super
7
7
  else
8
- Sentry.with_scope do |scope|
9
- capture_and_reraise_with_sentry(scope) do
10
- super
11
- end
8
+ SentryReporter.record(self) do
9
+ super
12
10
  end
13
11
  end
14
12
  end
15
13
 
16
- def capture_and_reraise_with_sentry(scope, &block)
17
- scope.set_transaction_name(self.class.name)
18
- transaction =
19
- if is_a?(::Sentry::SendEventJob)
20
- nil
21
- else
22
- Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
23
- end
24
-
25
- scope.set_span(transaction) if transaction
14
+ def already_supported_by_sentry_integration?
15
+ Sentry.configuration.rails.skippable_job_adapters.include?(self.class.queue_adapter.class.to_s)
16
+ end
26
17
 
27
- return_value = block.call
18
+ class SentryReporter
19
+ class << self
20
+ def record(job, &block)
21
+ Sentry.with_scope do |scope|
22
+ begin
23
+ scope.set_transaction_name(job.class.name)
24
+ transaction =
25
+ if job.is_a?(::Sentry::SendEventJob)
26
+ nil
27
+ else
28
+ Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
29
+ end
28
30
 
29
- finish_sentry_transaction(transaction, 200)
31
+ scope.set_span(transaction) if transaction
30
32
 
31
- return_value
32
- rescue Exception => e # rubocop:disable Lint/RescueException
33
- finish_sentry_transaction(transaction, 500)
33
+ yield.tap do
34
+ finish_sentry_transaction(transaction, 200)
35
+ end
36
+ rescue Exception => e # rubocop:disable Lint/RescueException
37
+ finish_sentry_transaction(transaction, 500)
34
38
 
35
- Sentry::Rails.capture_exception(
36
- e,
37
- extra: sentry_context,
38
- tags: {
39
- job_id: job_id,
40
- provider_job_id:provider_job_id
41
- }
42
- )
43
- raise e
44
- end
39
+ Sentry::Rails.capture_exception(
40
+ e,
41
+ extra: sentry_context(job),
42
+ tags: {
43
+ job_id: job.job_id,
44
+ provider_job_id: job.provider_job_id
45
+ }
46
+ )
47
+ raise
48
+ end
49
+ end
50
+ end
45
51
 
46
- def finish_sentry_transaction(transaction, status)
47
- return unless transaction
52
+ def finish_sentry_transaction(transaction, status)
53
+ return unless transaction
48
54
 
49
- transaction.set_http_status(status)
50
- transaction.finish
51
- end
55
+ transaction.set_http_status(status)
56
+ transaction.finish
57
+ end
52
58
 
53
- def already_supported_by_sentry_integration?
54
- Sentry.configuration.rails.skippable_job_adapters.include?(self.class.queue_adapter.class.to_s)
55
- end
59
+ def sentry_context(job)
60
+ {
61
+ active_job: job.class.name,
62
+ arguments: sentry_serialize_arguments(job.arguments),
63
+ scheduled_at: job.scheduled_at,
64
+ job_id: job.job_id,
65
+ provider_job_id: job.provider_job_id,
66
+ locale: job.locale
67
+ }
68
+ end
56
69
 
57
- def sentry_context
58
- {
59
- active_job: self.class.name,
60
- arguments: arguments,
61
- scheduled_at: scheduled_at,
62
- job_id: job_id,
63
- provider_job_id: provider_job_id,
64
- locale: locale
65
- }
70
+ def sentry_serialize_arguments(argument)
71
+ case argument
72
+ when Hash
73
+ argument.transform_values { |v| sentry_serialize_arguments(v) }
74
+ when Array, Enumerable
75
+ argument.map { |v| sentry_serialize_arguments(v) }
76
+ when ->(v) { v.respond_to?(:to_global_id) }
77
+ argument.to_global_id.to_s rescue argument
78
+ else
79
+ argument
80
+ end
81
+ end
82
+ end
66
83
  end
67
84
  end
68
85
  end
@@ -1,10 +1,10 @@
1
1
  module Sentry
2
2
  class BackgroundWorker
3
3
  def _perform(&block)
4
+ block.call
5
+ ensure
4
6
  # make sure the background worker returns AR connection if it accidentally acquire one during serialization
5
- ActiveRecord::Base.connection_pool.with_connection do
6
- block.call
7
- end
7
+ ActiveRecord::Base.connection_pool.release_connection
8
8
  end
9
9
  end
10
10
  end
@@ -20,14 +20,21 @@ module Sentry
20
20
  "rails.request".freeze
21
21
  end
22
22
 
23
- def capture_exception(exception)
23
+ def capture_exception(exception, env)
24
+ request = ActionDispatch::Request.new(env)
25
+
26
+ # the exception will be swallowed by ShowExceptions middleware
27
+ return if request.show_exceptions? && !Sentry.configuration.rails.report_rescued_exceptions
28
+
24
29
  current_scope = Sentry.get_current_scope
25
30
 
26
- if original_transaction = current_scope.rack_env["sentry.original_transaction"]
31
+ if original_transaction = env["sentry.original_transaction"]
27
32
  current_scope.set_transaction_name(original_transaction)
28
33
  end
29
34
 
30
- Sentry::Rails.capture_exception(exception)
35
+ Sentry::Rails.capture_exception(exception).tap do |event|
36
+ env[ERROR_EVENT_ID_KEY] = event.event_id if event
37
+ end
31
38
  end
32
39
 
33
40
  def start_transaction(env, scope)
@@ -39,7 +46,7 @@ module Sentry
39
46
  end
40
47
 
41
48
  transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, **options) if sentry_trace
42
- Sentry.start_transaction(transaction: transaction, **options)
49
+ Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
43
50
  end
44
51
  end
45
52
  end
@@ -42,6 +42,12 @@ module Sentry
42
42
  'ActiveRecord::RecordNotFound'
43
43
  ].freeze
44
44
  class Configuration
45
+ # Rails 7.0 introduced a new error reporter feature, which the SDK once opted-in by default.
46
+ # But after receiving multiple issue reports, the integration seemed to cause serious troubles to some users.
47
+ # So the integration is now controlled by this configuration, which is disabled (false) by default.
48
+ # More information can be found from: https://github.com/rails/rails/pull/43625#issuecomment-1072514175
49
+ attr_accessor :register_error_subscriber
50
+
45
51
  # Rails catches exceptions in the ActionDispatch::ShowExceptions or
46
52
  # ActionDispatch::DebugExceptions middlewares, depending on the environment.
47
53
  # When `rails_report_rescued_exceptions` is true (it is by default), Sentry
@@ -55,6 +61,7 @@ module Sentry
55
61
  attr_accessor :tracing_subscribers
56
62
 
57
63
  def initialize
64
+ @register_error_subscriber = false
58
65
  @report_rescued_exceptions = true
59
66
  @skippable_job_adapters = []
60
67
  @tracing_subscribers = Set.new([
@@ -0,0 +1,20 @@
1
+ module Sentry
2
+ module Rails
3
+ # This is not a user-facing class. You should use it with Rails 7.0's error reporter feature and its interfaces.
4
+ # See https://github.com/rails/rails/blob/main/activesupport/lib/active_support/error_reporter.rb for more information.
5
+ class ErrorSubscriber
6
+ SKIP_SOURCES = Regexp.union([/.*_cache_store.active_support/])
7
+
8
+ def report(error, handled:, severity:, context:, source: nil)
9
+ tags = { handled: handled }
10
+
11
+ if source
12
+ return if SKIP_SOURCES.match?(source)
13
+ tags[:source] = source
14
+ end
15
+
16
+ Sentry::Rails.capture_exception(error, level: severity, contexts: { "rails.error" => context }, tags: tags)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -46,11 +46,18 @@ module Sentry
46
46
  setup_backtrace_cleanup_callback
47
47
  inject_breadcrumbs_logger
48
48
  activate_tracing
49
+
50
+ register_error_subscriber(app) if ::Rails.version.to_f >= 7.0 && Sentry.configuration.rails.register_error_subscriber
49
51
  end
50
52
 
51
53
  runner do
52
54
  next unless Sentry.initialized?
53
55
  Sentry.configuration.background_worker_threads = 0
56
+
57
+ at_exit do
58
+ # TODO: Add a condition for Rails 7.1 to avoid confliction with https://github.com/rails/rails/pull/44999
59
+ Sentry::Rails.capture_exception($ERROR_INFO, tags: { source: "runner" }) if $ERROR_INFO
60
+ end
54
61
  end
55
62
 
56
63
  def configure_project_root
@@ -115,5 +122,10 @@ module Sentry
115
122
  Sentry::Rails::Tracing.patch_active_support_notifications
116
123
  end
117
124
  end
125
+
126
+ def register_error_subscriber(app)
127
+ require "sentry/rails/error_subscriber"
128
+ app.executor.error_reporter.subscribe(Sentry::Rails::ErrorSubscriber.new)
129
+ end
118
130
  end
119
131
  end
@@ -40,15 +40,12 @@ module Sentry
40
40
  def record_on_current_span(duration:, **options)
41
41
  return unless options[:start_timestamp]
42
42
 
43
- scope = Sentry.get_current_scope
44
- transaction = scope.get_transaction
45
- return unless transaction && transaction.sampled
46
-
47
- span = transaction.start_child(**options)
48
- # duration in ActiveSupport is computed in millisecond
49
- # so we need to covert it as second before calculating the timestamp
50
- span.set_timestamp(span.start_timestamp + duration / 1000)
51
- yield(span) if block_given?
43
+ Sentry.with_child_span(**options) do |child_span|
44
+ # duration in ActiveSupport is computed in millisecond
45
+ # so we need to covert it as second before calculating the timestamp
46
+ child_span.set_timestamp(child_span.start_timestamp + duration / 1000)
47
+ yield(child_span) if block_given?
48
+ end
52
49
  end
53
50
  end
54
51
  end
@@ -5,10 +5,11 @@ module Sentry
5
5
  module Tracing
6
6
  class ActionViewSubscriber < AbstractSubscriber
7
7
  EVENT_NAMES = ["render_template.action_view"].freeze
8
+ SPAN_PREFIX = "template.".freeze
8
9
 
9
10
  def self.subscribe!
10
11
  subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
11
- record_on_current_span(op: event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:identifier], duration: duration)
12
+ record_on_current_span(op: SPAN_PREFIX + event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:identifier], duration: duration)
12
13
  end
13
14
  end
14
15
  end
@@ -5,13 +5,14 @@ module Sentry
5
5
  module Tracing
6
6
  class ActiveRecordSubscriber < AbstractSubscriber
7
7
  EVENT_NAMES = ["sql.active_record"].freeze
8
+ SPAN_PREFIX = "db.".freeze
8
9
  EXCLUDED_EVENTS = ["SCHEMA", "TRANSACTION"].freeze
9
10
 
10
11
  def self.subscribe!
11
12
  subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
12
13
  next if EXCLUDED_EVENTS.include? payload[:name]
13
14
 
14
- record_on_current_span(op: event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:sql], duration: duration) do |span|
15
+ record_on_current_span(op: SPAN_PREFIX + event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:sql], duration: duration) do |span|
15
16
  span.set_data(:connection_id, payload[:connection_id])
16
17
  end
17
18
  end
@@ -1,5 +1,5 @@
1
1
  module Sentry
2
2
  module Rails
3
- VERSION = "4.9.2"
3
+ VERSION = "5.4.2"
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 "railties", ">= 5.0"
26
- spec.add_dependency "sentry-ruby-core", "~> 4.9.2"
26
+ spec.add_dependency "sentry-ruby", "~> 5.4.2"
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.9.2
4
+ version: 5.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-18 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: sentry-ruby-core
28
+ name: sentry-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.9.2
33
+ version: 5.4.2
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.9.2
40
+ version: 5.4.2
41
41
  description: A gem that provides Rails integration for the Sentry error logger
42
42
  email: accounts@sentry.io
43
43
  executables: []
@@ -71,6 +71,7 @@ files:
71
71
  - lib/sentry/rails/controller_methods.rb
72
72
  - lib/sentry/rails/controller_transaction.rb
73
73
  - lib/sentry/rails/engine.rb
74
+ - lib/sentry/rails/error_subscriber.rb
74
75
  - lib/sentry/rails/instrument_payload_cleanup_helper.rb
75
76
  - lib/sentry/rails/overrides/streaming_reporter.rb
76
77
  - lib/sentry/rails/railtie.rb