sentry-rails 5.1.0 → 6.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 +4 -4
- data/.gitignore +1 -1
- data/.rspec +1 -1
- data/Gemfile +44 -26
- data/README.md +1 -1
- data/Rakefile +13 -10
- data/app/jobs/sentry/send_event_job.rb +2 -1
- data/bin/console +1 -0
- data/bin/test +389 -0
- data/lib/generators/sentry_generator.rb +31 -0
- data/lib/sentry/rails/action_cable.rb +18 -7
- data/lib/sentry/rails/active_job.rb +118 -55
- data/lib/sentry/rails/background_worker.rb +13 -4
- data/lib/sentry/rails/backtrace_cleaner.rb +7 -7
- data/lib/sentry/rails/breadcrumb/active_support_logger.rb +5 -7
- data/lib/sentry/rails/capture_exceptions.rb +34 -15
- data/lib/sentry/rails/configuration.rb +171 -21
- data/lib/sentry/rails/controller_methods.rb +2 -0
- data/lib/sentry/rails/controller_transaction.rb +34 -2
- data/lib/sentry/rails/engine.rb +2 -0
- data/lib/sentry/rails/error_subscriber.rb +26 -12
- data/lib/sentry/rails/log_subscriber.rb +76 -0
- data/lib/sentry/rails/log_subscribers/action_controller_subscriber.rb +118 -0
- data/lib/sentry/rails/log_subscribers/action_mailer_subscriber.rb +92 -0
- data/lib/sentry/rails/log_subscribers/active_job_subscriber.rb +163 -0
- data/lib/sentry/rails/log_subscribers/active_record_subscriber.rb +164 -0
- data/lib/sentry/rails/log_subscribers/parameter_filter.rb +52 -0
- data/lib/sentry/rails/overrides/streaming_reporter.rb +2 -11
- data/lib/sentry/rails/railtie.rb +35 -13
- data/lib/sentry/rails/rescued_exception_interceptor.rb +12 -1
- data/lib/sentry/rails/structured_logging.rb +32 -0
- data/lib/sentry/rails/tracing/abstract_subscriber.rb +8 -10
- data/lib/sentry/rails/tracing/action_view_subscriber.rb +11 -2
- data/lib/sentry/rails/tracing/active_record_subscriber.rb +70 -6
- data/lib/sentry/rails/tracing/active_storage_subscriber.rb +17 -4
- data/lib/sentry/rails/tracing/active_support_subscriber.rb +63 -0
- data/lib/sentry/rails/tracing.rb +3 -1
- data/lib/sentry/rails/version.rb +3 -1
- data/lib/sentry/rails.rb +3 -0
- data/lib/sentry-rails.rb +2 -0
- data/sentry-rails.gemspec +16 -8
- metadata +26 -21
- data/CODE_OF_CONDUCT.md +0 -74
- data/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb +0 -44
- data/lib/sentry/rails/instrument_payload_cleanup_helper.rb +0 -13
- data/lib/sentry/rails/tracing/action_controller_subscriber.rb +0 -33
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sentry
|
|
4
|
+
module Rails
|
|
5
|
+
module LogSubscribers
|
|
6
|
+
# Shared utility module for filtering sensitive parameters in log subscribers.
|
|
7
|
+
#
|
|
8
|
+
# This module provides consistent parameter filtering across all Sentry Rails
|
|
9
|
+
# log subscribers, leveraging Rails' built-in parameter filtering when available.
|
|
10
|
+
# It automatically detects the correct Rails parameter filtering API based on
|
|
11
|
+
# the Rails version and includes the appropriate implementation module.
|
|
12
|
+
#
|
|
13
|
+
# @example Usage in a log subscriber
|
|
14
|
+
# class MySubscriber < Sentry::Rails::LogSubscriber
|
|
15
|
+
# include Sentry::Rails::LogSubscribers::ParameterFilter
|
|
16
|
+
#
|
|
17
|
+
# def my_event(event)
|
|
18
|
+
# if Sentry.configuration.send_default_pii && event.payload[:params]
|
|
19
|
+
# filtered_params = filter_sensitive_params(event.payload[:params])
|
|
20
|
+
# attributes[:params] = filtered_params unless filtered_params.empty?
|
|
21
|
+
# end
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
module ParameterFilter
|
|
25
|
+
EMPTY_HASH = {}.freeze
|
|
26
|
+
|
|
27
|
+
if ::Rails.version.to_f >= 6.0
|
|
28
|
+
def self.backend
|
|
29
|
+
ActiveSupport::ParameterFilter
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
def self.backend
|
|
33
|
+
ActionDispatch::Http::ParameterFilter
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Filter sensitive parameters from a hash, respecting Rails configuration.
|
|
38
|
+
#
|
|
39
|
+
# @param params [Hash] The parameters to filter
|
|
40
|
+
# @return [Hash] Filtered parameters with sensitive data removed
|
|
41
|
+
def filter_sensitive_params(params)
|
|
42
|
+
return EMPTY_HASH unless params.is_a?(Hash)
|
|
43
|
+
|
|
44
|
+
filter_parameters = ::Rails.application.config.filter_parameters
|
|
45
|
+
parameter_filter = ParameterFilter.backend.new(filter_parameters)
|
|
46
|
+
|
|
47
|
+
parameter_filter.filter(params)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sentry
|
|
2
4
|
module Rails
|
|
3
5
|
module Overrides
|
|
@@ -7,17 +9,6 @@ module Sentry
|
|
|
7
9
|
super
|
|
8
10
|
end
|
|
9
11
|
end
|
|
10
|
-
|
|
11
|
-
module OldStreamingReporter
|
|
12
|
-
def self.included(base)
|
|
13
|
-
base.send(:alias_method_chain, :log_error, :raven)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def log_error_with_raven(exception)
|
|
17
|
-
Sentry::Rails.capture_exception(exception)
|
|
18
|
-
log_error_without_raven(exception)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
12
|
end
|
|
22
13
|
end
|
|
23
14
|
end
|
data/lib/sentry/rails/railtie.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sentry/rails/capture_exceptions"
|
|
2
4
|
require "sentry/rails/rescued_exception_interceptor"
|
|
3
5
|
require "sentry/rails/backtrace_cleaner"
|
|
@@ -12,7 +14,7 @@ module Sentry
|
|
|
12
14
|
app.config.middleware.insert_after ActionDispatch::DebugExceptions, Sentry::Rails::RescuedExceptionInterceptor
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
# because the extension works by registering the around_perform
|
|
17
|
+
# because the extension works by registering the around_perform callback, it should always be run
|
|
16
18
|
# before the application is eager-loaded (before user's jobs register their own callbacks)
|
|
17
19
|
# See https://github.com/getsentry/sentry-ruby/issues/1249#issuecomment-853871871 for the detail explanation
|
|
18
20
|
initializer "sentry.extend_active_job", before: :eager_load! do |app|
|
|
@@ -40,19 +42,33 @@ module Sentry
|
|
|
40
42
|
|
|
41
43
|
configure_project_root
|
|
42
44
|
configure_trusted_proxies
|
|
45
|
+
configure_cron_timezone
|
|
43
46
|
extend_controller_methods if defined?(ActionController)
|
|
44
47
|
patch_background_worker if defined?(ActiveRecord)
|
|
45
48
|
override_streaming_reporter if defined?(ActionView)
|
|
46
49
|
setup_backtrace_cleanup_callback
|
|
47
50
|
inject_breadcrumbs_logger
|
|
48
51
|
activate_tracing
|
|
52
|
+
activate_structured_logging
|
|
53
|
+
|
|
54
|
+
register_error_subscriber(app) if ::Rails.version.to_f >= 7.0 && Sentry.configuration.rails.register_error_subscriber
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
# Presence of ActiveJob is no longer a reliable cue
|
|
57
|
+
if defined?(Sentry::Rails::ActiveJobExtensions)
|
|
58
|
+
Sentry::Rails::ActiveJobExtensions::SentryReporter.register_event_handlers
|
|
59
|
+
end
|
|
51
60
|
end
|
|
52
61
|
|
|
53
62
|
runner do
|
|
54
63
|
next unless Sentry.initialized?
|
|
55
64
|
Sentry.configuration.background_worker_threads = 0
|
|
65
|
+
|
|
66
|
+
at_exit do
|
|
67
|
+
# TODO: Add a condition for Rails 7.1 to avoid confliction with https://github.com/rails/rails/pull/44999
|
|
68
|
+
if $ERROR_INFO && !($ERROR_INFO.is_a?(SystemExit) && $ERROR_INFO.success?)
|
|
69
|
+
Sentry::Rails.capture_exception($ERROR_INFO, tags: { source: "runner" })
|
|
70
|
+
end
|
|
71
|
+
end
|
|
56
72
|
end
|
|
57
73
|
|
|
58
74
|
def configure_project_root
|
|
@@ -63,6 +79,11 @@ module Sentry
|
|
|
63
79
|
Sentry.configuration.trusted_proxies += Array(::Rails.application.config.action_dispatch.trusted_proxies)
|
|
64
80
|
end
|
|
65
81
|
|
|
82
|
+
def configure_cron_timezone
|
|
83
|
+
tz_info = ::ActiveSupport::TimeZone.find_tzinfo(::Rails.application.config.time_zone)
|
|
84
|
+
Sentry.configuration.cron.default_timezone = tz_info.name
|
|
85
|
+
end
|
|
86
|
+
|
|
66
87
|
def extend_controller_methods
|
|
67
88
|
require "sentry/rails/controller_methods"
|
|
68
89
|
require "sentry/rails/controller_transaction"
|
|
@@ -80,16 +101,11 @@ module Sentry
|
|
|
80
101
|
end
|
|
81
102
|
|
|
82
103
|
def inject_breadcrumbs_logger
|
|
83
|
-
if Sentry.configuration.breadcrumbs_logger.include?(:active_support_logger)
|
|
84
|
-
|
|
85
|
-
Sentry
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if Sentry.configuration.breadcrumbs_logger.include?(:monotonic_active_support_logger)
|
|
89
|
-
return warn "Usage of `monotonic_active_support_logger` require a version of Rails >= 6.1, please upgrade your Rails version or use another logger" if ::Rails.version.to_f < 6.1
|
|
90
|
-
|
|
91
|
-
require 'sentry/rails/breadcrumb/monotonic_active_support_logger'
|
|
92
|
-
Sentry::Rails::Breadcrumb::MonotonicActiveSupportLogger.inject
|
|
104
|
+
if Sentry.configuration.breadcrumbs_logger.include?(:active_support_logger) ||
|
|
105
|
+
## legacy name redirected for backwards compat
|
|
106
|
+
Sentry.configuration.breadcrumbs_logger.include?(:monotonic_active_support_logger)
|
|
107
|
+
require "sentry/rails/breadcrumb/active_support_logger"
|
|
108
|
+
Sentry::Rails::Breadcrumb::ActiveSupportLogger.inject(Sentry.configuration.rails.active_support_logger_subscription_items)
|
|
93
109
|
end
|
|
94
110
|
end
|
|
95
111
|
|
|
@@ -110,7 +126,7 @@ module Sentry
|
|
|
110
126
|
end
|
|
111
127
|
|
|
112
128
|
def activate_tracing
|
|
113
|
-
if Sentry.configuration.tracing_enabled?
|
|
129
|
+
if Sentry.configuration.tracing_enabled? && Sentry.configuration.instrumenter == :sentry
|
|
114
130
|
subscribers = Sentry.configuration.rails.tracing_subscribers
|
|
115
131
|
Sentry::Rails::Tracing.register_subscribers(subscribers)
|
|
116
132
|
Sentry::Rails::Tracing.subscribe_tracing_events
|
|
@@ -118,6 +134,12 @@ module Sentry
|
|
|
118
134
|
end
|
|
119
135
|
end
|
|
120
136
|
|
|
137
|
+
def activate_structured_logging
|
|
138
|
+
if Sentry.configuration.rails.structured_logging.enabled? && Sentry.configuration.enable_logs
|
|
139
|
+
Sentry::Rails::StructuredLogging.attach(Sentry.configuration.rails.structured_logging)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
121
143
|
def register_error_subscriber(app)
|
|
122
144
|
require "sentry/rails/error_subscriber"
|
|
123
145
|
app.executor.error_reporter.subscribe(Sentry::Rails::ErrorSubscriber.new)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sentry
|
|
2
4
|
module Rails
|
|
3
5
|
class RescuedExceptionInterceptor
|
|
@@ -17,7 +19,16 @@ module Sentry
|
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def report_rescued_exceptions?
|
|
20
|
-
Sentry.configuration.
|
|
22
|
+
# In rare edge cases, `Sentry.configuration` might be `nil` here.
|
|
23
|
+
# Hence, we use a safe navigation and fallback to a reasonable default
|
|
24
|
+
# of `true` in case the configuration couldn't be loaded.
|
|
25
|
+
# See https://github.com/getsentry/sentry-ruby/issues/2386
|
|
26
|
+
report_rescued_exceptions = Sentry.configuration&.rails&.report_rescued_exceptions
|
|
27
|
+
return report_rescued_exceptions unless report_rescued_exceptions.nil?
|
|
28
|
+
|
|
29
|
+
# `true` is the default for `report_rescued_exceptions`, as specified in
|
|
30
|
+
# `sentry-rails/lib/sentry/rails/configuration.rb`.
|
|
31
|
+
true
|
|
21
32
|
end
|
|
22
33
|
end
|
|
23
34
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "sentry/rails/log_subscriber"
|
|
4
|
+
require "sentry/rails/log_subscribers/action_controller_subscriber"
|
|
5
|
+
require "sentry/rails/log_subscribers/active_record_subscriber"
|
|
6
|
+
require "sentry/rails/log_subscribers/active_job_subscriber"
|
|
7
|
+
require "sentry/rails/log_subscribers/action_mailer_subscriber"
|
|
8
|
+
|
|
9
|
+
module Sentry
|
|
10
|
+
module Rails
|
|
11
|
+
module StructuredLogging
|
|
12
|
+
class << self
|
|
13
|
+
def attach(config)
|
|
14
|
+
config.subscribers.each do |component, subscriber_class|
|
|
15
|
+
subscriber_class.attach_to component
|
|
16
|
+
end
|
|
17
|
+
rescue => e
|
|
18
|
+
Sentry.configuration.sdk_logger.error("Failed to attach structured loggers: #{e.message}")
|
|
19
|
+
Sentry.configuration.sdk_logger.error(e.backtrace.join("\n"))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def detach(config)
|
|
23
|
+
config.subscribers.each do |component, subscriber_class|
|
|
24
|
+
subscriber_class.detach_from component
|
|
25
|
+
end
|
|
26
|
+
rescue => e
|
|
27
|
+
Sentry.configuration.sdk_logger.debug("Error during detaching loggers: #{e.message}")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sentry
|
|
2
4
|
module Rails
|
|
3
5
|
module Tracing
|
|
4
6
|
class AbstractSubscriber
|
|
5
|
-
|
|
6
7
|
class << self
|
|
7
8
|
def subscribe!
|
|
8
9
|
raise NotImplementedError
|
|
@@ -40,15 +41,12 @@ module Sentry
|
|
|
40
41
|
def record_on_current_span(duration:, **options)
|
|
41
42
|
return unless options[:start_timestamp]
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# so we need to covert it as second before calculating the timestamp
|
|
50
|
-
span.set_timestamp(span.start_timestamp + duration / 1000)
|
|
51
|
-
yield(span) if block_given?
|
|
44
|
+
Sentry.with_child_span(**options) do |child_span|
|
|
45
|
+
# duration in ActiveSupport is computed in millisecond
|
|
46
|
+
# so we need to covert it as second before calculating the timestamp
|
|
47
|
+
child_span.set_timestamp(child_span.start_timestamp + duration / 1000)
|
|
48
|
+
yield(child_span) if block_given?
|
|
49
|
+
end
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sentry/rails/tracing/abstract_subscriber"
|
|
2
4
|
|
|
3
5
|
module Sentry
|
|
@@ -5,11 +7,18 @@ module Sentry
|
|
|
5
7
|
module Tracing
|
|
6
8
|
class ActionViewSubscriber < AbstractSubscriber
|
|
7
9
|
EVENT_NAMES = ["render_template.action_view"].freeze
|
|
8
|
-
SPAN_PREFIX = "template."
|
|
10
|
+
SPAN_PREFIX = "template."
|
|
11
|
+
SPAN_ORIGIN = "auto.template.rails"
|
|
9
12
|
|
|
10
13
|
def self.subscribe!
|
|
11
14
|
subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
|
|
12
|
-
record_on_current_span(
|
|
15
|
+
record_on_current_span(
|
|
16
|
+
op: SPAN_PREFIX + event_name,
|
|
17
|
+
origin: SPAN_ORIGIN,
|
|
18
|
+
start_timestamp: payload[START_TIMESTAMP_NAME],
|
|
19
|
+
description: payload[:identifier],
|
|
20
|
+
duration: duration
|
|
21
|
+
)
|
|
13
22
|
end
|
|
14
23
|
end
|
|
15
24
|
end
|
|
@@ -1,19 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sentry/rails/tracing/abstract_subscriber"
|
|
4
|
+
require "sentry/backtrace"
|
|
2
5
|
|
|
3
6
|
module Sentry
|
|
4
7
|
module Rails
|
|
5
8
|
module Tracing
|
|
6
9
|
class ActiveRecordSubscriber < AbstractSubscriber
|
|
7
10
|
EVENT_NAMES = ["sql.active_record"].freeze
|
|
8
|
-
SPAN_PREFIX = "db."
|
|
11
|
+
SPAN_PREFIX = "db."
|
|
12
|
+
SPAN_ORIGIN = "auto.db.rails"
|
|
9
13
|
EXCLUDED_EVENTS = ["SCHEMA", "TRANSACTION"].freeze
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
SUPPORT_SOURCE_LOCATION = ActiveSupport::BacktraceCleaner.method_defined?(:clean_frame)
|
|
16
|
+
|
|
17
|
+
if SUPPORT_SOURCE_LOCATION
|
|
18
|
+
backtrace_cleaner = ActiveSupport::BacktraceCleaner.new.tap do |cleaner|
|
|
19
|
+
cleaner.add_silencer { |line| line.include?("sentry-ruby/lib") || line.include?("sentry-rails/lib") }
|
|
20
|
+
end.method(:clean_frame)
|
|
21
|
+
|
|
22
|
+
class_attribute :backtrace_cleaner, default: backtrace_cleaner
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def subscribe!
|
|
27
|
+
record_query_source = SUPPORT_SOURCE_LOCATION && Sentry.configuration.rails.enable_db_query_source
|
|
28
|
+
query_source_threshold = Sentry.configuration.rails.db_query_source_threshold_ms
|
|
29
|
+
|
|
30
|
+
subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
|
|
31
|
+
next if EXCLUDED_EVENTS.include? payload[:name]
|
|
32
|
+
|
|
33
|
+
record_on_current_span(
|
|
34
|
+
op: SPAN_PREFIX + event_name,
|
|
35
|
+
origin: SPAN_ORIGIN,
|
|
36
|
+
start_timestamp: payload[START_TIMESTAMP_NAME],
|
|
37
|
+
description: payload[:sql],
|
|
38
|
+
duration: duration
|
|
39
|
+
) do |span|
|
|
40
|
+
span.set_tag(:cached, true) if payload.fetch(:cached, false) # cached key is only set for hits in the QueryCache, from Rails 5.1
|
|
41
|
+
|
|
42
|
+
connection = payload[:connection]
|
|
43
|
+
|
|
44
|
+
if payload[:connection_id]
|
|
45
|
+
span.set_data(:connection_id, payload[:connection_id])
|
|
46
|
+
|
|
47
|
+
# we fallback to the base connection on rails < 6.0.0 since the payload doesn't have it
|
|
48
|
+
connection ||= ActiveRecord::Base.connection_pool.connections.find { |conn| conn.object_id == payload[:connection_id] }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
next unless connection
|
|
52
|
+
|
|
53
|
+
db_config =
|
|
54
|
+
if connection.pool.respond_to?(:db_config)
|
|
55
|
+
connection.pool.db_config.configuration_hash
|
|
56
|
+
elsif connection.pool.respond_to?(:spec)
|
|
57
|
+
connection.pool.spec.config
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
next unless db_config
|
|
61
|
+
|
|
62
|
+
span.set_data(Span::DataConventions::DB_SYSTEM, db_config[:adapter]) if db_config[:adapter]
|
|
63
|
+
span.set_data(Span::DataConventions::DB_NAME, db_config[:database]) if db_config[:database]
|
|
64
|
+
span.set_data(Span::DataConventions::SERVER_ADDRESS, db_config[:host]) if db_config[:host]
|
|
65
|
+
span.set_data(Span::DataConventions::SERVER_PORT, db_config[:port]) if db_config[:port]
|
|
66
|
+
span.set_data(Span::DataConventions::SERVER_SOCKET_ADDRESS, db_config[:socket]) if db_config[:socket]
|
|
67
|
+
|
|
68
|
+
# both duration and query_source_threshold are in ms
|
|
69
|
+
if record_query_source && duration >= query_source_threshold
|
|
70
|
+
backtrace_line = Backtrace.source_location(&backtrace_cleaner)
|
|
14
71
|
|
|
15
|
-
|
|
16
|
-
|
|
72
|
+
if backtrace_line
|
|
73
|
+
span.set_data(Span::DataConventions::FILEPATH, backtrace_line.file) if backtrace_line.file
|
|
74
|
+
span.set_data(Span::DataConventions::LINENO, backtrace_line.number) if backtrace_line.number
|
|
75
|
+
span.set_data(Span::DataConventions::FUNCTION, backtrace_line.method) if backtrace_line.method
|
|
76
|
+
# Only JRuby has namespace in the backtrace
|
|
77
|
+
span.set_data(Span::DataConventions::NAMESPACE, backtrace_line.module_name) if backtrace_line.module_name
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
17
81
|
end
|
|
18
82
|
end
|
|
19
83
|
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sentry/rails/tracing/abstract_subscriber"
|
|
2
4
|
|
|
3
5
|
module Sentry
|
|
4
6
|
module Rails
|
|
5
7
|
module Tracing
|
|
6
8
|
class ActiveStorageSubscriber < AbstractSubscriber
|
|
7
|
-
EVENT_NAMES = %w
|
|
9
|
+
EVENT_NAMES = %w[
|
|
8
10
|
service_upload.active_storage
|
|
9
11
|
service_download.active_storage
|
|
10
12
|
service_streaming_download.active_storage
|
|
@@ -17,13 +19,24 @@ module Sentry
|
|
|
17
19
|
service_update_metadata.active_storage
|
|
18
20
|
preview.active_storage
|
|
19
21
|
analyze.active_storage
|
|
20
|
-
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
SPAN_ORIGIN = "auto.file.rails"
|
|
21
25
|
|
|
22
26
|
def self.subscribe!
|
|
23
27
|
subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
|
|
24
|
-
record_on_current_span(
|
|
28
|
+
record_on_current_span(
|
|
29
|
+
op: "file.#{event_name}",
|
|
30
|
+
origin: SPAN_ORIGIN,
|
|
31
|
+
start_timestamp: payload[START_TIMESTAMP_NAME],
|
|
32
|
+
description: payload[:service],
|
|
33
|
+
duration: duration
|
|
34
|
+
) do |span|
|
|
25
35
|
payload.each do |key, value|
|
|
26
|
-
|
|
36
|
+
next if key == START_TIMESTAMP_NAME
|
|
37
|
+
next if key == :key && !Sentry.configuration.send_default_pii
|
|
38
|
+
|
|
39
|
+
span.set_data(key, value)
|
|
27
40
|
end
|
|
28
41
|
end
|
|
29
42
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "sentry/rails/tracing/abstract_subscriber"
|
|
4
|
+
|
|
5
|
+
module Sentry
|
|
6
|
+
module Rails
|
|
7
|
+
module Tracing
|
|
8
|
+
class ActiveSupportSubscriber < AbstractSubscriber
|
|
9
|
+
READ_EVENT_NAMES = %w[
|
|
10
|
+
cache_read.active_support
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
WRITE_EVENT_NAMES = %w[
|
|
14
|
+
cache_write.active_support
|
|
15
|
+
cache_increment.active_support
|
|
16
|
+
cache_decrement.active_support
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
REMOVE_EVENT_NAMES = %w[
|
|
20
|
+
cache_delete.active_support
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
FLUSH_EVENT_NAMES = %w[
|
|
24
|
+
cache_prune.active_support
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
EVENT_NAMES = READ_EVENT_NAMES + WRITE_EVENT_NAMES + REMOVE_EVENT_NAMES + FLUSH_EVENT_NAMES
|
|
28
|
+
|
|
29
|
+
SPAN_ORIGIN = "auto.cache.rails"
|
|
30
|
+
|
|
31
|
+
def self.subscribe!
|
|
32
|
+
subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
|
|
33
|
+
record_on_current_span(
|
|
34
|
+
op: operation_name(event_name),
|
|
35
|
+
origin: SPAN_ORIGIN,
|
|
36
|
+
start_timestamp: payload[START_TIMESTAMP_NAME],
|
|
37
|
+
description: payload[:store],
|
|
38
|
+
duration: duration
|
|
39
|
+
) do |span|
|
|
40
|
+
span.set_data("cache.key", [*payload[:key]].select { |key| Utils::EncodingHelper.valid_utf_8?(key) })
|
|
41
|
+
span.set_data("cache.hit", payload[:hit] == true) # Handle nil case
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.operation_name(event_name)
|
|
47
|
+
case
|
|
48
|
+
when READ_EVENT_NAMES.include?(event_name)
|
|
49
|
+
"cache.get"
|
|
50
|
+
when WRITE_EVENT_NAMES.include?(event_name)
|
|
51
|
+
"cache.put"
|
|
52
|
+
when REMOVE_EVENT_NAMES.include?(event_name)
|
|
53
|
+
"cache.remove"
|
|
54
|
+
when FLUSH_EVENT_NAMES.include?(event_name)
|
|
55
|
+
"cache.flush"
|
|
56
|
+
else
|
|
57
|
+
"other"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/sentry/rails/tracing.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sentry
|
|
2
4
|
module Rails
|
|
3
5
|
module Tracing
|
|
@@ -67,7 +69,7 @@ module Sentry
|
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
def self.get_current_transaction
|
|
70
|
-
Sentry.get_current_scope.get_transaction
|
|
72
|
+
Sentry.get_current_scope.get_transaction if Sentry.initialized?
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
# it's just a container for the extended method
|
data/lib/sentry/rails/version.rb
CHANGED
data/lib/sentry/rails.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "rails"
|
|
2
4
|
require "sentry-ruby"
|
|
3
5
|
require "sentry/integrable"
|
|
4
6
|
require "sentry/rails/tracing"
|
|
5
7
|
require "sentry/rails/configuration"
|
|
8
|
+
require "sentry/rails/structured_logging"
|
|
6
9
|
require "sentry/rails/engine"
|
|
7
10
|
require "sentry/rails/railtie"
|
|
8
11
|
|
data/lib/sentry-rails.rb
CHANGED
data/sentry-rails.gemspec
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative "lib/sentry/rails/version"
|
|
2
4
|
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
@@ -7,21 +9,27 @@ Gem::Specification.new do |spec|
|
|
|
7
9
|
spec.description = spec.summary = "A gem that provides Rails integration for the Sentry error logger"
|
|
8
10
|
spec.email = "accounts@sentry.io"
|
|
9
11
|
spec.license = 'MIT'
|
|
10
|
-
spec.homepage = "https://github.com/getsentry/sentry-ruby"
|
|
11
12
|
|
|
12
13
|
spec.platform = Gem::Platform::RUBY
|
|
13
|
-
spec.required_ruby_version = '>= 2.
|
|
14
|
+
spec.required_ruby_version = '>= 2.7'
|
|
14
15
|
spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
|
|
15
|
-
spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
|
|
16
|
+
spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n")
|
|
17
|
+
|
|
18
|
+
github_root_uri = 'https://github.com/getsentry/sentry-ruby'
|
|
19
|
+
spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}"
|
|
16
20
|
|
|
17
|
-
spec.metadata
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
spec.metadata = {
|
|
22
|
+
"homepage_uri" => spec.homepage,
|
|
23
|
+
"source_code_uri" => spec.homepage,
|
|
24
|
+
"changelog_uri" => "#{github_root_uri}/blob/#{spec.version}/CHANGELOG.md",
|
|
25
|
+
"bug_tracker_uri" => "#{github_root_uri}/issues",
|
|
26
|
+
"documentation_uri" => "http://www.rubydoc.info/gems/#{spec.name}/#{spec.version}"
|
|
27
|
+
}
|
|
20
28
|
|
|
21
29
|
spec.bindir = "exe"
|
|
22
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
31
|
spec.require_paths = ["lib"]
|
|
24
32
|
|
|
25
|
-
spec.add_dependency "railties", ">= 5.0"
|
|
26
|
-
spec.add_dependency "sentry-ruby
|
|
33
|
+
spec.add_dependency "railties", ">= 5.2.0"
|
|
34
|
+
spec.add_dependency "sentry-ruby", "~> 6.2.0"
|
|
27
35
|
end
|