sentry-ruby 5.23.0 → 5.27.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -1
  3. data/Gemfile +1 -3
  4. data/README.md +11 -6
  5. data/Rakefile +7 -11
  6. data/lib/sentry/background_worker.rb +2 -3
  7. data/lib/sentry/backpressure_monitor.rb +1 -1
  8. data/lib/sentry/breadcrumb.rb +5 -4
  9. data/lib/sentry/check_in_event.rb +2 -1
  10. data/lib/sentry/client.rb +84 -4
  11. data/lib/sentry/configuration.rb +63 -2
  12. data/lib/sentry/debug_structured_logger.rb +94 -0
  13. data/lib/sentry/dsn.rb +32 -0
  14. data/lib/sentry/envelope/item.rb +1 -1
  15. data/lib/sentry/event.rb +2 -1
  16. data/lib/sentry/hub.rb +13 -1
  17. data/lib/sentry/interfaces/request.rb +1 -1
  18. data/lib/sentry/log_event.rb +206 -0
  19. data/lib/sentry/log_event_buffer.rb +75 -0
  20. data/lib/sentry/metrics/aggregator.rb +1 -1
  21. data/lib/sentry/profiler.rb +3 -2
  22. data/lib/sentry/propagation_context.rb +59 -22
  23. data/lib/sentry/scope.rb +13 -3
  24. data/lib/sentry/session_flusher.rb +1 -1
  25. data/lib/sentry/span.rb +4 -3
  26. data/lib/sentry/std_lib_logger.rb +50 -0
  27. data/lib/sentry/structured_logger.rb +138 -0
  28. data/lib/sentry/test_helper.rb +29 -0
  29. data/lib/sentry/threaded_periodic_worker.rb +3 -3
  30. data/lib/sentry/transaction.rb +30 -8
  31. data/lib/sentry/transport/debug_transport.rb +70 -0
  32. data/lib/sentry/transport/dummy_transport.rb +1 -0
  33. data/lib/sentry/transport/http_transport.rb +9 -5
  34. data/lib/sentry/transport.rb +17 -8
  35. data/lib/sentry/utils/logging_helper.rb +10 -3
  36. data/lib/sentry/utils/sample_rand.rb +97 -0
  37. data/lib/sentry/utils/uuid.rb +13 -0
  38. data/lib/sentry/vernier/profiler.rb +3 -2
  39. data/lib/sentry/version.rb +1 -1
  40. data/lib/sentry-ruby.rb +67 -4
  41. metadata +17 -9
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ # The StructuredLogger class implements Sentry's SDK telemetry logs protocol.
5
+ # It provides methods for logging messages at different severity levels and
6
+ # sending them to Sentry with structured data.
7
+ #
8
+ # This class follows the Sentry Logs Protocol as defined in:
9
+ # https://develop.sentry.dev/sdk/telemetry/logs/
10
+ #
11
+ # @example Basic usage
12
+ # Sentry.logger.info("User logged in", user_id: 123)
13
+ #
14
+ # @example With structured data
15
+ # Sentry.logger.warn("API request failed",
16
+ # status_code: 404,
17
+ # endpoint: "/api/users",
18
+ # request_id: "abc-123"
19
+ # )
20
+ #
21
+ # @example With a message template
22
+ # # Using positional parameters
23
+ # Sentry.logger.info("User %s logged in", ["Jane Doe"])
24
+ #
25
+ # # Using hash parameters
26
+ # Sentry.logger.info("User %{name} logged in", name: "Jane Doe")
27
+ #
28
+ # # Using hash parameters and extra attributes
29
+ # Sentry.logger.info("User %{name} logged in", name: "Jane Doe", user_id: 312)
30
+ #
31
+ # @see https://develop.sentry.dev/sdk/telemetry/logs/ Sentry SDK Telemetry Logs Protocol
32
+ class StructuredLogger
33
+ # Severity number mapping for log levels according to the Sentry Logs Protocol
34
+ # @see https://develop.sentry.dev/sdk/telemetry/logs/#log-severity-number
35
+ LEVELS = {
36
+ trace: 1,
37
+ debug: 5,
38
+ info: 9,
39
+ warn: 13,
40
+ error: 17,
41
+ fatal: 21
42
+ }.freeze
43
+
44
+ # @return [Configuration] The Sentry configuration
45
+ # @!visibility private
46
+ attr_reader :config
47
+
48
+ # Initializes a new StructuredLogger instance
49
+ #
50
+ # @param config [Configuration] The Sentry configuration
51
+ def initialize(config)
52
+ @config = config
53
+ end
54
+
55
+ # Logs a message at TRACE level
56
+ #
57
+ # @param message [String] The log message
58
+ # @param parameters [Array] Array of values to replace template parameters in the message
59
+ # @param attributes [Hash] Additional attributes to include with the log
60
+ #
61
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
62
+ def trace(message, parameters = [], **attributes)
63
+ log(__method__, message, parameters: parameters, **attributes)
64
+ end
65
+
66
+ # Logs a message at DEBUG level
67
+ #
68
+ # @param message [String] The log message
69
+ # @param parameters [Array] Array of values to replace template parameters in the message
70
+ # @param attributes [Hash] Additional attributes to include with the log
71
+ #
72
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
73
+ def debug(message, parameters = [], **attributes)
74
+ log(__method__, message, parameters: parameters, **attributes)
75
+ end
76
+
77
+ # Logs a message at INFO level
78
+ #
79
+ # @param message [String] The log message
80
+ # @param parameters [Array] Array of values to replace template parameters in the message
81
+ # @param attributes [Hash] Additional attributes to include with the log
82
+ #
83
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
84
+ def info(message, parameters = [], **attributes)
85
+ log(__method__, message, parameters: parameters, **attributes)
86
+ end
87
+
88
+ # Logs a message at WARN level
89
+ #
90
+ # @param message [String] The log message
91
+ # @param parameters [Array] Array of values to replace template parameters in the message
92
+ # @param attributes [Hash] Additional attributes to include with the log
93
+ #
94
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
95
+ def warn(message, parameters = [], **attributes)
96
+ log(__method__, message, parameters: parameters, **attributes)
97
+ end
98
+
99
+ # Logs a message at ERROR level
100
+ #
101
+ # @param message [String] The log message
102
+ # @param parameters [Array] Array of values to replace template parameters in the message
103
+ # @param attributes [Hash] Additional attributes to include with the log
104
+ #
105
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
106
+ def error(message, parameters = [], **attributes)
107
+ log(__method__, message, parameters: parameters, **attributes)
108
+ end
109
+
110
+ # Logs a message at FATAL level
111
+ #
112
+ # @param message [String] The log message
113
+ # @param parameters [Array] Array of values to replace template parameters in the message
114
+ # @param attributes [Hash] Additional attributes to include with the log
115
+ #
116
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
117
+ def fatal(message, parameters = [], **attributes)
118
+ log(__method__, message, parameters: parameters, **attributes)
119
+ end
120
+
121
+ # Logs a message at the specified level
122
+ #
123
+ # @param level [Symbol] The log level (:trace, :debug, :info, :warn, :error, :fatal)
124
+ # @param message [String] The log message
125
+ # @param parameters [Array, Hash] Array or Hash of values to replace template parameters in the message
126
+ # @param attributes [Hash] Additional attributes to include with the log
127
+ #
128
+ # @return [LogEvent, nil] The created log event or nil if logging is disabled
129
+ def log(level, message, parameters:, **attributes)
130
+ case parameters
131
+ when Array then
132
+ Sentry.capture_log(message, level: level, severity: LEVELS[level], parameters: parameters, **attributes)
133
+ else
134
+ Sentry.capture_log(message, level: level, severity: LEVELS[level], **parameters)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -2,8 +2,13 @@
2
2
 
