sentry-rails 0.1.2 → 0.2.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: 3a0780603b519760f8819b1e9245514d479f5c55595d7a5d91a09ea1d72d1ea9
4
- data.tar.gz: d2137a13dd2f272298027818a2fd076c2b4a7b70bad18bd028b39a1fe95f9109
3
+ metadata.gz: 9e7eaef0b61e66058c293dd473a41a8a45af0c1547325099540d81f7802be480
4
+ data.tar.gz: c67ee2d0741a7822c43b3d29ad3d44a8590a032abe0727487dd88e09934f9449
5
5
  SHA512:
6
- metadata.gz: 0c0a349aded55ded8dc9c1d758cb1d23ee30ee08fbe063f58b842d31436a1e282d66dfea089441f71c6519ed4df340ea4bb6a3293832bc9301edfc5c3509243a
7
- data.tar.gz: ba5ed5414046187fcb7d1481e0808ff98bc35b91f61cd7481a5cba104e177fc36a3961fc6c23e871e9e7a2cc2cb8d6f8650b5ff21bc5cbc9c866a03d7fe654c4
6
+ metadata.gz: 82bbf7256864d79f10863c730508e7d0f24c0923ec0fbf77446584db1ecae1b04dcfb9e1de45367e3c0528848bd8e41d3db6d45e7d6be6eada7e2abd4e47c808
7
+ data.tar.gz: 661da577ee137848c260fcd019413b0efd7b0cc7756f90b33ba4f049446f3b1439439929e50b8ffddbfa08c1d6e907aa7f7e04761630b5cfaf81f29fe2ec1589
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ - Multiple fixes and refactorings
6
+ - Tracing support
7
+
3
8
  ## 0.1.2
4
9
 
5
10
  Fix require reference
data/Gemfile CHANGED
@@ -6,6 +6,10 @@ gemspec
6
6
  rails_version = ENV["RAILS_VERSION"]
7
7
  rails_version = "6.0" if rails_version.nil?
8
8
 
9
+ gem 'activerecord-jdbcmysql-adapter', platform: :jruby
10
+ gem "jdbc-sqlite3", platform: :jruby
11
+ gem "sqlite3", platform: :ruby
12
+
9
13
  gem "rails", "~> #{rails_version}"
10
14
  gem "rspec-rails", "~> 4.0"
11
15
  gem "codecov"
@@ -18,3 +22,8 @@ gem "sidekiq"
18
22
  gem "sentry-ruby", path: "../sentry-ruby"
19
23
 
20
24
  gem "pry"
25
+
26
+ gem "benchmark-ips"
27
+ gem "benchmark_driver"
28
+ gem "benchmark-ipsa"
29
+ gem "benchmark-memory"
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
4
+ RSpec::Core::RakeTask.new(:spec).tap do |task|
5
+ task.rspec_opts = "--order rand"
6
+ end
5
7
 
6
8
  task :default => :spec
@@ -1,6 +1,7 @@
1
1
  require "sentry-ruby"
2
2
  require "sentry/rails/configuration"
3
3
  require "sentry/rails/railtie"
4
+ require "sentry/rails/tracing"
4
5
 
5
6
  module Sentry
6
7
  module Rails
@@ -10,6 +10,7 @@ module Sentry
10
10
  class Railtie < ::Rails::Railtie
11
11
  initializer "sentry.use_rack_middleware" do |app|
12
12
  app.config.middleware.insert 0, Sentry::Rails::CaptureException
13
+ app.config.middleware.insert 0, Sentry::Rack::Tracing
13
14
  end
14
15
 
15
16
  initializer 'sentry.action_controller' do
@@ -50,6 +51,11 @@ module Sentry
50
51
 
51
52
  exceptions_class.send(:prepend, Sentry::Rails::Overrides::DebugExceptionsCatcher)
52
53
  end
54
+
55
+ if Sentry.configuration.tracing_enabled?
56
+ Sentry::Rails::Tracing.subscribe_tracing_events
57
+ Sentry::Rails::Tracing.patch_active_support_notifications
58
+ end
53
59
  end
54
60
 
55
61
  initializer 'sentry.active_job' do
