sentry-ruby 5.19.0 → 5.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sentry/attachment.rb +3 -5
  3. data/lib/sentry/backtrace.rb +1 -3
  4. data/lib/sentry/baggage.rb +6 -6
  5. data/lib/sentry/breadcrumb/sentry_logger.rb +6 -6
  6. data/lib/sentry/check_in_event.rb +4 -4
  7. data/lib/sentry/client.rb +9 -9
  8. data/lib/sentry/configuration.rb +28 -13
  9. data/lib/sentry/core_ext/object/deep_dup.rb +1 -1
  10. data/lib/sentry/cron/monitor_check_ins.rb +1 -1
  11. data/lib/sentry/cron/monitor_config.rb +1 -1
  12. data/lib/sentry/dsn.rb +3 -3
  13. data/lib/sentry/envelope.rb +8 -8
  14. data/lib/sentry/event.rb +7 -7
  15. data/lib/sentry/graphql.rb +1 -1
  16. data/lib/sentry/hub.rb +8 -1
  17. data/lib/sentry/interfaces/mechanism.rb +1 -1
  18. data/lib/sentry/interfaces/request.rb +5 -5
  19. data/lib/sentry/interfaces/single_exception.rb +1 -1
  20. data/lib/sentry/interfaces/stacktrace.rb +3 -1
  21. data/lib/sentry/interfaces/stacktrace_builder.rb +15 -2
  22. data/lib/sentry/logger.rb +1 -1
  23. data/lib/sentry/metrics/aggregator.rb +12 -12
  24. data/lib/sentry/metrics/set_metric.rb +2 -2
  25. data/lib/sentry/metrics.rb +15 -15
  26. data/lib/sentry/net/http.rb +1 -1
  27. data/lib/sentry/profiler.rb +19 -20
  28. data/lib/sentry/propagation_context.rb +1 -1
  29. data/lib/sentry/rack/capture_exceptions.rb +1 -1
  30. data/lib/sentry/rack.rb +2 -2
  31. data/lib/sentry/rake.rb +2 -2
  32. data/lib/sentry/release_detector.rb +4 -4
  33. data/lib/sentry/scope.rb +1 -0
  34. data/lib/sentry/session_flusher.rb +1 -1
  35. data/lib/sentry/span.rb +6 -0
  36. data/lib/sentry/test_helper.rb +1 -1
  37. data/lib/sentry/transaction.rb +2 -2
  38. data/lib/sentry/transaction_event.rb +1 -1
  39. data/lib/sentry/transport/http_transport.rb +12 -12
  40. data/lib/sentry/transport.rb +4 -4
  41. data/lib/sentry/utils/env_helper.rb +21 -0
  42. data/lib/sentry/utils/real_ip.rb +1 -1
  43. data/lib/sentry/version.rb +1 -1
  44. data/lib/sentry-ruby.rb +1 -1
  45. data/sentry-ruby-core.gemspec +1 -1
  46. data/sentry-ruby.gemspec +1 -1
  47. metadata +9 -8
@@ -41,8 +41,8 @@ module Sentry
41
41
  @stacktrace_builder = configuration.stacktrace_builder
42
42
 
43
43
  @default_tags = {}
44
- @default_tags['release'] = configuration.release if configuration.release
45
- @default_tags['environment'] = configuration.environment if configuration.environment
44
+ @default_tags["release"] = configuration.release if configuration.release
45
+ @default_tags["environment"] = configuration.environment if configuration.environment
46
46
 
47
47
  @mutex = Mutex.new
48
48
 
@@ -59,7 +59,7 @@ module Sentry
59
59
  def add(type,
60
60
  key,
61
61
  value,
62
- unit: 'none',
62
+ unit: "none",
63
63
  tags: {},
64
64
  timestamp: nil,
65
65
  stacklevel: nil)
@@ -98,7 +98,7 @@ module Sentry
98
98
  unless flushable_buckets.empty?
99
99
  payload = serialize_buckets(flushable_buckets)
100
100
  envelope.add_item(
101
- { type: 'statsd', length: payload.bytesize },
101
+ { type: "statsd", length: payload.bytesize },
102
102
  payload
103
103
  )