3
3
  module Sentry
4
4
  module TestHelper
5
+ module_function
6
+
5
7
  DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42"
6
8
 
9
+ # Not really real, but it will be resolved as a non-local for testing needs
10
+ REAL_DSN = "https://user:pass@getsentry.io/project/42"
11
+
7
12
  # Alters the existing SDK configuration with test-suitable options. Mainly:
8
13
  # - Sets a dummy DSN instead of `nil` or an actual DSN.
9
14
  # - Sets the transport to DummyTransport, which allows easy access to the captured events.
@@ -46,6 +51,8 @@ module Sentry
46
51
  def teardown_sentry_test
47
52
  return unless Sentry.initialized?
48
53
 
54
+ clear_sentry_events
55
+
49
56
  # pop testing layer created by `setup_sentry_test`
50
57
  # but keep the base layer to avoid nil-pointer errors
51
58
  # TODO: find a way to notify users if they somehow popped the test layer before calling this method
@@ -55,6 +62,21 @@ module Sentry
55
62
  Sentry::Scope.global_event_processors.clear
56
63
  end
57
64
 
65
+ def clear_sentry_events
66
+ return unless Sentry.initialized?
67
+
68
+ sentry_transport.clear if sentry_transport.respond_to?(:clear)
69
+
70
+ if Sentry.configuration.enable_logs && sentry_logger.respond_to?(:clear)
71
+ sentry_logger.clear
72
+ end
73
+ end
74
+
75
+ # @return [Sentry::StructuredLogger, Sentry::DebugStructuredLogger]
76
+ def sentry_logger
77
+ Sentry.logger
78
+ end
79
+
58
80
  # @return [Transport]
