sentry-rails 0.1.2 → 4.1.1

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: f1ded72e004f25631844145fc5a86d4e4a20e90417a42ac608a91b92fd5a0702
4
+ data.tar.gz: 5b36ca31d954d72c0ee3f0407b3ad201285809b45439d580ccad910cf5f68d6f
5
5
  SHA512:
6
- metadata.gz: 0c0a349aded55ded8dc9c1d758cb1d23ee30ee08fbe063f58b842d31436a1e282d66dfea089441f71c6519ed4df340ea4bb6a3293832bc9301edfc5c3509243a
7
- data.tar.gz: ba5ed5414046187fcb7d1481e0808ff98bc35b91f61cd7481a5cba104e177fc36a3961fc6c23e871e9e7a2cc2cb8d6f8650b5ff21bc5cbc9c866a03d7fe654c4
6
+ metadata.gz: b91264b7393b702a5f4e08e8ac37836dd97e5055eb214b37faa704930bb56ef681edbc7baabc8fcced668d2a78c4d10ab039715036a8196f6734a7ef5f429467
7
+ data.tar.gz: bb6d1c2a6c051922126ba745350f1c003cf928309a6507867084f1a1833dd160a2ac6637cd909caadf69ac848d66a8789a1286409267c7aefbb74453836833c2
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.1.1
4
+
5
+ - Use stricter dependency declaration [#1159](https://github.com/getsentry/sentry-ruby/pull/1159)
6
+
7
+ ## 4.1.0
8
+
9
+ - Merge & rename 2 Rack middlewares [#1147](https://github.com/getsentry/sentry-ruby/pull/1147)
10
+ - Fixes [#1153](https://github.com/getsentry/sentry-ruby/pull/1153)
11
+ - Removed `Sentry::Rack::Tracing` middleware and renamed `Sentry::Rack::CaptureException` to `Sentry::Rack::CaptureExceptions`
12
+ - Tidy up rails integration [#1150](https://github.com/getsentry/sentry-ruby/pull/1150)
13
+ - Check SDK initialization before running integrations [#1151](https://github.com/getsentry/sentry-ruby/pull/1151)
14
+ - Fixes [#1145](https://github.com/getsentry/sentry-ruby/pull/1145)
15
+
16
+ ## 4.0.0
17
+
18
+ - Only documents update for the official release and no API/feature changes.
19
+
20
+ ## 0.3.0
21
+
22
+ - Major API changes: [1123](https://github.com/getsentry/sentry-ruby/pull/1123)
23
+
24
+ ## 0.2.0
25
+
26
+ - Multiple fixes and refactorings
27
+ - Tracing support
28
+
3
29
  ## 0.1.2
4
30
 
5
31
  Fix require reference
data/Gemfile CHANGED
@@ -4,7 +4,11 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  rails_version = ENV["RAILS_VERSION"]
7
- rails_version = "6.0" if rails_version.nil?
7
+ rails_version = "6.1.0" if rails_version.nil?
8
+
9
+ gem 'activerecord-jdbcmysql-adapter', platform: :jruby
10
+ gem "jdbc-sqlite3", platform: :jruby
11
+ gem "sqlite3", platform: :ruby
8
12
 
9
13
  gem "rails", "~> #{rails_version}"
10
14
  gem "rspec-rails", "~> 4.0"
@@ -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/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-rails&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-rails&package-manager=bundler&version-scheme=semver)
18
18
 
19
19
 
20
- [Documentation](https://docs.sentry.io/clients/ruby/) | [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues) | [Forum](https://forum.sentry.io/) | IRC: irc.freenode.net, #sentry
20
+ [Documentation](https://docs.sentry.io/platforms/ruby/guides/rails/) | [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues) | [Forum](https://forum.sentry.io/) | IRC: irc.freenode.net, #sentry
21
21
 
22
22
  The official Ruby-language client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API.
23
23
 
@@ -50,3 +50,36 @@ Sentry.init do |config|
50
50
  end
51
51
  ```
52
52
 
53
+ ### Performance Monitoring
54
+
55
+ You can activate performance monitoring by enabling traces sampling:
56
+
57
+ ```ruby
58
+ Sentry.init do |config|
59
+ # set a uniform sample rate between 0.0 and 1.0
60
+ config.traces_sample_rate = 0.2
61
+
62
+ # or control sampling dynamically
63
+ config.traces_sampler = lambda do |sampling_context|
64
+ # sampling_context[:transaction_context] contains the information about the transaction
65
+ # sampling_context[:parent_sampled] contains the transaction's parent's sample decision
66
+ true # return value can be a boolean or a float between 0.0 and 1.0
67
+ end
68
+ end
69
+ ```
70
+
71
+ Currently, it tracks the following Rails instrumentation events:
72
+
73
+ - ActiveRecord
74
+ - `sql.active_record`
75
+ - ActionController
76
+ - `process_action.action_controller`
77
+ - ActionView
78
+ - `render_template.action_view`
79
+ - `render_partial.action_view`
80
+ - `render_collection.action_view`
81
+
82
+ To lean more about performance monitoring, please visit the [official documentation](https://docs.sentry.io/platforms/ruby/guides/rails/performance/).
83
+
84
+
85
+
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
@@ -4,16 +4,20 @@ module Sentry
4
4
  module ActiveSupportLogger
5
5
  class << self
6
6
  def add(name, started, _finished, _unique_id, data)
7
- Sentry.get_current_scope.breadcrumbs.record do |crumb|
8
- crumb.data = data
9
- crumb.category = name
10
- crumb.timestamp = started.to_i
11
- end
7
+ crumb = Sentry::Breadcrumb.new(
8
+ data: data,
9
+ category: name,
10
+ timestamp: started.to_i
11
+ )
12
+ Sentry.add_breadcrumb(crumb)
12
13
  end
13
14
 
14
15
  def inject
15
16
  @subscriber = ::ActiveSupport::Notifications.subscribe(/.*/) do |name, started, finished, unique_id, data|
16
- add(name, started, finished, unique_id, data)
17
+ # we only record events that has a started timestamp
18
+ if started.is_a?(Time)
19
+ add(name, started, finished, unique_id, data)
20
+ end
17
21
  end
18
22
  end
19
23
 
@@ -1,6 +1,6 @@
1
1
  module Sentry
2
2
  module Rails
3
- class CaptureException < Sentry::Rack::CaptureException
3
+ class CaptureExceptions < Sentry::Rack::CaptureExceptions
4
4
  def collect_exception(env)
5
5
  super || env["action_dispatch.exception"]
6
6
  end
@@ -1,5 +1,5 @@
1
1
  require "rails"
2
- require "sentry/rails/capture_exception"
2
+ require "sentry/rails/capture_exceptions"
3
3
  require "sentry/rails/backtrace_cleaner"
4
4
  require "sentry/rails/controller_methods"
5
5
  require "sentry/rails/controller_transaction"
@@ -8,11 +8,33 @@ require "sentry/rails/overrides/streaming_reporter"
8
8
 
9
9
  module Sentry
10
10
  class Railtie < ::Rails::Railtie
11
+ # middlewares can't be injected after initialize
11
12
  initializer "sentry.use_rack_middleware" do |app|
12
- app.config.middleware.insert 0, Sentry::Rails::CaptureException
13
+ app.config.middleware.insert 0, Sentry::Rails::CaptureExceptions
13
14
  end
14
15
 
15
- initializer 'sentry.action_controller' do
16
+ config.after_initialize do
17
+ next unless Sentry.initialized?
18
+
19
+ configure_sentry_logger
20
+ extend_controller_methods
21
+ extend_active_job
22
+ override_exceptions_handling
23
+ override_streaming_reporter
24
+ setup_backtrace_cleanup_callback
25
+ inject_breadcrumbs_logger
26
+ activate_tracing
27
+ end
28
+
29
+ def configure_sentry_logger
30
+ Sentry.configuration.logger = ::Rails.logger
31
+ end
32
+
33
+ def extend_active_job
34
+ ActiveJob::Base.send(:prepend, Sentry::Rails::ActiveJobExtensions)
35
+ end
36
+
37
+ def extend_controller_methods
16
38
  ActiveSupport.on_load :action_controller do
17
39
  include Sentry::Rails::ControllerMethods
18
40
  include Sentry::Rails::ControllerTransaction
@@ -20,26 +42,22 @@ module Sentry
20
42
  end
21
43
  end
22
44
 
23
- initializer 'sentry.action_view' do
24
- ActiveSupport.on_load :action_view do
25
- ActionView::StreamingTemplateRenderer::Body.send(:prepend, Sentry::Rails::Overrides::StreamingReporter)
45
+ def inject_breadcrumbs_logger
46
+ if Sentry.configuration.breadcrumbs_logger.include?(:active_support_logger)
47
+ require 'sentry/rails/breadcrumb/active_support_logger'
48
+ Sentry::Rails::Breadcrumb::ActiveSupportLogger.inject
26
49
  end
27
50
  end
28
51
 
29
- config.after_initialize do
30
- Sentry.configuration.logger = ::Rails.logger
31
-
52
+ def setup_backtrace_cleanup_callback
32
53
  backtrace_cleaner = Sentry::Rails::BacktraceCleaner.new
33
54
 
34
55
  Sentry.configuration.backtrace_cleanup_callback = lambda do |backtrace|
35
56
  backtrace_cleaner.clean(backtrace)
36
57
  end
58
+ end
37
59
 
38
- if Sentry.configuration.breadcrumbs_logger.include?(:active_support_logger)
39
- require 'sentry/rails/breadcrumb/active_support_logger'
40
- Sentry::Rails::Breadcrumb::ActiveSupportLogger.inject
41
- end
42
-
60
+ def override_exceptions_handling
43
61
  if Sentry.configuration.rails.report_rescued_exceptions
44
62
  require 'sentry/rails/overrides/debug_exceptions_catcher'
45
63
  if defined?(::ActionDispatch::DebugExceptions)
@@ -52,14 +70,17 @@ module Sentry
52
70
  end
53
71
  end
54
72
 
55
- initializer 'sentry.active_job' do
56
- ActiveSupport.on_load :active_job do
57
- require 'sentry/rails/active_job'
73
+ def override_streaming_reporter
74
+ ActiveSupport.on_load :action_view do
75
+ ActionView::StreamingTemplateRenderer::Body.send(:prepend, Sentry::Rails::Overrides::StreamingReporter)
58
76
  end
59
77
  end
60
78
 
61
- # rake_tasks do
62
- # require 'sentry/integrations/tasks'
63
- # end
79
+ def activate_tracing
80
+ if Sentry.configuration.tracing_enabled?
81
+ Sentry::Rails::Tracing.subscribe_tracing_events
82
+ Sentry::Rails::Tracing.patch_active_support_notifications
83
+ end
84
+ end
64
85
  end
65
86
  end
@@ -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 = "4.1.1"
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", "~> 4.1.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: 4.1.1
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-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: sentry-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 4.1.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: 4.1.0
41
41
  description: A gem that provides Rails integration for the Sentry error logger
42
42
  email: accounts@sentry.io
43
43
  executables: []
@@ -63,13 +63,18 @@ files:
63
63
  - lib/sentry/rails/active_job.rb
64
64
  - lib/sentry/rails/backtrace_cleaner.rb
65
65
  - lib/sentry/rails/breadcrumb/active_support_logger.rb
66
- - lib/sentry/rails/capture_exception.rb
66
+ - lib/sentry/rails/capture_exceptions.rb
67
67
  - lib/sentry/rails/configuration.rb
68
68
  - lib/sentry/rails/controller_methods.rb
69
69
  - lib/sentry/rails/controller_transaction.rb
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