sentry-rails 4.7.2 → 4.8.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: 601a533a33e665e2a7b470eead7e2598827189e985903fb78c0391d9a446ddeb
4
- data.tar.gz: e33f1dae2e5d5305432f8fcec69bd26daef8217adf582e6d6747ab1bdb79b112
3
+ metadata.gz: 64f471f2aff155e81f92c86c0dd054200366be64a8d3490fd55b4a25dc3143cb
4
+ data.tar.gz: 2a9504b5dbb3960d4a8115422bcaa837f1c8c725e53315daeab4a279e306c781
5
5
  SHA512:
6
- metadata.gz: e459f55b49f1b468ee151f5094e3e2bcc28ba6289f86ec83e69c00b2205c37982f34f4922c3c97af72a02902379c61b3a7bb2cb30cf6f6d8972fc2dbba70eeb2
7
- data.tar.gz: 794f8644fe6499cdeeb7bba75e9bf899629afe77ebbd0daca6dd587b8270b53c386f5bbcdae393d747341d3c758983520546e519aecfe23f6c31d94371e76375
6
+ metadata.gz: 8f30474068722a83f53855b9f637ea85834e2d075a625216ea8405c45d919ff43af25322ad7d6b4c104c2a845ad5da183923dffad5e6413d4f443e9ef89ebf30
7
+ data.tar.gz: '09002189531ad1ad22757d3b20cda8a9df782eb7a9bdf07499a3f9d6d9e6a17d1d57120e7519f6f9408e1836c99b369919cfb01c1c23e614ebf76fdc37425ee6'
data/Gemfile CHANGED
@@ -24,12 +24,14 @@ gem "sidekiq"
24
24
  gem "rspec", "~> 3.0"
25
25
  gem "rspec-retry"
26
26
  gem "rspec-rails", "~> 4.0"
27
- gem "codecov", "0.2.12"
27
+ gem 'simplecov'
28
+ gem "simplecov-cobertura", "~> 1.4"
29
+ gem "rexml"
28
30
 
29
31
  gem "rake", "~> 12.0"
30
32
 
31
33
  gem "object_tracer"
32
- gem "debug", github: "ruby/debug" if RUBY_VERSION.to_f >= 2.6
34
+ gem "debug", github: "ruby/debug", platform: :ruby if RUBY_VERSION.to_f >= 2.6
33
35
  gem "pry"
34
36
 
35
37
  gem "benchmark-ips"
@@ -16,8 +16,8 @@ if defined?(ActiveJob)
16
16
  discard_on ActiveJob::DeserializationError
17
17
  else
18
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}."
19
+ rescue_from ActiveJob::DeserializationError do |exception|
20
+ logger.error "Discarded #{self.class} due to a #{exception}. The original exception was #{exception.cause.inspect}."
21
21
  end
22
22
  end
23
23
 
@@ -1,28 +1,22 @@
1
1
  module Sentry
2
2
  module Rails
3
3
  module ActiveJobExtensions
4
- def self.included(base)
5
- base.class_eval do
6
- around_perform do |job, block|
7
- if Sentry.initialized?
8
- if already_supported_by_specific_integration?(job)
9
- block.call
10
- else
11
- Sentry.with_scope do |scope|
12
- capture_and_reraise_with_sentry(job, scope, block)
13
- end
14
- end
15
- else
16
- block.call
4
+ def perform_now
5
+ if !Sentry.initialized? || already_supported_by_sentry_integration?
6
+ super
7
+ else
8
+ Sentry.with_scope do |scope|
9
+ capture_and_reraise_with_sentry(scope) do
10
+ super
17
11
  end
18
12
  end
19
13
  end
20
14
  end
21
15
 
22
- def capture_and_reraise_with_sentry(job, scope, block)
23
- scope.set_transaction_name(job.class.name)
16
+ def capture_and_reraise_with_sentry(scope, &block)
17
+ scope.set_transaction_name(self.class.name)
24
18
  transaction =
25
- if job.is_a?(::Sentry::SendEventJob)
19
+ if is_a?(::Sentry::SendEventJob)
26
20
  nil
27
21
  else
28
22
  Sentry.start_transaction(name: scope.transaction_name, op: "active_job")
@@ -32,48 +26,42 @@ module Sentry
32
26
 
33
27
  block.call
34
28
 
35
- finish_transaction(transaction, 200)
29
+ finish_sentry_transaction(transaction, 200)
36
30
  rescue Exception => e # rubocop:disable Lint/RescueException
37
- rescue_handler_result = rescue_with_handler(e)
38
- finish_transaction(transaction, 500)
39
- return rescue_handler_result if rescue_handler_result
31
+ finish_sentry_transaction(transaction, 500)
40
32
 
