sentry-rails 5.18.2 → 5.28.1

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +43 -26
  3. data/Rakefile +13 -10
  4. data/app/jobs/sentry/send_event_job.rb +2 -0
  5. data/bin/console +1 -0
  6. data/bin/test +389 -0
  7. data/lib/generators/sentry_generator.rb +13 -1
  8. data/lib/sentry/rails/action_cable.rb +3 -1
  9. data/lib/sentry/rails/active_job.rb +65 -10
  10. data/lib/sentry/rails/background_worker.rb +13 -7
  11. data/lib/sentry/rails/backtrace_cleaner.rb +7 -7
  12. data/lib/sentry/rails/breadcrumb/active_support_logger.rb +2 -0
  13. data/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb +2 -0
  14. data/lib/sentry/rails/capture_exceptions.rb +4 -2
  15. data/lib/sentry/rails/configuration.rb +64 -18
  16. data/lib/sentry/rails/controller_methods.rb +2 -0
  17. data/lib/sentry/rails/controller_transaction.rb +7 -3
  18. data/lib/sentry/rails/engine.rb +2 -0
  19. data/lib/sentry/rails/error_subscriber.rb +2 -0
  20. data/lib/sentry/rails/instrument_payload_cleanup_helper.rb +2 -0
  21. data/lib/sentry/rails/log_subscriber.rb +73 -0
  22. data/lib/sentry/rails/log_subscribers/action_controller_subscriber.rb +116 -0
  23. data/lib/sentry/rails/log_subscribers/action_mailer_subscriber.rb +88 -0
  24. data/lib/sentry/rails/log_subscribers/active_job_subscriber.rb +155 -0
  25. data/lib/sentry/rails/log_subscribers/active_record_subscriber.rb +134 -0
  26. data/lib/sentry/rails/log_subscribers/parameter_filter.rb +52 -0
  27. data/lib/sentry/rails/overrides/streaming_reporter.rb +2 -0
  28. data/lib/sentry/rails/railtie.rb +16 -2
  29. data/lib/sentry/rails/rescued_exception_interceptor.rb +12 -1
  30. data/lib/sentry/rails/structured_logging.rb +32 -0
  31. data/lib/sentry/rails/tracing/abstract_subscriber.rb +2 -0
  32. data/lib/sentry/rails/tracing/action_controller_subscriber.rb +5 -3
  33. data/lib/sentry/rails/tracing/action_view_subscriber.rb +4 -2
  34. data/lib/sentry/rails/tracing/active_record_subscriber.rb +1 -0
  35. data/lib/sentry/rails/tracing/active_storage_subscriber.rb +8 -3
  36. data/lib/sentry/rails/tracing/active_support_subscriber.rb +63 -0
  37. data/lib/sentry/rails/tracing.rb +2 -0
  38. data/lib/sentry/rails/version.rb +3 -1
  39. data/lib/sentry/rails.rb +3 -0
  40. data/lib/sentry-rails.rb +2 -0
  41. data/sentry-rails.gemspec +4 -2
  42. metadata +20 -14
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sentry/rails/log_subscriber"
4
+ require "sentry/rails/log_subscribers/parameter_filter"
5
+
6
+ module Sentry
7
+ module Rails
8
+ module LogSubscribers
9
+ # LogSubscriber for ActiveJob events that captures background job execution
10
+ # and logs them using Sentry's structured logging system.
11
+ #
12
+ # This subscriber captures various ActiveJob events including job execution,
13
+ # enqueueing, retries, and failures with relevant job information.
14
+ #
15
+ # @example Usage
16
+ # # Enable structured logging for ActiveJob
17
+ # Sentry.init do |config|
18
+ # config.enable_logs = true
19
+ # config.rails.structured_logging = true
20
+ # config.rails.structured_logging.subscribers = { active_job: Sentry::Rails::LogSubscribers::ActiveJobSubscriber }
21
+ # end
22
+ class ActiveJobSubscriber < Sentry::Rails::LogSubscriber
23
+ include ParameterFilter
24
+
25
+ # Handle perform.active_job events
26
+ #
27
+ # @param event [ActiveSupport::Notifications::Event] The job performance event
28
+ def perform(event)
29
+ job = event.payload[:job]
30
+ duration = duration_ms(event)
31
+
32
+ attributes = {
33
+ job_class: job.class.name,
34
+ job_id: job.job_id,
35
+ queue_name: job.queue_name,
36
+ duration_ms: duration,
37
+ executions: job.executions,
38
+ priority: job.priority
39
+ }
40
+
41
+ attributes[:adapter] = job.class.queue_adapter.class.name
42
+
43
+ if job.scheduled_at
44
+ attributes[:scheduled_at] = job.scheduled_at.iso8601
45
+ attributes[:delay_ms] = ((Time.current - job.scheduled_at) * 1000).round(2)
46
+ end
47
+
48
+ if Sentry.configuration.send_default_pii && job.arguments.present?
49
+ filtered_args = filter_sensitive_arguments(job.arguments)
50
+ attributes[:arguments] = filtered_args unless filtered_args.empty?
51
+ end
52
+
53
+ message = "Job performed: #{job.class.name}"
54
+
55
+ log_structured_event(
56
+ message: message,
57
+ level: :info,
58
+ attributes: attributes
59
+ )
60
+ end
61
+
62
+ # Handle enqueue.active_job events
63
+ #
64
+ # @param event [ActiveSupport::Notifications::Event] The job enqueue event
65
+ def enqueue(event)
66
+ job = event.payload[:job]
67
+
68
+ attributes = {
69
+ job_class: job.class.name,
70
+ job_id: job.job_id,
71
+ queue_name: job.queue_name,
72
+ priority: job.priority
73
+ }
74
+
75
+ attributes[:adapter] = job.class.queue_adapter.class.name if job.class.respond_to?(:queue_adapter)
76
+
77
+ if job.scheduled_at
78
+ attributes[:scheduled_at] = job.scheduled_at.iso8601
79
+ attributes[:delay_seconds] = (job.scheduled_at - Time.current).round(2)
80
+ end
81
+
82
+ message = "Job enqueued: #{job.class.name}"
83
+
84
+ log_structured_event(
85
+ message: message,
86
+ level: :info,
87
+ attributes: attributes
88
+ )
89
+ end
90
+
91
+ def retry_stopped(event)
92
+ job = event.payload[:job]
93
+ error = event.payload[:error]
94
+
95
+ attributes = {
96
+ job_class: job.class.name,
97
+ job_id: job.job_id,
98
+ queue_name: job.queue_name,
99
+ executions: job.executions,
100
+ error_class: error.class.name,
101
+ error_message: error.message
102
+ }
103
+
104
+ message = "Job retry stopped: #{job.class.name}"
105
+
106
+ log_structured_event(
107
+ message: message,
108
+ level: :error,
109
+ attributes: attributes
110
+ )
111
+ end
112
+
113
+ def discard(event)
114
+ job = event.payload[:job]
115
+ error = event.payload[:error]
116
+
117
+ attributes = {
118
+ job_class: job.class.name,
119
+ job_id: job.job_id,
120
+ queue_name: job.queue_name,
121
+ executions: job.executions
122
+ }
123
+
124
+ attributes[:error_class] = error.class.name if error
125
+ attributes[:error_message] = error.message if error
126
+
127
+ message = "Job discarded: #{job.class.name}"
128
+
129
+ log_structured_event(
130
+ message: message,
131
+ level: :warn,
132
+ attributes: attributes
133
+ )
134
+ end
135
+
136
+ private
137
+
138
+ def filter_sensitive_arguments(arguments)
139
+ return [] unless arguments.is_a?(Array)
140
+
141
+ arguments.map do |arg|
142
+ case arg
143
+ when Hash
144
+ filter_sensitive_params(arg)
145
+ when String
146
+ arg.length > 100 ? "[FILTERED: #{arg.length} chars]" : arg
147
+ else
148
+ arg
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sentry/rails/log_subscriber"
4
+ require "sentry/rails/log_subscribers/parameter_filter"
5
+
6
+ module Sentry
7
+ module Rails
8
+ module LogSubscribers
9
+ # LogSubscriber for ActiveRecord events that captures database queries
10
+ # and logs them using Sentry's structured logging system.
11
+ #
12
+ # This subscriber captures sql.active_record events and formats them
13
+ # with relevant database information including SQL queries, duration,
14
+ # database configuration, and caching information.
15
+ #
16
+ # @example Usage
17
+ # # Automatically attached when structured logging is enabled for :active_record
18
+ # Sentry.init do |config|
19
+ # config.enable_logs = true
20
+ # config.rails.structured_logging = true
21
+ # config.rails.structured_logging.subscribers = { active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber }
22
+ # end
23
+ class ActiveRecordSubscriber < Sentry::Rails::LogSubscriber
24
+ include ParameterFilter
25
+
26
+ EXCLUDED_NAMES = ["SCHEMA", "TRANSACTION"].freeze
27
+
28
+ # Handle sql.active_record events
29
+ #
30
+ # @param event [ActiveSupport::Notifications::Event] The SQL event
31
+ def sql(event)
32
+ return if EXCLUDED_NAMES.include?(event.payload[:name])
33
+
34
+ sql = event.payload[:sql]
35
+ statement_name = event.payload[:name]
36
+
37
+ # Rails 5.0.0 doesn't include :cached in the payload, it was added in Rails 5.1
38
+ cached = event.payload.fetch(:cached, false)
39
+ connection_id = event.payload[:connection_id]
40
+
41
+ db_config = extract_db_config(event.payload)
42
+
43
+ attributes = {
44
+ sql: sql,
45
+ duration_ms: duration_ms(event),
46
+ cached: cached
47
+ }
48
+
49
+ attributes[:statement_name] = statement_name if statement_name && statement_name != "SQL"
50
+ attributes[:connection_id] = connection_id if connection_id
51
+
52
+ add_db_config_attributes(attributes, db_config)
53
+
54
+ message = build_log_message(statement_name)
55
+
56
+ log_structured_event(
57
+ message: message,
58
+ level: :info,
59
+ attributes: attributes
60
+ )
61
+ end
62
+
63
+ private
64
+
65
+ def build_log_message(statement_name)
66
+ if statement_name && statement_name != "SQL"
67
+ "Database query: #{statement_name}"
68
+ else
69
+ "Database query"
70
+ end
71
+ end
72
+
73
+ def extract_db_config(payload)
74
+ connection = payload[:connection]
75
+
76
+ return unless connection
77
+
78
+ extract_db_config_from_connection(connection)
79
+ end
80
+
81
+ def add_db_config_attributes(attributes, db_config)
82
+ return unless db_config
83
+
84
+ attributes[:db_system] = db_config[:adapter] if db_config[:adapter]
85
+
86
+ if db_config[:database]
87
+ db_name = db_config[:database]
88
+
89
+ if db_config[:adapter] == "sqlite3" && db_name.include?("/")
90
+ db_name = File.basename(db_name)
91
+ end
92
+
93
+ attributes[:db_name] = db_name
94
+ end
95
+
96
+ attributes[:server_address] = db_config[:host] if db_config[:host]
97
+ attributes[:server_port] = db_config[:port] if db_config[:port]
98
+ attributes[:server_socket_address] = db_config[:socket] if db_config[:socket]
99
+ end
100
+
101
+ if ::Rails.version.to_f >= 6.1
102
+ def extract_db_config_from_connection(connection)
103
+ if connection.pool.respond_to?(:db_config)
104
+ db_config = connection.pool.db_config
105
+ if db_config.respond_to?(:configuration_hash)
106
+ return db_config.configuration_hash
107
+ elsif db_config.respond_to?(:config)
108
+ return db_config.config
109
+ end
110
+ end
111
+
112
+ extract_db_config_fallback(connection)
113
+ end
114
+ else
115
+ # Rails 6.0 and earlier use spec API
116
+ def extract_db_config_from_connection(connection)
117
+ if connection.pool.respond_to?(:spec)
118
+ spec = connection.pool.spec
119
+ if spec.respond_to?(:config)
120
+ return spec.config
121
+ end
122
+ end
123
+
124
+ extract_db_config_fallback(connection)
125
+ end
126
+ end
127
+
128
+ def extract_db_config_fallback(connection)
129
+ connection.config if connection.respond_to?(:config)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -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
@@ -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"
@@ -47,8 +49,14 @@ module Sentry
47
49
  setup_backtrace_cleanup_callback