104
104
  end
@@ -107,7 +107,7 @@ module Sentry
107
107
  code_locations.each do |timestamp, locations|
108
108
  payload = serialize_locations(timestamp, locations)
109
109
  envelope.add_item(
110
- { type: 'metric_meta', content_type: 'application/json' },
110
+ { type: "metric_meta", content_type: "application/json" },
111
111
  payload
112
112
  )
113
113
  end
@@ -161,8 +161,8 @@ module Sentry
161
161
  buckets.map do |timestamp, timestamp_buckets|
162
162
  timestamp_buckets.map do |metric_key, metric|
163
163
  type, key, unit, tags = metric_key
164
- values = metric.serialize.join(':')
165
- sanitized_tags = tags.map { |k, v| "#{sanitize_tag_key(k)}:#{sanitize_tag_value(v)}" }.join(',')
164
+ values = metric.serialize.join(":")
165
+ sanitized_tags = tags.map { |k, v| "#{sanitize_tag_key(k)}:#{sanitize_tag_value(v)}" }.join(",")
166
166
 
167
167
  "#{sanitize_key(key)}@#{sanitize_unit(unit)}:#{values}|#{type}|\##{sanitized_tags}|T#{timestamp}"
168
168
  end
@@ -175,22 +175,22 @@ module Sentry
175
175
  mri = "#{type}:#{sanitize_key(key)}@#{sanitize_unit(unit)}"
176
176
 
177
177
  # note this needs to be an array but it really doesn't serve a purpose right now
178
- [mri, [location.merge(type: 'location')]]
178
+ [mri, [location.merge(type: "location")]]
179
179
  end.to_h
180
180
 
181
181
  { timestamp: timestamp, mapping: mapping }
182
182
  end
183
183
 
184
184
  def sanitize_key(key)
185
- key.gsub(KEY_SANITIZATION_REGEX, '_')
185
+ key.gsub(KEY_SANITIZATION_REGEX, "_")
186
186
  end
187
187
 
188
188
  def sanitize_unit(unit)
189
- unit.gsub(UNIT_SANITIZATION_REGEX, '')
189
+ unit.gsub(UNIT_SANITIZATION_REGEX, "")
190
190
  end
191
191
 
192
192
  def sanitize_tag_key(key)
193
- key.gsub(TAG_KEY_SANITIZATION_REGEX, '')
193
+ key.gsub(TAG_KEY_SANITIZATION_REGEX, "")
194
194
  end
195
195
 
196
196
  def sanitize_tag_value(value)
@@ -209,7 +209,7 @@ module Sentry
209
209
  updated_tags = @default_tags.merge(tags)
210
210
 
211
211
  transaction_name = get_transaction_name
212
- updated_tags['transaction'] = transaction_name if transaction_name
212
+ updated_tags["transaction"] = transaction_name if transaction_name
213
213
 
214
214
  updated_tags
215
215
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
- require 'zlib'
3
+ require "set"
4
+ require "zlib"
5
5
 
6
6
  module Sentry
7
7
  module Metrics
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sentry/metrics/metric'
4
- require 'sentry/metrics/counter_metric'
5
- require 'sentry/metrics/distribution_metric'
6
- require 'sentry/metrics/gauge_metric'
7
- require 'sentry/metrics/set_metric'
8
- require 'sentry/metrics/timing'
9
- require 'sentry/metrics/aggregator'
3
+ require "sentry/metrics/metric"
4
+ require "sentry/metrics/counter_metric"
5
+ require "sentry/metrics/distribution_metric"
6
+ require "sentry/metrics/gauge_metric"
7
+ require "sentry/metrics/set_metric"
8
+ require "sentry/metrics/timing"
9
+ require "sentry/metrics/aggregator"
10
10
 
11
11
  module Sentry
12
12
  module Metrics
@@ -14,32 +14,32 @@ module Sentry
14
14
  INFORMATION_UNITS = %w[bit byte kilobyte kibibyte megabyte mebibyte gigabyte gibibyte terabyte tebibyte petabyte pebibyte exabyte exbibyte]
15
15
  FRACTIONAL_UNITS = %w[ratio percent]
