sentry-ruby 5.19.0 → 5.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Rakefile +2 -0
  4. data/bin/console +1 -0
  5. data/lib/sentry/attachment.rb +3 -5
  6. data/lib/sentry/backtrace.rb +3 -5
  7. data/lib/sentry/baggage.rb +7 -7
  8. data/lib/sentry/breadcrumb/sentry_logger.rb +6 -6
  9. data/lib/sentry/check_in_event.rb +4 -4
  10. data/lib/sentry/client.rb +9 -9
  11. data/lib/sentry/configuration.rb +52 -19
  12. data/lib/sentry/core_ext/object/deep_dup.rb +1 -1
  13. data/lib/sentry/cron/monitor_check_ins.rb +3 -1
  14. data/lib/sentry/cron/monitor_config.rb +1 -1
  15. data/lib/sentry/dsn.rb +3 -3
  16. data/lib/sentry/envelope/item.rb +88 -0
  17. data/lib/sentry/envelope.rb +2 -85
  18. data/lib/sentry/event.rb +7 -7
  19. data/lib/sentry/graphql.rb +1 -1
  20. data/lib/sentry/hub.rb +8 -1
  21. data/lib/sentry/interfaces/mechanism.rb +1 -1
  22. data/lib/sentry/interfaces/request.rb +5 -5
  23. data/lib/sentry/interfaces/single_exception.rb +3 -3
  24. data/lib/sentry/interfaces/stacktrace.rb +3 -1
  25. data/lib/sentry/interfaces/stacktrace_builder.rb +15 -2
  26. data/lib/sentry/logger.rb +1 -1
  27. data/lib/sentry/metrics/aggregator.rb +12 -12
  28. data/lib/sentry/metrics/set_metric.rb +2 -2
  29. data/lib/sentry/metrics.rb +15 -15
  30. data/lib/sentry/net/http.rb +1 -1
  31. data/lib/sentry/profiler/helpers.rb +46 -0
  32. data/lib/sentry/profiler.rb +25 -56
  33. data/lib/sentry/propagation_context.rb +1 -1
  34. data/lib/sentry/rack/capture_exceptions.rb +2 -2
  35. data/lib/sentry/rack.rb +2 -2
  36. data/lib/sentry/rake.rb +2 -2
  37. data/lib/sentry/release_detector.rb +4 -4
  38. data/lib/sentry/scope.rb +1 -0
  39. data/lib/sentry/session_flusher.rb +1 -1
  40. data/lib/sentry/span.rb +6 -0
  41. data/lib/sentry/test_helper.rb +3 -1
  42. data/lib/sentry/transaction.rb +4 -4
  43. data/lib/sentry/transaction_event.rb +1 -2
  44. data/lib/sentry/transport/http_transport.rb +12 -12
  45. data/lib/sentry/transport.rb +4 -4
  46. data/lib/sentry/utils/env_helper.rb +21 -0
  47. data/lib/sentry/utils/real_ip.rb +1 -1
  48. data/lib/sentry/vernier/output.rb +89 -0
  49. data/lib/sentry/vernier/profiler.rb +125 -0
  50. data/lib/sentry/version.rb +1 -1
  51. data/lib/sentry-ruby.rb +5 -4
  52. data/sentry-ruby-core.gemspec +3 -1
  53. data/sentry-ruby.gemspec +3 -1
  54. metadata +13 -8
@@ -13,12 +13,12 @@ module Sentry
13
13
 
14
14
  def detect_release_from_heroku(running_on_heroku)
15
15
  return unless running_on_heroku
16
- ENV['HEROKU_SLUG_COMMIT']
16
+ ENV["HEROKU_SLUG_COMMIT"]
17
17
  end
18
18
 
19
19
  def detect_release_from_capistrano(project_root)
20
- revision_file = File.join(project_root, 'REVISION')
21
- revision_log = File.join(project_root, '..', 'revisions.log')
20
+ revision_file = File.join(project_root, "REVISION")
21
+ revision_log = File.join(project_root, "..", "revisions.log")
22
22
 
23
23
  if File.exist?(revision_file)