41
33
  Sentry::Rails.capture_exception(
42
34
  e,
43
- extra: sentry_context(job),
35
+ extra: sentry_context,
44
36
  tags: {
45
- job_id: job.job_id,
46
- provider_job_id: job.provider_job_id
37
+ job_id: job_id,
38
+ provider_job_id:provider_job_id
47
39
  }
48
40
  )
49
41
  raise e
50
42
  end
51
43
 
52
- def finish_transaction(transaction, status)
44
+ def finish_sentry_transaction(transaction, status)
53
45
  return unless transaction
54
46
 
55
47
  transaction.set_http_status(status)
56
48
  transaction.finish
57
49
  end
58
50
 
59
- def already_supported_by_specific_integration?(job)
60
- Sentry.configuration.rails.skippable_job_adapters.include?(job.class.queue_adapter.class.to_s)
51
+ def already_supported_by_sentry_integration?
52
+ Sentry.configuration.rails.skippable_job_adapters.include?(self.class.queue_adapter.class.to_s)
61
53
  end
62
54
 
63
- def sentry_context(job)
55
+ def sentry_context
64
56
  {
65
- active_job: job.class.name,
66
- arguments: job.arguments,
67
- scheduled_at: job.scheduled_at,
68
- job_id: job.job_id,
69
- provider_job_id: job.provider_job_id,
70
- locale: job.locale
57
+ active_job: self.class.name,
58
+ arguments: arguments,
59
+ scheduled_at: scheduled_at,
60
+ job_id: job_id,
61
+ provider_job_id: provider_job_id,
62
+ locale: locale
71
63
  }
72
64
  end
73
65
  end
74
66
  end
75
67
  end
76
-
77
- class ActiveJob::Base
78
- include Sentry::Rails::ActiveJobExtensions
79
- end
@@ -1,11 +1,9 @@
1
1
  module Sentry
2
2
  class BackgroundWorker
3
- def perform(&block)
4
- @executor.post do
5
- # make sure the background worker returns AR connection if it accidentally acquire one during serialization
6
- ActiveRecord::Base.connection_pool.with_connection do
7
- block.call
8
- end
3
+ def _perform(&block)
4
+ # 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
9
7
  end
10
8
  end
11
9
  end
@@ -1,6 +1,7 @@
1
1
  require "sentry/rails/tracing/action_controller_subscriber"
2
2
  require "sentry/rails/tracing/action_view_subscriber"
3
3
  require "sentry/rails/tracing/active_record_subscriber"
4
+ require "sentry/rails/tracing/active_storage_subscriber"
4
5
 
5
6
  module Sentry
6
7
  class Configuration
@@ -59,7 +60,8 @@ module Sentry
59
60
  @tracing_subscribers = Set.new([
60
61
  Sentry::Rails::Tracing::ActionControllerSubscriber,
61
62
  Sentry::Rails::Tracing::ActionViewSubscriber,
62
- Sentry::Rails::Tracing::ActiveRecordSubscriber
63
+ Sentry::Rails::Tracing::ActiveRecordSubscriber,
64
+ Sentry::Rails::Tracing::ActiveStorageSubscriber
63
65
  ])
64
66
  end
65
67
  end
@@ -1,7 +1,7 @@
1
1
  module Sentry
2
2
  module Rails
3
3
  module InstrumentPayloadCleanupHelper
4
- IGNORED_DATA_TYPES = [:request, :response, :headers, :exception, :exception_object]
4
+ IGNORED_DATA_TYPES = [:request, :response, :headers, :exception, :exception_object, Tracing::START_TIMESTAMP_NAME]
5
5
 
6
6
  def cleanup_data(data)
7
7
  IGNORED_DATA_TYPES.each do |key|
@@ -7,7 +7,7 @@ module Sentry
7
7
  # middlewares can't be injected after initialize
8
8
  initializer "sentry.use_rack_middleware" do |app|
9
9
  # placed after all the file-sending middlewares so we can avoid unnecessary transactions
10
- app.config.middleware.insert_after ActionDispatch::Executor, Sentry::Rails::CaptureExceptions
10
+ app.config.middleware.insert_after ActionDispatch::ShowExceptions, Sentry::Rails::CaptureExceptions
11
11
  # need to place as close to DebugExceptions as possible to intercept most of the exceptions, including those raised by middlewares
12
12
  app.config.middleware.insert_after ActionDispatch::DebugExceptions, Sentry::Rails::RescuedExceptionInterceptor
13
13
  end
@@ -11,22 +11,6 @@ module Sentry
11
11
  begin
12
12
  @app.call(env)
13
13
  rescue => e