16
16
 
17
- OP_NAME = 'metric.timing'
18
- SPAN_ORIGIN = 'auto.metric.timing'
17
+ OP_NAME = "metric.timing"
18
+ SPAN_ORIGIN = "auto.metric.timing"
19
19
 
20
20
  class << self
21
- def increment(key, value = 1.0, unit: 'none', tags: {}, timestamp: nil)
21
+ def increment(key, value = 1.0, unit: "none", tags: {}, timestamp: nil)
22
22
  Sentry.metrics_aggregator&.add(:c, key, value, unit: unit, tags: tags, timestamp: timestamp)
23
23
  end
24
24
 
25
- def distribution(key, value, unit: 'none', tags: {}, timestamp: nil)
25
+ def distribution(key, value, unit: "none", tags: {}, timestamp: nil)
26
26
  Sentry.metrics_aggregator&.add(:d, key, value, unit: unit, tags: tags, timestamp: timestamp)
27
27
  end
28
28
 
29
- def set(key, value, unit: 'none', tags: {}, timestamp: nil)
29
+ def set(key, value, unit: "none", tags: {}, timestamp: nil)
30
30
  Sentry.metrics_aggregator&.add(:s, key, value, unit: unit, tags: tags, timestamp: timestamp)
31
31
  end
32
32
 
33
- def gauge(key, value, unit: 'none', tags: {}, timestamp: nil)
33
+ def gauge(key, value, unit: "none", tags: {}, timestamp: nil)
34
34
  Sentry.metrics_aggregator&.add(:g, key, value, unit: unit, tags: tags, timestamp: timestamp)
35
35
  end
36
36
 
37
- def timing(key, unit: 'second', tags: {}, timestamp: nil, &block)
37
+ def timing(key, unit: "second", tags: {}, timestamp: nil, &block)
38
38
  return unless block_given?
39
39
  return yield unless DURATION_UNITS.include?(unit)
40
40
 
41
41
  result, value = Sentry.with_child_span(op: OP_NAME, description: key, origin: SPAN_ORIGIN) do |span|
42
- tags.each { |k, v| span.set_tag(k, v.is_a?(Array) ? v.join(', ') : v.to_s) } if span
42
+ tags.each { |k, v| span.set_tag(k, v.is_a?(Array) ? v.join(", ") : v.to_s) } if span
43
43
 
44
44
  start = Timing.send(unit.to_sym)
45
45
  result = yield
@@ -66,7 +66,7 @@ module Sentry
66
66
  # IPv6 url could look like '::1/path', and that won't parse without
67
67
  # wrapping it in square brackets.
68
68
  hostname = address =~ Resolv::IPv6::Regex ? "[#{address}]" : address
69
- uri = req.uri || URI.parse("#{use_ssl? ? 'https' : 'http'}://#{hostname}#{req.path}")
69
+ uri = req.uri || URI.parse(URI::DEFAULT_PARSER.escape("#{use_ssl? ? 'https' : 'http'}://#{hostname}#{req.path}"))
70
70
  url = "#{uri.scheme}://#{uri.host}#{uri.path}" rescue uri.to_s
71
71
 
72
72
  result = { method: req.method, url: url }
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
3
+ require "securerandom"
4
4
 
5
5
  module Sentry
6
6
  class Profiler
7
- VERSION = '1'
8
- PLATFORM = 'ruby'
7
+ VERSION = "1"
8
+ PLATFORM = "ruby"
9
9
  # 101 Hz in microseconds
10
10
  DEFAULT_INTERVAL = 1e6 / 101
11
11
  MICRO_TO_NANO_SECONDS = 1e3
@@ -14,14 +14,14 @@ module Sentry
14
14
  attr_reader :sampled, :started, :event_id
15
15
 
16
16
  def initialize(configuration)
17
- @event_id = SecureRandom.uuid.delete('-')
17
+ @event_id = SecureRandom.uuid.delete("-")
18
18
  @started = false
19
19
  @sampled = nil
20
20
 
21
21
  @profiling_enabled = defined?(StackProf) && configuration.profiling_enabled?