24
24
  File.read(revision_file).strip
@@ -32,7 +32,7 @@ module Sentry
32
32
  end
33
33
 
34
34
  def detect_release_from_env
35
- ENV['SENTRY_RELEASE']
35
+ ENV["SENTRY_RELEASE"]
36
36
  end
37
37
  end
38
38
  end
data/lib/sentry/scope.rb CHANGED
@@ -62,6 +62,7 @@ module Sentry
62
62
 
63
63
  if span
64
64
  event.contexts[:trace] ||= span.get_trace_context
65
+ event.dynamic_sampling_context ||= span.get_dynamic_sampling_context
65
66
  else
66
67
  event.contexts[:trace] ||= propagation_context.get_trace_context
67
68
  event.dynamic_sampling_context ||= propagation_context.get_dynamic_sampling_context
@@ -44,7 +44,7 @@ module Sentry
44
44
  def pending_envelope
45
45
  envelope = Envelope.new
46
46
 
47
- header = { type: 'sessions' }
47
+ header = { type: "sessions" }
48
48
  payload = { attrs: attrs, aggregates: @pending_aggregates.values }
49
49
 
50
50
  envelope.add_item(header, payload)
data/lib/sentry/span.rb CHANGED
@@ -160,6 +160,12 @@ module Sentry
160
160
  transaction.get_baggage&.serialize
161
161
  end
162
162
 
163
+ # Returns the Dynamic Sampling Context from the transaction baggage.
164
+ # @return [Hash, nil]
165
+ def get_dynamic_sampling_context
166
+ transaction.get_baggage&.dynamic_sampling_context
167
+ end
168
+
163
169
  # @return [Hash]
164
170
  def to_hash
165
171
  hash = {
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  module TestHelper
3
- DUMMY_DSN = 'http://12345:67890@sentry.localdomain/sentry/42'
5
+ DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42"
4
6
 
5
7
  # Alters the existing SDK configuration with test-suitable options. Mainly:
6
8
  # - Sets a dummy DSN instead of `nil` or an actual DSN.
@@ -9,7 +9,7 @@ module Sentry
9
9
  # @deprecated Use Sentry::PropagationContext::SENTRY_TRACE_REGEXP instead.
10
10
  SENTRY_TRACE_REGEXP = PropagationContext::SENTRY_TRACE_REGEXP
11
11
 
12
- UNLABELD_NAME = "<unlabeled transaction>".freeze
12
+ UNLABELD_NAME = "<unlabeled transaction>"
13
13
  MESSAGE_PREFIX = "[Tracing]"
14
14
 
15
15
  # https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations
@@ -85,7 +85,7 @@ module Sentry
85
85
  @effective_sample_rate = nil
86
86
  @contexts = {}
87
87
  @measurements = {}
88
- @profiler = Profiler.new(@configuration)
88
+ @profiler = @configuration.profiler_class.new(@configuration)
89
89
  init_span_recorder
90
90
  end
91
91
 
@@ -265,8 +265,8 @@ module Sentry
265
265
  else
266
266
  is_backpressure = Sentry.backpressure_monitor&.downsample_factor&.positive?
267
267
  reason = is_backpressure ? :backpressure : :sample_rate
268
- hub.current_client.transport.record_lost_event(reason, 'transaction')
269
- hub.current_client.transport.record_lost_event(reason, 'span')
268
+ hub.current_client.transport.record_lost_event(reason, "transaction")
269
+ hub.current_client.transport.record_lost_event(reason, "span")
270
270
  end
271
271
  end
272
272
 
@@ -74,8 +74,7 @@ module Sentry
74
74
  id: event_id,
75
75
  name: transaction.name,
76
76
  trace_id: transaction.trace_id,
77
- # TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb
78
- active_thead_id: '0'
77
+ active_thread_id: transaction.profiler.active_thread_id.to_s
79
78
  }
80
79
  )
81
80
 
@@ -7,7 +7,7 @@ module Sentry
7
7
  class HTTPTransport < Transport
8
8
  GZIP_ENCODING = "gzip"
9
9
  GZIP_THRESHOLD = 1024 * 30