59
81
  def sentry_transport
60
82
  Sentry.get_current_client.transport
@@ -72,6 +94,13 @@ module Sentry
72
94
  sentry_transport.envelopes
73
95
  end
74
96
 
97
+ def sentry_logs
98
+ sentry_envelopes
99
+ .flat_map(&:items)
100
+ .select { |item| item.headers[:type] == "log" }
101
+ .flat_map { |item| item.payload[:items] }
102
+ end
103
+
75
104
  # Returns the last captured event object.
76
105
  # @return [Event, nil]
77
106
  def last_sentry_event
@@ -4,11 +4,11 @@ module Sentry
4
4
  class ThreadedPeriodicWorker
5
5
  include LoggingHelper
6
6
 
7
- def initialize(logger, internal)
7
+ def initialize(sdk_logger, interval)
8
8
  @thread = nil
9
9
  @exited = false
10
- @interval = internal
11
- @logger = logger
10
+ @interval = interval
11
+ @sdk_logger = sdk_logger
12
12
  end
13
13
 
14
14
  def ensure_thread
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "sentry/baggage"
4
4
  require "sentry/profiler"
5
+ require "sentry/utils/sample_rand"
5
6
  require "sentry/propagation_context"
6
7
 
7
8
  module Sentry
@@ -45,9 +46,6 @@ module Sentry
45
46
  # @deprecated Use Sentry.configuration instead.
46
47
  attr_reader :configuration
47
48
 
48
- # @deprecated Use Sentry.logger instead.
49
- attr_reader :logger
50
-
51
49
  # The effective sample rate at which this transaction was sampled.
52
50
  # @return [Float, nil]
53
51
  attr_reader :effective_sample_rate
@@ -60,12 +58,17 @@ module Sentry
60
58
  # @return [Profiler]
61
59
  attr_reader :profiler
62
60
 
61
+ # Sample rand value generated from trace_id
62
+ # @return [String]
63
+ attr_reader :sample_rand
64
+
63
65
  def initialize(
64
66
  hub:,
65
67
  name: nil,
66
68
  source: :custom,
67
69
  parent_sampled: nil,
68
70
  baggage: nil,
71
+ sample_rand: nil,
69
72
  **options
70
73
  )
71
74
  super(transaction: self, **options)
@@ -78,19 +81,25 @@ module Sentry
78
81
  @tracing_enabled = hub.configuration.tracing_enabled?
79
82
  @traces_sampler = hub.configuration.traces_sampler
80
83
  @traces_sample_rate = hub.configuration.traces_sample_rate
81
- @logger = hub.configuration.logger
84
+ @sdk_logger = hub.configuration.sdk_logger
82
85
  @release = hub.configuration.release
83
86
  @environment = hub.configuration.environment
84
87
  @dsn = hub.configuration.dsn
85
88
  @effective_sample_rate = nil
86
89
  @contexts = {}
87
90
  @measurements = {}
91
+ @sample_rand = sample_rand
88
92
 
89
93
  unless @hub.profiler_running?
90
94
  @profiler = @configuration.profiler_class.new(@configuration)
91
95
  end
92
96
 
93
97
  init_span_recorder
98
+
99
+ unless @sample_rand
100
+ generator = Utils::SampleRand.new(trace_id: @trace_id)
101
+ @sample_rand = generator.generate_from_trace_id
102
+ end
94
103
  end
95
104
 
96
105
  # @deprecated use Sentry.continue_trace instead.