22
22
  @profiles_sample_rate = configuration.profiles_sample_rate
23
23
  @project_root = configuration.project_root
24
- @app_dirs_pattern = configuration.app_dirs_pattern || Backtrace::APP_DIRS_PATTERN
24
+ @app_dirs_pattern = configuration.app_dirs_pattern
25
25
  @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}")
26
26
  end
27
27
 
@@ -33,7 +33,7 @@ module Sentry
33
33
  raw: true,
34
34
  aggregate: false)
35
35
 
36
- @started ? log('Started') : log('Not started since running elsewhere')
36
+ @started ? log("Started") : log("Not started since running elsewhere")
37
37
  end
38
38
 
39
39
  def stop
@@ -41,7 +41,7 @@ module Sentry
41
41
  return unless @started
42
42
 
43
43
  StackProf.stop
44
- log('Stopped')
44
+ log("Stopped")
45
45
  end
46
46
 
47
47
  # Sets initial sampling decision of the profile.
@@ -54,14 +54,14 @@ module Sentry
54
54
 
55
55
  unless transaction_sampled
56
56
  @sampled = false
57
- log('Discarding profile because transaction not sampled')
57
+ log("Discarding profile because transaction not sampled")
58
58
  return
59
59
  end
60
60
 
61
61
  case @profiles_sample_rate
62
62
  when 0.0
63
63
  @sampled = false
64
- log('Discarding profile because sample_rate is 0')
64
+ log("Discarding profile because sample_rate is 0")
65
65
  return
66
66
  when 1.0
67
67
  @sampled = true
@@ -70,7 +70,7 @@ module Sentry
70
70
  @sampled = Random.rand < @profiles_sample_rate
71
71
  end
72
72
 
73
- log('Discarding profile due to sampling decision') unless @sampled
73
+ log("Discarding profile due to sampling decision") unless @sampled
74
74
  end
75
75
 
76
76
  def to_hash
@@ -90,13 +90,12 @@ module Sentry
90
90
 
91
91
  frame_map = {}
92
92
 
93
- frames = results[:frames].to_enum.with_index.map do |frame, idx|
94
- frame_id, frame_data = frame
95
-
93
+ frames = results[:frames].map.with_index do |(frame_id, frame_data), idx|
96
94
  # need to map over stackprof frame ids to ours
97
95
  frame_map[frame_id] = idx
98
96
 
99
97
  file_path = frame_data[:file]
98
+ lineno = frame_data[:line]
100
99
  in_app = in_app?(file_path)
101
100
  filename = compute_filename(file_path, in_app)
102
101
  function, mod = split_module(frame_data[:name])
@@ -109,7 +108,7 @@ module Sentry
109
108
  }
110
109
 
111
110
  frame_hash[:module] = mod if mod
112
- frame_hash[:lineno] = frame_data[:line] if frame_data[:line] && frame_data[:line] >= 0
111
+ frame_hash[:lineno] = lineno if lineno && lineno >= 0
113
112
 
114
113
  frame_hash
115
114
  end
@@ -130,7 +129,7 @@ module Sentry
130
129
  num_seen << results[:raw][idx + len]
131
130
  idx += len + 1
132
131
 
133
- log('Unknown frame in stack') if stack.size != len
132
+ log("Unknown frame in stack") if stack.size != len
134
133
  end
135
134
 
136
135
  idx = 0
@@ -155,16 +154,16 @@ module Sentry
155
154
  # Till then, on multi-threaded servers like puma, we will get frames from other active threads when the one
156
155
  # we're profiling is idle/sleeping/waiting for IO etc.
157
156
  # https://bugs.ruby-lang.org/issues/10602
158
- thread_id: '0',
157
+ thread_id: "0",
159
158
  elapsed_since_start_ns: elapsed_since_start_ns.to_s
160
159
  }
161
160
  end
162
161
  end
163
162
 
164
- log('Some samples thrown away') if samples.size != results[:samples]
163
+ log("Some samples thrown away") if samples.size != results[:samples]
165
164
 
166
165
  if samples.size <= MIN_SAMPLES_REQUIRED
167
- log('Not enough samples, discarding profiler')
166
+ log("Not enough samples, discarding profiler")
168
167
  record_lost_event(:insufficient_data)