48
50
  inject_breadcrumbs_logger
49
51
  activate_tracing
52
+ activate_structured_logging
50
53
 
51
54
  register_error_subscriber(app) if ::Rails.version.to_f >= 7.0 && Sentry.configuration.rails.register_error_subscriber
55
+
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
52
60
  end
53
61
 
54
62
  runner do
@@ -94,14 +102,14 @@ module Sentry
94
102
 
95
103
  def inject_breadcrumbs_logger
96
104
  if Sentry.configuration.breadcrumbs_logger.include?(:active_support_logger)
97
- require 'sentry/rails/breadcrumb/active_support_logger'
105
+ require "sentry/rails/breadcrumb/active_support_logger"
98
106
  Sentry::Rails::Breadcrumb::ActiveSupportLogger.inject(Sentry.configuration.rails.active_support_logger_subscription_items)
99
107
  end
100
108
 
101
109
  if Sentry.configuration.breadcrumbs_logger.include?(:monotonic_active_support_logger)
102
110
  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
103
111
 
104
- require 'sentry/rails/breadcrumb/monotonic_active_support_logger'
112
+ require "sentry/rails/breadcrumb/monotonic_active_support_logger"
105
113
  Sentry::Rails::Breadcrumb::MonotonicActiveSupportLogger.inject