@@ -126,12 +135,15 @@ module Sentry
126
135
 
127
136
  baggage.freeze!
128
137
 
138
+ sample_rand = extract_sample_rand_from_baggage(baggage, trace_id, parent_sampled)
139
+
129
140
  new(
130
141
  trace_id: trace_id,
131
142
  parent_span_id: parent_span_id,
132
143
  parent_sampled: parent_sampled,
133
144
  hub: hub,
134
145
  baggage: baggage,
146
+ sample_rand: sample_rand,
135
147
  **options
136
148
  )
137
149
  end
@@ -142,6 +154,11 @@ module Sentry
142
154
  PropagationContext.extract_sentry_trace(sentry_trace)
143
155
  end
144
156
 
157
+ def self.extract_sample_rand_from_baggage(baggage, trace_id, parent_sampled)
158
+ PropagationContext.extract_sample_rand_from_baggage(baggage, trace_id) ||
159
+ PropagationContext.generate_sample_rand(baggage, trace_id, parent_sampled)
160
+ end
161
+
145
162
  # @return [Hash]
146
163
  def to_hash
147
164
  hash = super
@@ -156,6 +173,13 @@ module Sentry
156
173
  hash
157
174
  end
158
175
 
176
+ def parent_sample_rate
177
+ return unless @baggage&.items
178
+
179
+ sample_rate_str = @baggage.items["sample_rate"]
180
+ sample_rate_str&.to_f
181
+ end
182
+
159
183
  # @return [Transaction]
160
184
  def deep_dup
161
185
  copy = super
@@ -228,7 +252,7 @@ module Sentry
228
252
  @effective_sample_rate /= 2**factor
229
253
  end
230
254
 
231
- @sampled = Random.rand < @effective_sample_rate
255
+ @sampled = @sample_rand < @effective_sample_rate
232
256
  end
233
257
 
234
258
  if @sampled