169
168
  return {}
170
169
  end
@@ -219,7 +218,7 @@ module Sentry
219
218
 
220
219
  def split_module(name)
221
220
  # last module plus class/instance method
222
- i = name.rindex('::')
221
+ i = name.rindex("::")
223
222
  function = i ? name[(i + 2)..-1] : name
224
223
  mod = i ? name[0...i] : nil
225
224
 
@@ -227,7 +226,7 @@ module Sentry
227
226
  end
228
227
 
229
228
  def record_lost_event(reason)
230
- Sentry.get_current_client&.transport&.record_lost_event(reason, 'profile')
229
+ Sentry.get_current_client&.transport&.record_lost_event(reason, "profile")
231
230
  end
232
231
  end
233
232
  end
@@ -108,7 +108,7 @@ module Sentry
108
108
  end
109
109
 
110
110
  # Returns the Dynamic Sampling Context from the baggage.
111
- # @return [String, nil]
111
+ # @return [Hash, nil]
112
112
  def get_dynamic_sampling_context
113
113
  get_baggage&.dynamic_sampling_context
114
114
  end
@@ -50,7 +50,7 @@ module Sentry
50
50
  private
51
51
 
52
52
  def collect_exception(env)
53
- env['rack.exception'] || env['sinatra.error']
53
+ env["rack.exception"] || env["sinatra.error"]
54
54
  end
55
55
 
56
56
  def transaction_op
data/lib/sentry/rack.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack'
3
+ require "rack"
4
4
 
5
- require 'sentry/rack/capture_exceptions'
5
+ require "sentry/rack/capture_exceptions"
data/lib/sentry/rake.rb CHANGED
@@ -8,10 +8,10 @@ module Sentry
8
8
  module Application
9
9
  # @api private
10
10
  def display_error_message(ex)
11
- mechanism = Sentry::Mechanism.new(type: 'rake', handled: false)
11
+ mechanism = Sentry::Mechanism.new(type: "rake", handled: false)
12
12
 
13
13
  Sentry.capture_exception(ex, hint: { mechanism: mechanism }) do |scope|
14
- task_name = top_level_tasks.join(' ')
14
+ task_name = top_level_tasks.join(" ")
15
15
  scope.set_transaction_name(task_name, source: :task)
16
16
  scope.set_tag("rake_task", task_name)
17
17
  end if Sentry.initialized? && !Sentry.configuration.skip_rake_integration
@@ -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,6 @@
1
1
  module Sentry
2
2
  module TestHelper
3
- DUMMY_DSN = 'http://12345:67890@sentry.localdomain/sentry/42'
3
+ DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42"
4
4
 
5
5
  # Alters the existing SDK configuration with test-suitable options. Mainly:
6
6
  # - Sets a dummy DSN instead of `nil` or an actual DSN.
@@ -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
 
@@ -75,7 +75,7 @@ module Sentry
75
75
  name: transaction.name,
76
76
  trace_id: transaction.trace_id,
77
77
  # TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb
78
- active_thead_id: '0'
78
+ active_thead_id: "0"
79
79
  }
80
80
  )
81
81
 
@@ -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,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.19.0"
4
+ VERSION = "5.20.1"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -563,7 +563,7 @@ module Sentry
563
563
  #
564
564
  # @return [String]
565
565
  def get_trace_propagation_meta
566
- return '' unless initialized?
566
+ return "" unless initialized?
567
567
  get_current_hub.get_trace_propagation_meta
568
568
  end
569
569
 
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.platform = Gem::Platform::RUBY
13
13
  spec.required_ruby_version = '>= 2.4'
14
14
  spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
15
- spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
15
+ spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n")
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
data/sentry-ruby.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.platform = Gem::Platform::RUBY
12
12
  spec.required_ruby_version = '>= 2.4'
13
13
  spec.extra_rdoc_files = ["README.md", "LICENSE.txt"]
14
- spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
14
+ spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n")
15
15
 
16
16
  github_root_uri = 'https://github.com/getsentry/sentry-ruby'
17
17
  spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}"