106
114
  end
107
115
  end
@@ -131,6 +139,12 @@ module Sentry
131
139
  end
132
140
  end
133
141
 
142
+ def activate_structured_logging
143
+ if Sentry.configuration.rails.structured_logging.enabled? && Sentry.configuration.enable_logs
144
+ Sentry::Rails::StructuredLogging.attach(Sentry.configuration.rails.structured_logging)
145
+ end
146
+ end
147
+
134
148
  def register_error_subscriber(app)
135
149
  require "sentry/rails/error_subscriber"
136
150
  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.rails.report_rescued_exceptions
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  module Rails
3
5
  module Tracing
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "sentry/rails/tracing/abstract_subscriber"
2
4
  require "sentry/rails/instrument_payload_cleanup_helper"
3
5
 
@@ -8,11 +10,11 @@ module Sentry
8
10
  extend InstrumentPayloadCleanupHelper
9
11
 
10
12
  EVENT_NAMES = ["process_action.action_controller"].freeze
11
- OP_NAME = "view.process_action.action_controller".freeze
12
- SPAN_ORIGIN = "auto.view.rails".freeze
13
+ OP_NAME = "view.process_action.action_controller"
14
+ SPAN_ORIGIN = "auto.view.rails"
13
15
 
14
16
  def self.subscribe!
