sentry-rails 0.1.2 → 0.2.0

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