sentry-ruby 5.22.4 → 5.26.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ccdc435e6c9cc7602051e6ae33794509604f6a6973e8098acb3b39cdaa727056
4
- data.tar.gz: 7963e284f23ac79656f94eccbed48840be1746927bcae3ae18a66c60aea923c5
3
+ metadata.gz: eb03eb536d1060c3a097a1ff3726ae71c8ffbd0012580d75c491665e054ac7c1
4
+ data.tar.gz: 65df577369b281f3e1d1d9335e78786a800947c2014b35608d88c863458f24ca
5
5
  SHA512:
6
- metadata.gz: da82afec03f9100f4d1389ac96069328a61f658b3ebf39b982aa8eb1284fbc19bd00168d4d89b3b4e8b0a0d82b98e161a4d38f4e5afbc88bdbbcfa3b7aadd958
7
- data.tar.gz: 1711020af1887f806b3cc01a9e1d2540b616e5f3e5d77da85cb252e85ae90af9062de51eb9e552a434595345d0978a10b6002cd2944e0baaf4414275e58fd399
6
+ metadata.gz: b4e398e02a8fe619afc8982760c290a168785c4557dca30767fbeb039032d7907135e84d0598a5ac90b7b1cfb8413ceda83ebe4647702ba5c10c613ff0543574
7
+ data.tar.gz: 285a3e0f650a41bcb6cc4539f48c7efcb9bc3442f31c76f301089c4672e6d9c790f407dd9d53db4e216df4eacd9be019b5bc46e453437fa1614aa48555541c9a
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
- --format documentation
1
+ --require spec_helper
2
+ --format progress
2
3
  --color
4
+ --order rand
data/Gemfile CHANGED
@@ -3,6 +3,8 @@
3
3
  source "https://rubygems.org"
4
4
  git_source(:github) { |name| "https://github.com/#{name}.git" }
5
5
 
6
+ eval_gemfile "../Gemfile"
7
+
6
8
  gem "sentry-ruby", path: "./"
7
9
 
8
10
  rack_version = ENV["RACK_VERSION"]
@@ -27,9 +29,8 @@ gem "benchmark_driver"
27
29
  gem "benchmark-ipsa"
28
30
  gem "benchmark-memory"
29
31
 
30
- gem "yard", github: "lsegal/yard"
32
+ gem "yard"
31
33
  gem "webrick"
32
34
  gem "faraday"
33
35
  gem "excon"
34
-
35
- eval_gemfile File.expand_path("../Gemfile", __dir__)
36
+ gem "webmock"
data/README.md CHANGED
@@ -15,12 +15,12 @@ Sentry SDK for Ruby
15
15
 
16
16
  | Current version | Build | Coverage | API doc |
17
17
  | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