@@ -334,6 +358,7 @@ module Sentry
334
358
  items = {
335
359
  "trace_id" => trace_id,
336
360
  "sample_rate" => effective_sample_rate&.to_s,
361
+ "sample_rand" => Utils::SampleRand.format(@sample_rand),
337
362
  "sampled" => sampled&.to_s,
338
363
  "environment" => @environment,
339
364
  "release" => @release,
@@ -342,9 +367,6 @@ module Sentry
342
367
 
343
368
  items["transaction"] = name unless source_low_quality?
344
369
 
345
- user = @hub.current_scope&.user
346
- items["user_segment"] = user["segment"] if user && user["segment"]
347
-
348
370
  items.compact!
349
371
  @baggage = Baggage.new(items, mutable: false)
350
372
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "fileutils"
5
+ require "pathname"
6
+ require "delegate"
7
+
8
+ module Sentry
9
+ # DebugTransport is a transport that logs events to a file for debugging purposes.
10
+ #
11
+ # It can optionally also send events to Sentry via HTTP transport if a real DSN
12
+ # is provided.
13
+ class DebugTransport < SimpleDelegator
14
+ DEFAULT_LOG_FILE_PATH = File.join("log", "sentry_debug_events.log")
15
+
16
+ attr_reader :log_file, :backend
17
+
18
+ def initialize(configuration)
19
+ @log_file = initialize_log_file(configuration)
20
+ @backend = initialize_backend(configuration)
21
+
22
+ super(@backend)
23
+ end
24
+
25
+ def send_event(event)
26
+ log_envelope(envelope_from_event(event))
27
+ backend.send_event(event)
28
+ end
29
+
30
+ def log_envelope(envelope)
31
+ envelope_json = {
32
+ timestamp: Time.now.utc.iso8601,
33
+ envelope_headers: envelope.headers,
34
+ items: envelope.items.map do |item|
35
+ { headers: item.headers, payload: item.payload }
36
+ end
37
+ }
38
+
39
+ File.open(log_file, "a") { |file| file << JSON.dump(envelope_json) << "\n" }
40
+ end
41
+
42
+ def logged_envelopes
43
+ return [] unless File.exist?(log_file)
44
+
45
+ File.readlines(log_file).map do |line|
46
+ JSON.parse(line)
47
+ end
48
+ end
49
+
50
+ def clear
51
+ File.write(log_file, "")
52
+ log_debug("DebugTransport: Cleared events from #{log_file}")
53
+ end
54
+
55
+ private
56
+
57
+ def initialize_backend(configuration)
58
+ backend = configuration.dsn.local? ? DummyTransport : HTTPTransport
59
+ backend.new(configuration)
60
+ end
61
+
62
+ def initialize_log_file(configuration)
63
+ log_file = Pathname(configuration.sdk_debug_transport_log_file || DEFAULT_LOG_FILE_PATH)
64
+
65
+ FileUtils.mkdir_p(log_file.dirname) unless log_file.dirname.exist?
66
+
67
+ log_file
68
+ end
69
+ end
70
+ end
@@ -12,6 +12,7 @@ module Sentry
12
12
 
13
13
  def send_event(event)
14
14
  @events << event
15
+ super
15
16
  end
16
17
 
17
18
  def send_envelope(envelope)
@@ -45,11 +45,7 @@ module Sentry
45
45
  auth_header = generate_auth_header
46
46
  headers["X-Sentry-Auth"] = auth_header if auth_header
47
47
 
48
- response = conn.start do |http|
49
- request = ::Net::HTTP::Post.new(endpoint, headers)
50
- request.body = data
51
- http.request(request)
52
- end
48
+ response = do_request(endpoint, headers, data)
53
49
 
54
50
  if response.code.match?(/\A2\d{2}/)
55
51
  handle_rate_limited_response(response) if has_rate_limited_header?(response)
@@ -111,6 +107,14 @@ module Sentry
111
107
  connection
112
108
  end
113
109
 
110
+ def do_request(endpoint, headers, body)
111
+ conn.start do |http|
112
+ request = ::Net::HTTP::Post.new(endpoint, headers)
113
+ request.body = body
114
+ http.request(request)
115
+ end
116
+ end
117
+
114
118
  private
115
119
 
116
120
  def has_rate_limited_header?(headers)
@@ -26,11 +26,8 @@ module Sentry
26
26
 
27
27
  attr_reader :rate_limits, :discarded_events, :last_client_report_sent
28
28
 
29
- # @deprecated Use Sentry.logger to retrieve the current logger instead.
30
- attr_reader :logger
31
-
32
29
  def initialize(configuration)
33
- @logger = configuration.logger
30
+ @sdk_logger = configuration.sdk_logger
34
31
  @transport_configuration = configuration.transport
35
32
  @dsn = configuration.dsn
36
33
  @rate_limits = {}
@@ -133,10 +130,21 @@ module Sentry
133
130
 
134
131
  envelope = Envelope.new(envelope_headers)
135
132
 
136
- envelope.add_item(
137
- { type: item_type, content_type: "application/json" },
138
- event_payload
139
- )
133
+ if event.is_a?(LogEvent)
134
+ envelope.add_item(
135
+ {
136
+ type: "log",
137
+ item_count: 1,
138
+ content_type: "application/vnd.sentry.items.log+json"
139
+ },
140
+ { items: [event_payload] }
141
+ )
142
+ else
143
+ envelope.add_item(
144
+ { type: item_type, content_type: "application/json" },
145
+ event_payload
146
+ )
147
+ end
140
148
 
141
149
  if event.is_a?(TransactionEvent) && event.profile
142
150
  envelope.add_item(
@@ -215,3 +223,4 @@ end
215
223
  require "sentry/transport/dummy_transport"
216
224
  require "sentry/transport/http_transport"
217
225
  require "sentry/transport/spotlight_transport"
226
+ require "sentry/transport/debug_transport"
@@ -1,22 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
+ # @private
4
5
  module LoggingHelper
6
+ # @!visibility private
7
+ attr_reader :sdk_logger
8
+
9
+ # @!visibility private
5
10
  def log_error(message, exception, debug: false)
6
11
  message = "#{message}: #{exception.message}"
7
12
  message += "\n#{exception.backtrace.join("\n")}" if debug
8
13
 
9
- @logger.error(LOGGER_PROGNAME) do
14
+ sdk_logger.error(LOGGER_PROGNAME) do
10
15
  message
11
16
  end
12
17
  end
13
18
 
19
+ # @!visibility private
14
20
  def log_debug(message)
15
- @logger.debug(LOGGER_PROGNAME) { message }
21
+ sdk_logger.debug(LOGGER_PROGNAME) { message }
16
22
  end
17
23
 
24
+ # @!visibility private
18
25
  def log_warn(message)
19
- @logger.warn(LOGGER_PROGNAME) { message }
26
+ sdk_logger.warn(LOGGER_PROGNAME) { message }
20
27
  end
21
28
  end
22
29
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ module Utils
5
+ class SampleRand
6
+ PRECISION = 1_000_000.0
7
+ FORMAT_PRECISION = 6
8
+
9
+ attr_reader :trace_id
10
+
11
+ def self.valid?(value)
12
+ return false unless value
13
+ value >= 0.0 && value < 1.0
14
+ end
15
+
16
+ def self.format(value)
17
+ return unless value
18
+
19
+ truncated = (value * PRECISION).floor / PRECISION
20
+ "%.#{FORMAT_PRECISION}f" % truncated
21
+ end
22
+
23
+ def initialize(trace_id: nil)
24
+ @trace_id = trace_id
25
+ end
26
+
27
+ def generate_from_trace_id
28
+ (random_from_trace_id * PRECISION).floor / PRECISION
29
+ end
30
+
31
+ def generate_from_sampling_decision(sampled, sample_rate)
32
+ if invalid_sample_rate?(sample_rate)
33
+ fallback_generation
34
+ else
35
+ generate_based_on_sampling(sampled, sample_rate)
36
+ end
37
+ end
38
+
39
+ def generate_from_value(sample_rand_value)
40
+ parsed_value = parse_value(sample_rand_value)
41
+
42
+ if self.class.valid?(parsed_value)
43
+ parsed_value
44
+ else
45
+ fallback_generation
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def random_from_trace_id
52
+ if @trace_id
53
+ Random.new(@trace_id[0, 16].to_i(16))
54
+ else
55
+ Random.new
56
+ end.rand(1.0)
57
+ end
58
+
59
+ def invalid_sample_rate?(sample_rate)
60
+ sample_rate.nil? || sample_rate <= 0.0 || sample_rate > 1.0
61
+ end
62
+
63
+ def fallback_generation
64
+ if @trace_id
65
+ (random_from_trace_id * PRECISION).floor / PRECISION
66
+ else
67
+ format_random(Random.rand(1.0))
68
+ end
69
+ end
70
+
71
+ def generate_based_on_sampling(sampled, sample_rate)
72
+ random = random_from_trace_id
73
+
74
+ result = if sampled
75
+ random * sample_rate
76
+ elsif sample_rate == 1.0
77
+ random
78
+ else
79
+ sample_rate + random * (1.0 - sample_rate)
80
+ end
81
+
82
+ format_random(result)
83
+ end
84
+
85
+ def format_random(value)
86
+ truncated = (value * PRECISION).floor / PRECISION
87
+ ("%.#{FORMAT_PRECISION}f" % truncated).to_f
88
+ end
89
+
90
+ def parse_value(sample_rand_value)
91
+ Float(sample_rand_value)
92
+ rescue ArgumentError
93
+ nil
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Sentry
6
+ module Utils
7
+ DELIMITER = "-"
8
+
9
+ def self.uuid
10
+ SecureRandom.uuid.delete(DELIMITER)
11
+ end
12
+ end
13
+ end
@@ -3,6 +3,7 @@
3
3
  require "securerandom"
4
4
  require_relative "../profiler/helpers"
5
5
  require_relative "output"
6
+ require "sentry/utils/uuid"
6
7
 
7
8
  module Sentry
8
9
  module Vernier
@@ -12,7 +13,7 @@ module Sentry
12
13
  attr_reader :started, :event_id, :result
13
14
 
14
15
  def initialize(configuration)
15
- @event_id = SecureRandom.uuid.delete("-")
16
+ @event_id = Utils.uuid
16
17
 
17
18
  @started = false
18
19
  @sampled = nil
@@ -103,7 +104,7 @@ module Sentry
103
104
  private
104
105
 
105
106
  def log(message)
106
- Sentry.logger.debug(LOGGER_PROGNAME) { "[Profiler::Vernier] #{message}" }
107
+ Sentry.sdk_logger.debug(LOGGER_PROGNAME) { "[Profiler::Vernier] #{message}" }
107
108
  end
108
109
 
109
110
  def record_lost_event(reason)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.23.0"
4
+ VERSION = "5.27.0"
5
5
  end