14
- request = ActionDispatch::Request.new(env)
15
-
16
- # Rails' ShowExceptions#render_exception will mutate env for the exceptions app
17
- # so we need to hold a copy of env to report the accurate data (like request's url)
18
- if request.show_exceptions?
19
- scope = Sentry.get_current_scope
20
- copied_env = scope.rack_env.dup
21
- copied_env["sentry.original_transaction"] = scope.transaction_name
22
- scope.set_rack_env(copied_env)
23
-
24
- if report_rescued_exceptions?
25
- Sentry::Rails.capture_exception(e)
26
- env["sentry.already_captured"] = true
27
- end
28
- end
29
-
30
14
  env["sentry.rescued_exception"] = e if report_rescued_exceptions?
31
15
  raise e
32
16
  end
@@ -9,22 +9,30 @@ module Sentry
9
9
  end
10
10
 
11
11
  def unsubscribe!
12
- ActiveSupport::Notifications.unsubscribe(self::EVENT_NAME)
12
+ self::EVENT_NAMES.each do |name|
13
+ ActiveSupport::Notifications.unsubscribe(name)
14
+ end
13
15
  end
14
16
 
15
- def subscribe_to_event(event_name)
16
- if ::Rails.version.to_i == 5
17
- ActiveSupport::Notifications.subscribe(event_name) do |*args|
18
- next unless Tracing.get_current_transaction
17
+ if ::Rails.version.to_i == 5
18
+ def subscribe_to_event(event_names)
19
+ event_names.each do |event_name|
20
+ ActiveSupport::Notifications.subscribe(event_name) do |*args|
21
+ next unless Tracing.get_current_transaction
19
22
 
20
- event = ActiveSupport::Notifications::Event.new(*args)
21
- yield(event_name, event.duration, event.payload)
23
+ event = ActiveSupport::Notifications::Event.new(*args)
24
+ yield(event_name, event.duration, event.payload)
25
+ end
22
26
  end
23
- else
24
- ActiveSupport::Notifications.subscribe(event_name) do |event|
25
- next unless Tracing.get_current_transaction
26
-
27
- yield(event_name, event.duration, event.payload)
27
+ end
28
+ else
29
+ def subscribe_to_event(event_names)
30
+ event_names.each do |event_name|
31
+ ActiveSupport::Notifications.subscribe(event_name) do |event|
32
+ next unless Tracing.get_current_transaction
33
+
34
+ yield(event_name, event.duration, event.payload)
35
+ end
28
36
  end
29
37
  end
30
38
  end
@@ -7,16 +7,16 @@ module Sentry
7
7
  class ActionControllerSubscriber < AbstractSubscriber
8
8
  extend InstrumentPayloadCleanupHelper
9
9
 
10
- EVENT_NAME = "process_action.action_controller".freeze
10
+ EVENT_NAMES = ["process_action.action_controller"].freeze
11
11
 
12
12
  def self.subscribe!
13
- subscribe_to_event(EVENT_NAME) do |event_name, duration, payload|
13
+ subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
14
14
  controller = payload[:controller]
15
15
  action = payload[:action]
16
16
 
17
17
  record_on_current_span(
18
18
  op: event_name,
19
- start_timestamp: payload[:start_timestamp],
19
+ start_timestamp: payload[START_TIMESTAMP_NAME],
20
20
  description: "#{controller}##{action}",
21
21
  duration: duration
22
22
  ) do |span|
@@ -4,11 +4,11 @@ module Sentry
4
4
  module Rails
5
5
  module Tracing
6
6
  class ActionViewSubscriber < AbstractSubscriber
7
- EVENT_NAME = "render_template.action_view".freeze
7
+ EVENT_NAMES = ["render_template.action_view"].freeze
8
8
 
9
9
  def self.subscribe!
10
- subscribe_to_event(EVENT_NAME) do |event_name, duration, payload|
11
- record_on_current_span(op: event_name, start_timestamp: payload[:start_timestamp], description: payload[:identifier], duration: duration)
10
+ 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
12
  end
13
13
  end
14
14
  end
@@ -4,14 +4,14 @@ module Sentry
4
4
  module Rails
5
5
  module Tracing
6
6
  class ActiveRecordSubscriber < AbstractSubscriber
7
- EVENT_NAME = "sql.active_record".freeze
7
+ EVENT_NAMES = ["sql.active_record"].freeze
8
8
  EXCLUDED_EVENTS = ["SCHEMA", "TRANSACTION"].freeze
9
9
 
10
10
  def self.subscribe!
11
- subscribe_to_event(EVENT_NAME) do |event_name, duration, payload|
11
+ subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
12
12
  next if EXCLUDED_EVENTS.include? payload[:name]
13
13
 
14
- record_on_current_span(op: event_name, start_timestamp: payload[:start_timestamp], description: payload[:sql], duration: duration) do |span|
14
+ record_on_current_span(op: event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:sql], duration: duration) do |span|
15
15
  span.set_data(:connection_id, payload[:connection_id])