15
- Sentry.logger.warn <<~MSG
17
+ Sentry.sdk_logger.warn <<~MSG
16
18
  DEPRECATION WARNING: sentry-rails has changed its approach on controller span recording and #{self.name} is now depreacted.
17
19
  Please stop using or referencing #{self.name} as it will be removed in the next major release.
18
20
  MSG
@@ -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,8 +7,8 @@ module Sentry
5
7
  module Tracing
6
8
  class ActionViewSubscriber < AbstractSubscriber
7
9
  EVENT_NAMES = ["render_template.action_view"].freeze
8
- SPAN_PREFIX = "template.".freeze
9
- SPAN_ORIGIN = "auto.template.rails".freeze
10
+ SPAN_PREFIX = "template."
11
+ SPAN_ORIGIN = "auto.template.rails"
10
12
 
11
13
  def self.subscribe!
12
14
  subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
@@ -71,6 +71,7 @@ module Sentry
71
71
 
72
72
  if source_location
73
73
  backtrace_line = Sentry::Backtrace::Line.parse(source_location)
74
+
74
75
  span.set_data(Span::DataConventions::FILEPATH, backtrace_line.file) if backtrace_line.file
75
76
  span.set_data(Span::DataConventions::LINENO, backtrace_line.number) if backtrace_line.number
76
77
  span.set_data(Span::DataConventions::FUNCTION, backtrace_line.method) if backtrace_line.method
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "sentry/rails/tracing/abstract_subscriber"
2
4
 
3
5
  module Sentry
@@ -19,19 +21,22 @@ module Sentry
19
21
  analyze.active_storage
20
22
  ].freeze
21
23
 
22
- SPAN_ORIGIN = "auto.file.rails".freeze
24
+ SPAN_ORIGIN = "auto.file.rails"
23
25
 
24
26
  def self.subscribe!
25
27
  subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
26
28
  record_on_current_span(
27
- op: "file.#{event_name}".freeze,
29
+ op: "file.#{event_name}",
28
30
  origin: SPAN_ORIGIN,
29
31
  start_timestamp: payload[START_TIMESTAMP_NAME],
30
32
  description: payload[:service],
31
33
  duration: duration
32
34
  ) do |span|
33
35
  payload.each do |key, value|
34
- span.set_data(key, value) unless key == START_TIMESTAMP_NAME
36
+ next if key == START_TIMESTAMP_NAME
37
+ next if key == :key && !Sentry.configuration.send_default_pii
38
+
39
+ span.set_data(key, value)
35
40
  end
36
41
  end
37
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  module Rails
3
5
  module Tracing
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  module Rails
3
- VERSION = "5.18.2"
5
+ VERSION = "5.28.1"
4
6
  end
5
7
  end
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
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "sentry/rails/version"
2
4
  require "sentry/rails"
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|
@@ -11,7 +13,7 @@ Gem::Specification.new do |spec|
11
13
  spec.platform = Gem::Platform::RUBY
12
14
  spec.required_ruby_version = '>= 2.4'
13
15
  spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
14
- 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")
15
17
 
16
18
  github_root_uri = 'https://github.com/getsentry/sentry-ruby'
17
19
  spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}"
@@ -29,5 +31,5 @@ Gem::Specification.new do |spec|
29
31
  spec.require_paths = ["lib"]
30
32
 
31
33
  spec.add_dependency "railties", ">= 5.0"
32
- spec.add_dependency "sentry-ruby", "~> 5.18.2"
34
+ spec.add_dependency "sentry-ruby", "~> 5.28.1"
33
35
  end