18
- | [![Gem Version](https://img.shields.io/gem/v/sentry-ruby?label=sentry-ruby)](https://rubygems.org/gems/sentry-ruby) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-ruby) |
19
- | [![Gem Version](https://img.shields.io/gem/v/sentry-rails?label=sentry-rails)](https://rubygems.org/gems/sentry-rails) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-rails) |
20
- | [![Gem Version](https://img.shields.io/gem/v/sentry-sidekiq?label=sentry-sidekiq)](https://rubygems.org/gems/sentry-sidekiq) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-sidekiq) |
21
- | [![Gem Version](https://img.shields.io/gem/v/sentry-delayed_job?label=sentry-delayed_job)](https://rubygems.org/gems/sentry-delayed_job) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-delayed_job) |
22
- | [![Gem Version](https://img.shields.io/gem/v/sentry-resque?label=sentry-resque)](https://rubygems.org/gems/sentry-resque) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-resque) |
23
- | [![Gem Version](https://img.shields.io/gem/v/sentry-opentelemetry?label=sentry-opentelemetry)](https://rubygems.org/gems/sentry-opentelemetry) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml) | [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-opentelemetry) |
18
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-ruby?label=sentry-ruby)](https://rubygems.org/gems/sentry-ruby) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-ruby)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-ruby) |
19
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-rails?label=sentry-rails)](https://rubygems.org/gems/sentry-rails) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-rails)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-rails) |
20
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-sidekiq?label=sentry-sidekiq)](https://rubygems.org/gems/sentry-sidekiq) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-sidekiq)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-sidekiq) |
21
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-delayed_job?label=sentry-delayed_job)](https://rubygems.org/gems/sentry-delayed_job) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-delayed_job)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-delayed_job) |
22
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-resque?label=sentry-resque)](https://rubygems.org/gems/sentry-resque) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-resque)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-resque) |
23
+ | [![Gem Version](https://img.shields.io/gem/v/sentry-opentelemetry?label=sentry-opentelemetry)](https://rubygems.org/gems/sentry-opentelemetry) | [![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [![codecov](https://codecov.io/gh/getsentry/sentry-ruby/graph/badge.svg?token=ZePzrpZFP6&component=sentry-opentelemetry)](https://codecov.io/gh/getsentry/sentry-ruby) | [![API doc](https://img.shields.io/badge/API%20doc-rubydoc.info-blue)](https://www.rubydoc.info/gems/sentry-opentelemetry) |
24
24
 
25
25
 
26
26
 
@@ -59,6 +59,8 @@ gem "sentry-opentelemetry"
59
59
 
60
60
  You need to use Sentry.init to initialize and configure your SDK:
61
61
  ```ruby
62
+ require "sentry-ruby"
63
+
62
64
  Sentry.init do |config|
63
65
  config.dsn = "MY_DSN"
64
66
  end
@@ -116,3 +118,6 @@ Thanks to everyone who has contributed to this project so far.
116
118
  <a href="https://github.com/getsentry/sentry-ruby/graphs/contributors">
117
119
  <img src="https://contributors-img.web.app/image?repo=getsentry/sentry-ruby" />
118
120
  </a>
121
+
122
+ > [!WARNING]
123
+ > Example and sample code in sentry-rails/examples and sentry-rails/spec/dummy is unmaintained. Sample code may contain security vulnerabilities, should never be used in production, and exists only for illustrative purposes.
data/Rakefile CHANGED
@@ -6,17 +6,13 @@ CLOBBER.include "pkg"
6
6
  require "bundler/gem_helper"
7
7
  Bundler::GemHelper.install_tasks(name: "sentry-ruby")
8
8
 
9
- require "rspec/core/rake_task"
9
+ require_relative "../lib/sentry/test/rake_tasks"
10
10
 
11
- RSpec::Core::RakeTask.new(:spec).tap do |task|
12
- task.rspec_opts = "--order rand"
13
- task.exclude_pattern = "spec/isolated/**/*_spec.rb"
14
- end
11
+ ISOLATED_SPECS = "spec/isolated/**/*_spec.rb"
15
12
 
16
- task :isolated_specs do
17
- Dir["spec/isolated/*"].each do |file|
18
- sh "bundle exec rspec #{file}"
19
- end
20
- end
13
+ Sentry::Test::RakeTasks.define_spec_tasks(
14
+ isolated_specs_pattern: ISOLATED_SPECS,
15
+ spec_exclude_pattern: ISOLATED_SPECS
16
+ )
21
17
 
22
- task default: [:spec, :isolated_specs]
18
+ task default: [:spec, :"spec:isolated"]
@@ -9,8 +9,7 @@ module Sentry
9
9
  include LoggingHelper
10
10
 
11
11
  attr_reader :max_queue, :number_of_threads
12
- # @deprecated Use Sentry.logger to retrieve the current logger instead.
13
- attr_reader :logger
12
+
14
13
  attr_accessor :shutdown_timeout
15
14
 
16
15
  DEFAULT_MAX_QUEUE = 30
@@ -19,7 +18,7 @@ module Sentry
19
18
  @shutdown_timeout = 1
20
19
  @number_of_threads = configuration.background_worker_threads
21
20
  @max_queue = configuration.background_worker_max_queue
22
- @logger = configuration.logger
21
+ @sdk_logger = configuration.sdk_logger
23
22
  @debug = configuration.debug
24
23
  @shutdown_callback = nil
25
24
 
@@ -6,7 +6,7 @@ module Sentry
6
6
  MAX_DOWNSAMPLE_FACTOR = 10
7
7
 
8
8
  def initialize(configuration, client, interval: DEFAULT_INTERVAL)
9
- super(configuration.logger, interval)
9
+ super(configuration.sdk_logger, interval)
10
10
  @client = client
11
11
 
12
12
  @healthy = true
@@ -16,7 +16,7 @@ module Sentry
16
16
  /x
17
17
 
18
18
  # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
19
- JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
19
+ JAVA_INPUT_FORMAT = /^([\w$.]+)\.([\w$]+)\(([\w$.]+):(\d+)\)$/
20
20
 
21
21
  # The file portion of the line (such as app/models/user.rb)
22
22
  attr_reader :file
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Sentry
4
4
  class Breadcrumb
5
+ MAX_NESTING = 10
5
6
  DATA_SERIALIZATION_ERROR_MESSAGE = "[data were removed due to serialization issues]"
6
7
 
7
8
  # @return [String, nil]
@@ -47,7 +48,7 @@ module Sentry
47
48
  # @param message [String]
48
49
  # @return [void]
49
50
  def message=(message)
50
- @message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
51
+ @message = message && Utils::EncodingHelper.valid_utf_8?(message) ? message.byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES) : ""
51
52
  end
52
53
 
53
54
  # @param level [String]
@@ -60,16 +61,16 @@ module Sentry
60
61
 
61
62
  def serialized_data
62
63
  begin
63
- ::JSON.parse(::JSON.generate(@data))
64
+ ::JSON.parse(::JSON.generate(@data, max_nesting: MAX_NESTING))
64
65
  rescue Exception => e
65
- Sentry.logger.debug(LOGGER_PROGNAME) do
66
+ Sentry.sdk_logger.debug(LOGGER_PROGNAME) do
66
67
  <<~MSG
67
68
  can't serialize breadcrumb data because of error: #{e}
68
69
  data: #{@data}
69
70
  MSG
70
71
  end
71
72
 
72
- DATA_SERIALIZATION_ERROR_MESSAGE
73
+ { error: DATA_SERIALIZATION_ERROR_MESSAGE }
73
74
  end
74
75
  end
75
76
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "securerandom"
4
4
  require "sentry/cron/monitor_config"
5
+ require "sentry/utils/uuid"
5
6
 
6
7
  module Sentry
7
8
  class CheckInEvent < Event
@@ -43,7 +44,7 @@ module Sentry
43
44
  self.status = status
44
45
  self.duration = duration
45
46
  self.monitor_config = monitor_config
46
- self.check_in_id = check_in_id || SecureRandom.uuid.delete("-")
47
+ self.check_in_id = check_in_id || Utils.uuid
47
48
  end
48
49
 
49
50
  # @return [Hash]
data/lib/sentry/client.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sentry/transport"
4
+ require "sentry/log_event"
5
+ require "sentry/log_event_buffer"
6
+ require "sentry/utils/uuid"
4
7
 
5
8
  module Sentry
6
9
  class Client
@@ -14,16 +17,16 @@ module Sentry
14
17
  # @return [SpotlightTransport, nil]
15
18
  attr_reader :spotlight_transport
16
19
 
20
+ # @!visibility private
21
+ attr_reader :log_event_buffer
22
+
17
23
  # @!macro configuration
18
24
  attr_reader :configuration
19
25
 
20
- # @deprecated Use Sentry.logger to retrieve the current logger instead.
21
- attr_reader :logger
22
-
23
26
  # @param configuration [Configuration]
24
27
  def initialize(configuration)
25
28
  @configuration = configuration
26
- @logger = configuration.logger
29
+ @sdk_logger = configuration.sdk_logger
27
30
 
28
31
  if transport_class = configuration.transport.transport_class
29
32
  @transport = transport_class.new(configuration)
@@ -38,6 +41,10 @@ module Sentry
38
41
  end
39
42
 
40
43
  @spotlight_transport = SpotlightTransport.new(configuration) if configuration.spotlight
44
+
45
+ if configuration.enable_logs
46
+ @log_event_buffer = LogEventBuffer.new(configuration, self).start
47
+ end
41
48
  end
42
49
 
43
50
  # Applies the given scope's data to the event and sends it to Sentry.
@@ -88,6 +95,15 @@ module Sentry
88
95
  nil
89
96
  end
90
97
 
98
+ # Buffer a log event to be sent later with other logs in a single envelope
99
+ # @param event [LogEvent] the log event to be buffered
100
+ # @return [LogEvent]
101
+ def buffer_log_event(event, scope)
102
+ return unless event.is_a?(LogEvent)
103
+ @log_event_buffer.add_event(scope.apply_to_event(event))
104
+ event
105
+ end
106
+
91
107
  # Capture an envelope directly.
92
108
  # @param envelope [Envelope] the envelope to be captured.
93
109
  # @return [void]
@@ -100,6 +116,7 @@ module Sentry
100
116
  def flush
101
117
  transport.flush if configuration.sending_to_dsn_allowed?
102
118
  spotlight_transport.flush if spotlight_transport
119
+ @log_event_buffer&.flush
103
120
  end
104
121
 
105
122
  # Initializes an Event object with the given exception. Returns `nil` if the exception's class is excluded from reporting.
@@ -167,6 +184,22 @@ module Sentry
167
184
  )
168
185
  end
169
186
 
187
+ # Initializes a LogEvent object with the given message and options
188
+ #
189
+ # @param message [String] the log message
190
+ # @param level [Symbol] the log level (:trace, :debug, :info, :warn, :error, :fatal)
191
+ # @param options [Hash] additional options
192
+ # @option options [Array] :parameters Array of values to replace template tokens in the message
193
+ #
194
+ # @return [LogEvent] the created log event
195
+ def event_from_log(message, level:, **options)
196
+ return unless configuration.sending_allowed?
197
+
198
+ attributes = options.reject { |k, _| k == :level || k == :severity }
199
+
200
+ LogEvent.new(level: level, body: message, attributes: attributes)
201
+ end
202
+
170
203
  # Initializes an Event object with the given Transaction object.
171
204
  # @param transaction [Transaction] the transaction to be recorded.
172
205
  # @return [TransactionEvent]
@@ -237,6 +270,53 @@ module Sentry
237
270
  raise
238
271
  end
239
272
 
273
+ # Send an envelope with batched logs
274
+ # @param log_events [Array<LogEvent>] the log events to be sent
275
+ # @api private
276
+ # @return [void]
277
+ def send_logs(log_events)
278
+ envelope = Envelope.new(
279
+ event_id: Sentry::Utils.uuid,
280
+ sent_at: Sentry.utc_now.iso8601,
281
+ dsn: configuration.dsn,
282
+ sdk: Sentry.sdk_meta
283
+ )
284
+
285
+ discarded_count = 0
286
+ envelope_items = []
287
+
288
+ if configuration.before_send_log
289
+ log_events.each do |log_event|
290
+ processed_log_event = configuration.before_send_log.call(log_event)
291
+
292
+ if processed_log_event
293
+ envelope_items << processed_log_event.to_hash
294
+ else
295
+ discarded_count += 1
296
+ end
297
+ end
298
+
299
+ envelope_items
300
+ else
301
+ envelope_items = log_events.map(&:to_hash)
302
+ end
303
+
304
+ envelope.add_item(
305
+ {
306
+ type: "log",
307
+ item_count: envelope_items.size,
308
+ content_type: "application/vnd.sentry.items.log+json"
309
+ },
310
+ { items: envelope_items }
311
+ )
312
+
313
+ send_envelope(envelope)
314
+
315
+ unless discarded_count.zero?
316
+ transport.record_lost_event(:before_send, "log_item", num: discarded_count)
317
+ end
318
+ end
319
+
240
320
  # Send an envelope directly to Sentry.
241
321
  # @param envelope [Envelope] the envelope to be sent.
242
322
  # @return [void]
@@ -12,6 +12,8 @@ require "sentry/cron/configuration"
12
12
  require "sentry/metrics/configuration"
13
13
  require "sentry/linecache"
14
14
  require "sentry/interfaces/stacktrace_builder"
15
+ require "sentry/logger"
16
+ require "sentry/log_event_buffer"
15
17
 
16
18
  module Sentry
17
19
  class Configuration
@@ -99,6 +101,15 @@ module Sentry
99
101
  # @return [Proc]
100
102
  attr_reader :before_send_transaction
101
103
 
104
+ # Optional Proc, called before sending an event to the server
105
+ # @example
106
+ # config.before_send_log = lambda do |log|
107
+ # log.attributes["sentry"] = true
108
+ # log
109
+ # end
110
+ # @return [Proc]
111
+ attr_accessor :before_send_log
112
+
102
113
  # An array of breadcrumbs loggers to be used. Available options are:
103
114
  # - :sentry_logger
104
115
  # - :http_logger
@@ -183,7 +194,19 @@ module Sentry
183
194
  # Logger used by Sentry. In Rails, this is the Rails logger, otherwise
184
195
  # Sentry provides its own Sentry::Logger.
185
196
  # @return [Logger]
186
- attr_accessor :logger
197
+ attr_accessor :sdk_logger
198
+
199
+ # @deprecated Use {#sdk_logger=} instead.
200
+ def logger=(logger)
201
+ warn "[sentry] `config.logger=` is deprecated. Please use `config.sdk_logger=` instead."
202
+ self.sdk_logger = logger
203
+ end
204
+
205
+ # @deprecated Use {#sdk_logger} instead.
206
+ def logger
207
+ warn "[sentry] `config.logger` is deprecated. Please use `config.sdk_logger` instead."
208
+ self.sdk_logger
209
+ end
187
210
 
188
211
  # Project directory root for in_app detection. Could be Rails root, etc.
189
212
  # Set automatically for Rails.
@@ -262,8 +285,13 @@ module Sentry
262
285
  # @return [Proc]
263
286
  attr_accessor :traces_sampler
264
287
 
288
+ # Enable Structured Logging
289
+ # @return [Boolean]
290
+ attr_accessor :enable_logs
291
+
265
292
  # Easier way to use performance tracing
266
293
  # If set to true, will set traces_sample_rate to 1.0
294
+ # @deprecated It will be removed in the next major release.
267
295
  # @return [Boolean, nil]
268
296
  attr_reader :enable_tracing
269
297
 
@@ -306,6 +334,10 @@ module Sentry
306
334
  # @return [Array<Symbol>]
307
335
  attr_accessor :enabled_patches
308
336
 
337
+ # Maximum number of log events to buffer before sending
338
+ # @return [Integer]
339
+ attr_accessor :max_log_events
340
+
309
341
  # these are not config options
310
342
  # @!visibility private
311
343
  attr_reader :errors, :gem_specs
@@ -418,7 +450,7 @@ module Sentry
418
450
  self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
419
451
  self.inspect_exception_causes_for_exclusion = true
420
452
  self.linecache = ::Sentry::LineCache.new
421
- self.logger = ::Sentry::Logger.new(STDOUT)
453
+ self.sdk_logger = ::Sentry::Logger.new(STDOUT)
422
454
  self.project_root = Dir.pwd
423
455
  self.propagate_traces = true
424
456
 
@@ -442,9 +474,11 @@ module Sentry
442
474
 
443
475
  self.before_send = nil
444
476
  self.before_send_transaction = nil
477
+ self.before_send_log = nil
445
478
  self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
446
479
  self.traces_sampler = nil
447
480
  self.enable_tracing = nil
481
+ self.enable_logs = false
448
482
 
449
483
  self.profiler_class = Sentry::Profiler
450
484
 
@@ -454,6 +488,8 @@ module Sentry
454
488
  @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
455
489
 
456
490
  run_post_initialization_callbacks
491
+
492
+ self.max_log_events = LogEventBuffer::DEFAULT_MAX_EVENTS
457
493
  end
458
494
 
459
495
  def validate
@@ -542,6 +578,12 @@ module Sentry
542
578
  end
543
579
 
544
580
  def enable_tracing=(enable_tracing)
581
+ unless enable_tracing.nil?
582
+ log_warn <<~MSG
583
+ `enable_tracing` is now deprecated in favor of `traces_sample_rate = 1.0`.
584
+ MSG
585
+ end
586
+
545
587
  @enable_tracing = enable_tracing
546
588
  @traces_sample_rate ||= 1.0 if enable_tracing
547
589
  end
@@ -15,7 +15,7 @@ module Sentry
15
15
  # rate limits and client reports use the data_category rather than envelope item type
16
16
  def self.data_category(type)
17
17
  case type
18
- when "session", "attachment", "transaction", "profile", "span" then type
18
+ when "session", "attachment", "transaction", "profile", "span", "log" then type
19
19
  when "sessions" then "session"
20
20
  when "check_in" then "monitor"
21
21
  when "statsd", "metric_meta" then "metric_bucket"
data/lib/sentry/event.rb CHANGED
@@ -7,6 +7,7 @@ require "sentry/backtrace"
7
7
  require "sentry/utils/real_ip"
8
8
  require "sentry/utils/request_id"
9
9
  require "sentry/utils/custom_inspection"
10
+ require "sentry/utils/uuid"
10
11
 
11
12
  module Sentry
12
13
  # This is an abstract class that defines the shared attributes of an event.
@@ -50,7 +51,7 @@ module Sentry
50
51
  # @param message [String, nil]
51
52
  def initialize(configuration:, integration_meta: nil, message: nil)
52
53
  # Set some simple default values
53
- @event_id = SecureRandom.uuid.delete("-")
54
+ @event_id = Utils.uuid
54
55
  @timestamp = Sentry.utc_now.iso8601
55
56
  @platform = :ruby
56
57
  @type = self.class::TYPE
data/lib/sentry/hub.rb CHANGED
@@ -8,12 +8,42 @@ module Sentry
8
8
  class Hub
9
9
  include ArgumentCheckingHelper
10
10
 
11
+ MUTEX = Mutex.new
12
+
11
13
  attr_reader :last_event_id
12
14
 
15
+ attr_reader :current_profiler
16
+
13
17
  def initialize(client, scope)
14
18
  first_layer = Layer.new(client, scope)
15
19
  @stack = [first_layer]
16
20
  @last_event_id = nil
21
+ @current_profiler = {}
22
+ end
23
+
24
+ # This is an internal private method
25
+ # @api private
26
+ def start_profiler!(transaction)
27
+ MUTEX.synchronize do
28
+ transaction.start_profiler!
29
+ @current_profiler[transaction.__id__] = transaction.profiler
30
+ end
31
+ end
32
+
33
+ # This is an internal private method
34
+ # @api private
35
+ def stop_profiler!(transaction)
36
+ MUTEX.synchronize do
37
+ @current_profiler.delete(transaction.__id__)&.stop
38
+ end
39
+ end
40
+
41
+ # This is an internal private method
42
+ # @api private
43
+ def profiler_running?
44
+ MUTEX.synchronize do
45
+ !@current_profiler.empty?
46
+ end
17
47
  end
18
48
 
19
49
  def new_from_top
@@ -96,7 +126,7 @@ module Sentry
96
126
  sampling_context.merge!(custom_sampling_context)
97
127
  transaction.set_initial_sample_decision(sampling_context: sampling_context)
98
128
 
99
- transaction.start_profiler!
129
+ start_profiler!(transaction)
100
130
 
101
131
  transaction
102
132
  end
@@ -186,6 +216,16 @@ module Sentry
186
216
  event.check_in_id
187
217
  end
188
218
 
219
+ def capture_log_event(message, **options)
220
+ return unless current_client
221
+
222
+ event = current_client.event_from_log(message, **options)
223
+
224
+ return unless event
225
+
226
+ current_client.buffer_log_event(event, current_scope)
227
+ end
228
+
189
229
  def capture_event(event, **options, &block)
190
230
  check_argument_type!(event, Sentry::Event)
191
231
 
@@ -99,7 +99,7 @@ module Sentry
99
99
  # Rails adds objects to the Rack env that can sometimes raise exceptions
100
100
  # when `to_s` is called.
101
101
  # See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134
102
- Sentry.logger.warn(LOGGER_PROGNAME) { "Error raised while formatting headers: #{e.message}" }
102
+ Sentry.sdk_logger.warn(LOGGER_PROGNAME) { "Error raised while formatting headers: #{e.message}" }
103
103
  next
104
104
  end
105
105
  end
@@ -29,9 +29,9 @@ module Sentry
29
29
 
30
30
  def getlines(path)
31
31
  @cache[path] ||= begin
32
- IO.readlines(path)
33
- rescue
34
- nil
32
+ File.open(path, "r", &:readlines)
33
+ rescue
34
+ nil
35
35
  end
36
36
  end
37
37