@@ -0,0 +1,65 @@
1
+ require "sentry/rails/tracing/abstract_subscriber"
2
+ require "sentry/rails/tracing/active_record_subscriber"
3
+ require "sentry/rails/tracing/action_controller_subscriber"
4
+ require "sentry/rails/tracing/action_view_subscriber"
5
+
6
+ module Sentry
7
+ module Rails
8
+ module Tracing
9
+ AVAILABLE_SUBSCRIBERS = [ActionViewSubscriber, ActiveRecordSubscriber, ActionControllerSubscriber]
10
+
11
+ def self.subscribe_tracing_events
12
+ # need to avoid duplicated subscription
13
+ return if @subscribed
14
+
15
+ AVAILABLE_SUBSCRIBERS.each(&:subscribe!)
16
+
17
+ @subscribed = true
18
+ end
19
+
20
+ def self.unsubscribe_tracing_events
21
+ return unless @subscribed
22
+
23
+ AVAILABLE_SUBSCRIBERS.each(&:unsubscribe!)
24
+
25
+ @subscribed = false
26
+ end
27
+
28
+ # this is necessary because instrumentation events don't record absolute start/finish time
29
+ # so we need to retrieve the correct time this way
30
+ def self.patch_active_support_notifications
31
+ unless ::ActiveSupport::Notifications::Instrumenter.ancestors.include?(SentryNotificationExtension)
32
+ ::ActiveSupport::Notifications::Instrumenter.send(:prepend, SentryNotificationExtension)
33
+ end
34
+
35
+ SentryNotificationExtension.module_eval do
36
+ def instrument(name, payload = {}, &block)
37
+ is_public_event = name[0] != "!"
38
+
39
+ payload[:start_timestamp] = Time.now.utc.to_f if is_public_event
40
+
41
+ super(name, payload, &block)
42
+ end
43
+ end
44
+ end
45
+
46
+ def self.remove_active_support_notifications_patch
47
+ if ::ActiveSupport::Notifications::Instrumenter.ancestors.include?(SentryNotificationExtension)
48
+ SentryNotificationExtension.module_eval do
49
+ def instrument(name, payload = {}, &block)
50
+ super
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.get_current_transaction
57
+ Sentry.get_current_scope.get_transaction
58
+ end
59
+
60
+ # it's just a container for the extended method
61
+ module SentryNotificationExtension
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ module Sentry
2
+ module Rails
3
+ module Tracing
4
+ class AbstractSubscriber
5
+
6
+ class << self
7
+ def subscribe!
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def unsubscribe!
12
+ ActiveSupport::Notifications.unsubscribe(self::EVENT_NAME)
13
+ end
14
+
15
+ def subscribe_to_event(event_name)
16
+ if ::Rails.version.to_i == 5
17
+ ActiveSupport::Notifications.subscribe(event_name) do |_, start, finish, _, payload|
18
+ next unless Tracing.get_current_transaction
19
+
20
+ duration = finish.to_f - start.to_f
21
+ yield(event_name, duration, payload)
22
+ 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)
28
+ end
29
+ end
30
+ end
31
+
32
+ def record_on_current_span(duration:, **options)
33
+ return unless options[:start_timestamp]
34
+
35
+ scope = Sentry.get_current_scope
36
+ transaction = scope.get_transaction
37
+ return unless transaction && transaction.sampled
38
+
39
+ span = transaction.start_child(**options)
40
+ # duration in ActiveSupport is computed in millisecond
41
+ # so we need to covert it as second before calculating the timestamp
42
+ span.set_timestamp(span.start_timestamp + duration / 1000)
43
+ yield(span) if block_given?
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ module Sentry
2
+ module Rails
3
+ module Tracing
4
+ class ActionControllerSubscriber < AbstractSubscriber
5
+ EVENT_NAME = "process_action.action_controller".freeze
6
+
7
+ def self.subscribe!
8
+ subscribe_to_event(EVENT_NAME) do |event_name, duration, payload|
9
+ controller = payload[:controller]
10
+ action = payload[:action]
11
+
12
+ record_on_current_span(
13
+ op: event_name,
14
+ start_timestamp: payload[:start_timestamp],
15
+ description: "#{controller}##{action}",
16
+ duration: duration
17
+ ) do |span|
18
+ span.set_data(:payload, payload)
19
+ span.set_http_status(payload[:status])
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Sentry
2
+ module Rails
3
+ module Tracing
4
+ class ActionViewSubscriber < AbstractSubscriber
5
+ EVENT_NAMES = ["render_template.action_view", "render_partial.action_view", "render_collection.action_view"]
6
+
7
+ def self.subscribe!
8
+ EVENT_NAMES.each do |event_name|
9
+ subscribe_to_event(event_name) do |event_name, duration, payload|
10
+ record_on_current_span(op: event_name, start_timestamp: payload[:start_timestamp], description: payload[:identifier], duration: duration)
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.unsubscribe!
16
+ EVENT_NAMES.each do |event_name|
17
+ ActiveSupport::Notifications.unsubscribe(event_name)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Sentry
2
+ module Rails
3
+ module Tracing
4
+ class ActiveRecordSubscriber < AbstractSubscriber
5
+ EVENT_NAME = "sql.active_record".freeze
6
+ EXCLUDED_EVENTS = ["SCHEMA", "TRANSACTION"].freeze
7
+
8
+ def self.subscribe!
9
+ subscribe_to_event(EVENT_NAME) do |event_name, duration, payload|
10
+ next if EXCLUDED_EVENTS.include? payload[:name]
11
+
12
+ record_on_current_span(op: event_name, start_timestamp: payload[:start_timestamp], description: payload[:sql], duration: duration) do |span|
13
+ span.set_data(:connection_id, payload[:connection_id])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Sentry
2
2
  module Rails
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -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"
26
+ spec.add_dependency "sentry-ruby", ">= 0.2.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: 0.1.2
4
+ version: 0.2.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: 2020-11-13 00:00:00.000000000 Z
11
+ date: 2020-11-30 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: '0'
33
+ version: 0.2.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: '0'
40
+ version: 0.2.0
41
41
  description: A gem that provides Rails integration for the Sentry error logger
42
42
  email: accounts@sentry.io
43
43
  executables: []
@@ -70,6 +70,11 @@ files:
70
70
  - lib/sentry/rails/overrides/debug_exceptions_catcher.rb
71
71
  - lib/sentry/rails/overrides/streaming_reporter.rb
72
72
  - lib/sentry/rails/railtie.rb
73
+ - lib/sentry/rails/tracing.rb
74
+ - lib/sentry/rails/tracing/abstract_subscriber.rb
75
+ - lib/sentry/rails/tracing/action_controller_subscriber.rb
76
+ - lib/sentry/rails/tracing/action_view_subscriber.rb
77
+ - lib/sentry/rails/tracing/active_record_subscriber.rb
73
78
  - lib/sentry/rails/version.rb
74
79
  - sentry-rails.gemspec
75
80
  homepage: https://github.com/getsentry/sentry-ruby