16
16
  end
17
17
  end
@@ -0,0 +1,34 @@
1
+ require "sentry/rails/tracing/abstract_subscriber"
2
+
3
+ module Sentry
4
+ module Rails
5
+ module Tracing
6
+ class ActiveStorageSubscriber < AbstractSubscriber
7
+ EVENT_NAMES = %w(
8
+ service_upload.active_storage
9
+ service_download.active_storage
10
+ service_streaming_download.active_storage
11
+ service_download_chunk.active_storage
12
+ service_delete.active_storage
13
+ service_delete_prefixed.active_storage
14
+ service_exist.active_storage
15
+ service_url.active_storage
16
+ service_mirror.active_storage
17
+ service_update_metadata.active_storage
18
+ preview.active_storage
19
+ analyze.active_storage
20
+ ).freeze
21
+
22
+ def self.subscribe!
23
+ subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
24
+ record_on_current_span(op: event_name, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:service], duration: duration) do |span|
25
+ payload.each do |key, value|
26
+ span.set_data(key, value) unless key == START_TIMESTAMP_NAME
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,8 @@
1
1
  module Sentry
2
2
  module Rails
3
3
  module Tracing
4
+ START_TIMESTAMP_NAME = :sentry_start_timestamp
5
+
4
6
  def self.register_subscribers(subscribers)
5
7
  @subscribers = subscribers
6
8
  end
@@ -9,11 +11,19 @@ module Sentry
9
11
  @subscribers
10
12
  end
11
13
 
14
+ def self.subscribed_tracing_events
15
+ @subscribed_tracing_events ||= []
16
+ end
17
+
12
18
  def self.subscribe_tracing_events
13
19
  # need to avoid duplicated subscription
14
20
  return if @subscribed
15
21
 
16
- subscribers.each(&:subscribe!)
22
+ subscribers.each do |subscriber|
23
+ subscriber.subscribe!
24
+ @subscribed_tracing_events ||= []
25
+ @subscribed_tracing_events += subscriber::EVENT_NAMES
26
+ end
17
27
 
18
28
  @subscribed = true
19
29
  end
@@ -22,6 +32,7 @@ module Sentry
22
32
  return unless @subscribed
23
33
 
24
34
  subscribers.each(&:unsubscribe!)
35
+ subscribed_tracing_events.clear
25
36
 
26
37
  @subscribed = false
27
38
  end
@@ -35,9 +46,10 @@ module Sentry
35
46
 
36
47
  SentryNotificationExtension.module_eval do
37
48
  def instrument(name, payload = {}, &block)
38
- is_public_event = name[0] != "!"
39
-
40
- payload[:start_timestamp] = Time.now.utc.to_f if is_public_event
49
+ # only inject timestamp to the events the SDK subscribes to
50
+ if Tracing.subscribed_tracing_events.include?(name)
51
+ payload[START_TIMESTAMP_NAME] = Time.now.utc.to_f if name[0] != "!" && payload.is_a?(Hash)
52
+ end
41
53
 
42
54
  super(name, payload, &block)
43
55
  end
@@ -1,5 +1,5 @@
1
1
  module Sentry
2
2
  module Rails
3
- VERSION = "4.7.2"
3
+ VERSION = "4.8.2"
4
4
  end
5
5
  end
data/lib/sentry/rails.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  require "rails"
2
2
  require "sentry-ruby"
3
3
  require "sentry/integrable"
4
+ require "sentry/rails/tracing"
4
5
  require "sentry/rails/configuration"
5
6
  require "sentry/rails/engine"
6
7
  require "sentry/rails/railtie"
7
- require "sentry/rails/tracing"
8
8
 
9
9
  module Sentry
10
10
  module Rails
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.7.0"
26
+ spec.add_dependency "sentry-ruby-core", "~> 4.8.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.7.2
4
+ version: 4.8.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: 2021-09-09 00:00:00.000000000 Z
11
+ date: 2022-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.7.0
33
+ version: 4.8.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.7.0
40
+ version: 4.8.2
41
41
  description: A gem that provides Rails integration for the Sentry error logger
42
42
  email: accounts@sentry.io
43
43
  executables: []
@@ -79,6 +79,7 @@ files:
79
79
  - lib/sentry/rails/tracing/action_controller_subscriber.rb
80
80
  - lib/sentry/rails/tracing/action_view_subscriber.rb
81
81
  - lib/sentry/rails/tracing/active_record_subscriber.rb
82
+ - lib/sentry/rails/tracing/active_storage_subscriber.rb
82
83
  - lib/sentry/rails/version.rb
83
84
  - sentry-rails.gemspec
84
85
  homepage: https://github.com/getsentry/sentry-ruby