10
- CONTENT_TYPE = 'application/x-sentry-envelope'
10
+ CONTENT_TYPE = "application/x-sentry-envelope"
11
11
 
12
12
  DEFAULT_DELAY = 60
13
13
  RETRY_AFTER_HEADER = "retry-after"
@@ -38,13 +38,13 @@ module Sentry
38
38
  end
39
39
 
40
40
  headers = {
41
- 'Content-Type' => CONTENT_TYPE,
42
- 'Content-Encoding' => encoding,
43
- 'User-Agent' => USER_AGENT
41
+ "Content-Type" => CONTENT_TYPE,
42
+ "Content-Encoding" => encoding,
43
+ "User-Agent" => USER_AGENT
44
44
  }
45
45
 
46
46
  auth_header = generate_auth_header
47
- headers['X-Sentry-Auth'] = auth_header if auth_header
47
+ headers["X-Sentry-Auth"] = auth_header if auth_header
48
48
 
49
49
  response = conn.start do |http|
50
50
  request = ::Net::HTTP::Post.new(endpoint, headers)
@@ -60,7 +60,7 @@ module Sentry
60
60
  else
61
61
  error_info = "the server responded with status #{response.code}"
62
62
  error_info += "\nbody: #{response.body}"
63
- error_info += " Error in headers is: #{response['x-sentry-error']}" if response['x-sentry-error']
63
+ error_info += " Error in headers is: #{response['x-sentry-error']}" if response["x-sentry-error"]
64
64
 
65
65
  raise Sentry::ExternalError, error_info
66
66
  end
@@ -78,13 +78,13 @@ module Sentry
78
78
 
79
79
  now = Sentry.utc_now.to_i
80
80
  fields = {
81
- 'sentry_version' => PROTOCOL_VERSION,
82
- 'sentry_client' => USER_AGENT,
83
- 'sentry_timestamp' => now,
84
- 'sentry_key' => @dsn.public_key
81
+ "sentry_version" => PROTOCOL_VERSION,
82
+ "sentry_client" => USER_AGENT,
83
+ "sentry_timestamp" => now,
84
+ "sentry_key" => @dsn.public_key
85
85
  }
86
- fields['sentry_secret'] = @dsn.secret_key if @dsn.secret_key
87
- 'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
86
+ fields["sentry_secret"] = @dsn.secret_key if @dsn.secret_key
87
+ "Sentry " + fields.map { |key, value| "#{key}=#{value}" }.join(", ")
88
88
  end
89
89
 
90
90
  def conn
@@ -5,7 +5,7 @@ require "sentry/envelope"
5
5
 
6
6
  module Sentry
7
7
  class Transport
8
- PROTOCOL_VERSION = '7'
8
+ PROTOCOL_VERSION = "7"
9
9
  USER_AGENT = "sentry-ruby/#{Sentry::VERSION}"
10
10
  CLIENT_REPORT_INTERVAL = 30
11
11
 
@@ -134,13 +134,13 @@ module Sentry
134
134
  envelope = Envelope.new(envelope_headers)
135
135
 
136
136
  envelope.add_item(
137
- { type: item_type, content_type: 'application/json' },
137
+ { type: item_type, content_type: "application/json" },
138
138
  event_payload
139
139
  )
140
140
 
141
141
  if event.is_a?(TransactionEvent) && event.profile
142
142
  envelope.add_item(
143
- { type: 'profile', content_type: 'application/json' },
143
+ { type: "profile", content_type: "application/json" },
144
144
  event.profile
145
145
  )
146
146
  end
@@ -185,7 +185,7 @@ module Sentry
185
185
  { reason: reason, category: category, quantity: val }
186
186
  end
187
187
 
