sentry-rails 4.7.2 → 4.8.2

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: 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