188
- item_header = { type: 'client_report' }
188
+ item_header = { type: "client_report" }
189
189
  item_payload = {
190
190
  timestamp: Sentry.utc_now.iso8601,
191
191
  discarded_events: discarded_events_hash
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ module Utils
5
+ module EnvHelper
6
+ TRUTHY_ENV_VALUES = %w[t true yes y 1 on].freeze
7
+ FALSY_ENV_VALUES = %w[f false no n 0 off].freeze
8
+
9
+ def self.env_to_bool(value, strict: false)
10
+ value = value.to_s
11
+ normalized = value.downcase
12
+
13
+ return false if FALSY_ENV_VALUES.include?(normalized)
14
+
15
+ return true if TRUTHY_ENV_VALUES.include?(normalized)
16
+
17
+ strict ? nil : !(value.nil? || value.empty?)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ipaddr'
3
+ require "ipaddr"
4
4
 
5
5
  # Based on ActionDispatch::RemoteIp. All security-related precautions from that
6
6
  # middleware have been removed, because the Event IP just needs to be accurate,
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rbconfig"
5
+
6
+ module Sentry
7
+ module Vernier
8
+ class Output
9
+ include Profiler::Helpers
10
+
11
+ attr_reader :profile
12
+
13
+ def initialize(profile, project_root:, in_app_pattern:, app_dirs_pattern:)
14
+ @profile = profile
15
+ @project_root = project_root
16
+ @in_app_pattern = in_app_pattern
17
+ @app_dirs_pattern = app_dirs_pattern
18
+ end
19
+
20
+ def to_h
21
+ @to_h ||= {
22
+ frames: frames,
23
+ stacks: stacks,
24
+ samples: samples,
25
+ thread_metadata: thread_metadata
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ def thread_metadata
32
+ profile.threads.map { |thread_id, thread_info|
33
+ [thread_id, { name: thread_info[:name] }]
34
+ }.to_h
35
+ end
36
+
37
+ def samples
38
+ profile.threads.flat_map { |thread_id, thread_info|
39
+ started_at = thread_info[:started_at]
40
+ samples, timestamps = thread_info.values_at(:samples, :timestamps)
41
+
42
+ samples.zip(timestamps).map { |stack_id, timestamp|
43
+ elapsed_since_start_ns = timestamp - started_at
44
+
45
+ next if elapsed_since_start_ns < 0
46
+
47
+ {
48
+ thread_id: thread_id.to_s,
49
+ stack_id: stack_id,
50
+ elapsed_since_start_ns: elapsed_since_start_ns.to_s
51
+ }
52
+ }.compact
53
+ }
54
+ end
55
+
56
+ def frames
57
+ funcs = stack_table_hash[:frame_table].fetch(:func)
58
+ lines = stack_table_hash[:func_table].fetch(:first_line)
59
+
60
+ funcs.map do |idx|
61
+ function, mod = split_module(stack_table_hash[:func_table][:name][idx])
62
+
63
+ abs_path = stack_table_hash[:func_table][:filename][idx]
64
+ in_app = in_app?(abs_path)
65
+ filename = compute_filename(abs_path, in_app)
66
+
67
+ {
68
+ function: function,
69
+ module: mod,
70
+ filename: filename,
71
+ abs_path: abs_path,
72
+ lineno: (lineno = lines[idx]) > 0 ? lineno : nil,
73
+ in_app: in_app
74
+ }.compact
75
+ end
76
+ end
77
+
78
+ def stacks
79
+ profile._stack_table.stack_count.times.map do |stack_id|
80
+ profile.stack(stack_id).frames.map(&:idx)
81
+ end
82
+ end
83
+
84
+ def stack_table_hash
85
+ @stack_table_hash ||= profile._stack_table.to_h
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require_relative "../profiler/helpers"
5
+ require_relative "output"
6
+
7
+ module Sentry
8
+ module Vernier
9
+ class Profiler
10
+ EMPTY_RESULT = {}.freeze
11
+
12
+ attr_reader :started, :event_id, :result
13
+
14
+ def initialize(configuration)
15
+ @event_id = SecureRandom.uuid.delete("-")
16
+
17
+ @started = false
18
+ @sampled = nil
19
+
20
+ @profiling_enabled = defined?(Vernier) && configuration.profiling_enabled?
21
+ @profiles_sample_rate = configuration.profiles_sample_rate
22
+ @project_root = configuration.project_root
23
+ @app_dirs_pattern = configuration.app_dirs_pattern
24
+ @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}")
25
+ end
26
+
27
+ def set_initial_sample_decision(transaction_sampled)
28
+ unless @profiling_enabled
29
+ @sampled = false
30
+ return
31
+ end
32
+
33
+ unless transaction_sampled
34
+ @sampled = false
35
+ log("Discarding profile because transaction not sampled")
36
+ return
37
+ end
38
+
39
+ case @profiles_sample_rate
40
+ when 0.0
41
+ @sampled = false
42
+ log("Discarding profile because sample_rate is 0")
43
+ return
44
+ when 1.0
45
+ @sampled = true
46
+ return
47
+ else
48
+ @sampled = Random.rand < @profiles_sample_rate
49
+ end
50
+
51
+ log("Discarding profile due to sampling decision") unless @sampled
52
+ end
53
+
54
+ def start
55
+ return unless @sampled
56
+ return if @started
57
+
58
+ ::Vernier.start_profile
59
+ @started = true
60
+
61
+ log("Started")
62
+
63
+ @started
64
+ rescue RuntimeError => e
65
+ # TODO: once Vernier raises something more dedicated, we should catch that instead
66
+ if e.message.include?("Profile already started")
67
+ log("Not started since running elsewhere")
68
+ else
69
+ log("Failed to start: #{e.message}")
70
+ end
71
+ end
72
+
73
+ def stop
74
+ return unless @sampled
75
+ return unless @started
76
+
77
+ @result = ::Vernier.stop_profile
78
+
79
+ log("Stopped")
80
+ end
81
+
82
+ def active_thread_id
83
+ Thread.current.object_id
84
+ end
85
+
86
+ def to_hash
87
+ return EMPTY_RESULT unless @started
88
+
89
+ unless @sampled
90
+ record_lost_event(:sample_rate)
91
+ return EMPTY_RESULT
92
+ end
93
+
94
+ { **profile_meta, profile: output.to_h }
95
+ end
96
+
97
+ private
98
+
99
+ def log(message)
100
+ Sentry.logger.debug(LOGGER_PROGNAME) { "[Profiler::Vernier] #{message}" }
101
+ end
102
+
103
+ def record_lost_event(reason)
104
+ Sentry.get_current_client&.transport&.record_lost_event(reason, "profile")
105
+ end
106
+
107
+ def profile_meta
108
+ {
109
+ event_id: @event_id,
110
+ version: "1",
111
+ platform: "ruby"
112
+ }
113
+ end
114
+
115
+ def output
116
+ @output ||= Output.new(
117
+ result,
118
+ project_root: @project_root,
119
+ app_dirs_pattern: @app_dirs_pattern,
120
+ in_app_pattern: @in_app_pattern
121
+ )
122
+ end
123
+ end
124
+ end
125
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.19.0"
4
+ VERSION = "5.21.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -25,6 +25,7 @@ require "sentry/session_flusher"
25
25
  require "sentry/backpressure_monitor"
26
26
  require "sentry/cron/monitor_check_ins"
27
27
  require "sentry/metrics"
28
+ require "sentry/vernier/profiler"
28
29
 
29
30
  [
30
31
  "sentry/rake",
@@ -41,11 +42,11 @@ module Sentry
41
42
 
42
43
  CAPTURED_SIGNATURE = :@__sentry_captured
43
44
 
44
- LOGGER_PROGNAME = "sentry".freeze
45
+ LOGGER_PROGNAME = "sentry"
45
46
 
46
- SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze
47
+ SENTRY_TRACE_HEADER_NAME = "sentry-trace"
47
48
 
48
- BAGGAGE_HEADER_NAME = "baggage".freeze
49
+ BAGGAGE_HEADER_NAME = "baggage"
49
50
 
50
51
  THREAD_LOCAL = :sentry_hub
51
52
 
@@ -563,7 +564,7 @@ module Sentry
563
564
  #
564
565
  # @return [String]
565
566
  def get_trace_propagation_meta
566
- return '' unless initialized?
567
+ return "" unless initialized?
567
568
  get_current_hub.get_trace_propagation_meta
568
569
  end
569
570
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "lib/sentry/version"
2
4
 
3
5
  Gem::Specification.new do |spec|
@@ -12,7 +14,7 @@ Gem::Specification.new do |spec|
12
14
  spec.platform = Gem::Platform::RUBY
13
15
  spec.required_ruby_version = '>= 2.4'
14
16
  spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
15
- spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
17
+ spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n")
16
18
 
17
19
  spec.metadata["homepage_uri"] = spec.homepage
18
20
  spec.metadata["source_code_uri"] = spec.homepage
data/sentry-ruby.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "lib/sentry/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}"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.19.0
4
+ version: 5.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-13 00:00:00.000000000 Z
11
+ date: 2024-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -83,6 +83,7 @@ files:
83
83
  - lib/sentry/cron/monitor_schedule.rb
84
84
  - lib/sentry/dsn.rb
85
85
  - lib/sentry/envelope.rb
86
+ - lib/sentry/envelope/item.rb
86
87
  - lib/sentry/error_event.rb
87
88
  - lib/sentry/event.rb
88
89
  - lib/sentry/exceptions.rb
@@ -112,6 +113,7 @@ files:
112
113
  - lib/sentry/metrics/timing.rb
113
114
  - lib/sentry/net/http.rb
114
115
  - lib/sentry/profiler.rb
116
+ - lib/sentry/profiler/helpers.rb
115
117
  - lib/sentry/propagation_context.rb
116
118
  - lib/sentry/puma.rb
117
119
  - lib/sentry/rack.rb
@@ -135,23 +137,26 @@ files:
135
137
  - lib/sentry/utils/argument_checking_helper.rb
136
138
  - lib/sentry/utils/custom_inspection.rb
137
139
  - lib/sentry/utils/encoding_helper.rb
140
+ - lib/sentry/utils/env_helper.rb
138
141
  - lib/sentry/utils/exception_cause_chain.rb
139
142
  - lib/sentry/utils/http_tracing.rb
140
143
  - lib/sentry/utils/logging_helper.rb
141
144
  - lib/sentry/utils/real_ip.rb
142
145
  - lib/sentry/utils/request_id.rb
146
+ - lib/sentry/vernier/output.rb
147
+ - lib/sentry/vernier/profiler.rb
143
148
  - lib/sentry/version.rb
144
149
  - sentry-ruby-core.gemspec
145
150
  - sentry-ruby.gemspec
146
- homepage: https://github.com/getsentry/sentry-ruby/tree/5.19.0/sentry-ruby
151
+ homepage: https://github.com/getsentry/sentry-ruby/tree/5.21.0/sentry-ruby
147
152
  licenses:
148
153
  - MIT
149
154
  metadata:
150
- homepage_uri: https://github.com/getsentry/sentry-ruby/tree/5.19.0/sentry-ruby
151
- source_code_uri: https://github.com/getsentry/sentry-ruby/tree/5.19.0/sentry-ruby
152
- changelog_uri: https://github.com/getsentry/sentry-ruby/blob/5.19.0/CHANGELOG.md
155
+ homepage_uri: https://github.com/getsentry/sentry-ruby/tree/5.21.0/sentry-ruby
156
+ source_code_uri: https://github.com/getsentry/sentry-ruby/tree/5.21.0/sentry-ruby
157
+ changelog_uri: https://github.com/getsentry/sentry-ruby/blob/5.21.0/CHANGELOG.md
153
158
  bug_tracker_uri: https://github.com/getsentry/sentry-ruby/issues
154
- documentation_uri: http://www.rubydoc.info/gems/sentry-ruby/5.19.0
159
+ documentation_uri: http://www.rubydoc.info/gems/sentry-ruby/5.21.0
155
160
  post_install_message:
156
161
  rdoc_options: []
157
162
  require_paths:
@@ -167,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
172
  - !ruby/object:Gem::Version
168
173
  version: '0'
169
174
  requirements: []
170
- rubygems_version: 3.5.11
175
+ rubygems_version: 3.5.16
171
176
  signing_key:
172
177
  specification_version: 4
173
178
  summary: A gem that provides a client interface for the Sentry error logger