sentry-ruby 5.14.0 → 5.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95fd53222ce5360d32645f0bc7577792bdef0a02b9e4b8de27555eabd2ef1844
4
- data.tar.gz: e5eb696315a22747051e5bbdeac314c5ae103cabd59d3fb266b16b0b22345611
3
+ metadata.gz: 76add924de8ccd4132764766cf92d057a7e4ee9554790688e2c2597b569097c2
4
+ data.tar.gz: 856d0936cb2ad123b3ca632e63cb8cf951e13f90755386dcb67b3cc63760ee69
5
5
  SHA512:
6
- metadata.gz: f18df0d05208c0a03352501b4b746f6ccc74799b234198b67b35e709539fde52aa36c56a6297510e8e9e1dc8a62658ac5d81e0023c5935de455effc16ee824fe
7
- data.tar.gz: 47f5db68454ab971d92df8c7fbd95846830edfe09b6b2ea40fef1f5ab39a9db922a5564abe45b29fb55df729bdf53bb1632c566c93b8b7f0d1c96e00c441d0dc
6
+ metadata.gz: 245ee7955da8f38b12db8e2ed18802fbb63a74efd5853968a91fe5e45551f17aa0dd95e8dd07458e1374817b33b3cfc6ab752406fea9f16f55a4027d204d622b
7
+ data.tar.gz: 7fd7cadec651b7464409154ed26eb41852bb2cfbf89bb3f57cecc102058a9b8498bf9f29670ebcd6c25048a1a353878adaadc8a8c1b816baf5b08baf0c380e54
data/Gemfile CHANGED
@@ -12,28 +12,9 @@ gem "redis", "~> #{redis_rb_version}"
12
12
 
13
13
  gem "puma"
14
14
 
15
- gem "rake", "~> 12.0"
16
- gem "rspec", "~> 3.0"
17
- gem "rspec-retry"
18
15
  gem "timecop"
19
- gem "simplecov"
20
- gem "simplecov-cobertura", "~> 1.4"
21
- gem "rexml"
22
16
  gem "stackprof" unless RUBY_PLATFORM == "java"
23
17
 
24
- ruby_version = Gem::Version.new(RUBY_VERSION)
25
-
26
- if ruby_version >= Gem::Version.new("2.6.0")
27
- gem "debug", github: "ruby/debug", platform: :ruby
28
- gem "irb"
29
-
30
- if ruby_version >= Gem::Version.new("3.0.0")
31
- gem "ruby-lsp-rspec"
32
- end
33
- end
34
-
35
- gem "pry"
36
-
37
18
  gem "benchmark-ips"
38
19
  gem "benchmark_driver"
39
20
  gem "benchmark-ipsa"
@@ -41,3 +22,5 @@ gem "benchmark-memory"
41
22
 
42
23
  gem "yard", github: "lsegal/yard"
43
24
  gem "webrick"
25
+
26
+ eval_gemfile File.expand_path("../Gemfile", __dir__)
@@ -13,10 +13,12 @@ module Sentry
13
13
  attr_reader :logger
14
14
  attr_accessor :shutdown_timeout
15
15
 
16
+ DEFAULT_MAX_QUEUE = 30
17
+
16
18
  def initialize(configuration)
17
- @max_queue = 30
18
19
  @shutdown_timeout = 1
19
20
  @number_of_threads = configuration.background_worker_threads
21
+ @max_queue = configuration.background_worker_max_queue
20
22
  @logger = configuration.logger
21
23
  @debug = configuration.debug
22
24
  @shutdown_callback = nil
data/lib/sentry/client.rb CHANGED
@@ -10,6 +10,10 @@ module Sentry
10
10
  # @return [Transport]
11
11
  attr_reader :transport
12
12
 
13
+ # The Transport object that'll send events for the client.
14
+ # @return [SpotlightTransport, nil]
15
+ attr_reader :spotlight_transport
16
+
13
17
  # @!macro configuration
14
18
  attr_reader :configuration
15
19
 
@@ -32,6 +36,8 @@ module Sentry
32
36
  DummyTransport.new(configuration)
33
37
  end
34
38
  end
39
+
40
+ @spotlight_transport = SpotlightTransport.new(configuration) if configuration.spotlight
35
41
  end
36
42
 
37
43
  # Applies the given scope's data to the event and sends it to Sentry.
@@ -167,6 +173,7 @@ module Sentry
167
173
  end
168
174
 
169
175
  transport.send_event(event)
176
+ spotlight_transport&.send_event(event)
170
177
 
171
178
  event
172
179
  rescue => e
@@ -40,6 +40,13 @@ module Sentry
40
40
  # @return [Integer]
41
41
  attr_accessor :background_worker_threads
42
42
 
43
+ # The maximum queue size for the background worker.
44
+ # Jobs will be rejected above this limit.
45
+ #
46
+ # Default is {BackgroundWorker::DEFAULT_MAX_QUEUE}.
47
+ # @return [Integer]
48
+ attr_accessor :background_worker_max_queue
49
+
43
50
  # a proc/lambda that takes an array of stack traces
44
51
  # it'll be used to silence (reduce) backtrace of the exception
45
52
  #
@@ -142,6 +149,14 @@ module Sentry
142
149
  # @return [Boolean]
143
150
  attr_accessor :include_local_variables
144
151
 
152
+ # Whether to capture events and traces into Spotlight. Default is false.
153
+ # If you set this to true, Sentry will send events and traces to the local
154
+ # Sidecar proxy at http://localhost:8969/stream.
155
+ # If you want to use a different Sidecar proxy address, set this to String
156
+ # with the proxy URL.
157
+ # @return [Boolean, String]
158
+ attr_accessor :spotlight
159
+
145
160
  # @deprecated Use {#include_local_variables} instead.
146
161
  alias_method :capture_exception_frame_locals, :include_local_variables
147
162
 
@@ -321,6 +336,7 @@ module Sentry
321
336
  self.app_dirs_pattern = nil
322
337
  self.debug = false
323
338
  self.background_worker_threads = Concurrent.processor_count
339
+ self.background_worker_max_queue = BackgroundWorker::DEFAULT_MAX_QUEUE
324
340
  self.backtrace_cleanup_callback = nil
325
341
  self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
326
342
  self.breadcrumbs_logger = []
@@ -344,6 +360,7 @@ module Sentry
344
360
  self.auto_session_tracking = true
345
361
  self.trusted_proxies = []
346
362
  self.dsn = ENV['SENTRY_DSN']
363
+ self.spotlight = false
347
364
  self.server_name = server_name_from_env
348
365
  self.instrumenter = :sentry
349
366
  self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
@@ -451,7 +468,7 @@ module Sentry
451
468
  def sending_allowed?
452
469
  @errors = []
453
470
 
454
- valid? && capture_in_environment?
471
+ spotlight || (valid? && capture_in_environment?)
455
472
  end
456
473
 
457
474
  def sample_allowed?
@@ -4,7 +4,7 @@ module Sentry
4
4
  MAX_SLUG_LENGTH = 50
5
5
 
6
6
  module Patch
7
- def perform(*args)
7
+ def perform(*args, **opts)
8
8
  slug = self.class.sentry_monitor_slug
9
9
  monitor_config = self.class.sentry_monitor_config
10
10
 
@@ -13,7 +13,8 @@ module Sentry
13
13
  monitor_config: monitor_config)
14
14
 
15
15
  start = Sentry.utc_now.to_i
16
- ret = super
16
+ # need to do this on ruby <= 2.6 sadly
17
+ ret = method(:perform).super_method.arity == 0 ? super() : super
17
18
  duration = Sentry.utc_now.to_i - start
18
19
 
19
20
  Sentry.capture_check_in(slug,
@@ -44,7 +45,7 @@ module Sentry
44
45
  prepend Patch
45
46
  end
46
47
 
47
- def sentry_monitor_slug
48
+ def sentry_monitor_slug(name: self.name)
48
49
  @sentry_monitor_slug ||= begin
49
50
  slug = name.gsub('::', '-').downcase
50
51
  slug[-MAX_SLUG_LENGTH..-1] || slug
@@ -14,11 +14,19 @@ module Sentry
14
14
  RATE_LIMIT_HEADER = "x-sentry-rate-limits"
15
15
  USER_AGENT = "sentry-ruby/#{Sentry::VERSION}"
16
16
 
17
+ # The list of errors ::Net::HTTP is known to raise
18
+ # See https://github.com/ruby/ruby/blob/b0c639f249165d759596f9579fa985cb30533de6/lib/bundler/fetcher.rb#L281-L286
19
+ HTTP_ERRORS = [
20
+ Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
21
+ Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
22
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
23
+ Zlib::BufError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
24
+ ].freeze
25
+
26
+
17
27
  def initialize(*args)
18
28
  super
19
- @endpoint = @dsn.envelope_endpoint
20
-
21
- log_debug("Sentry HTTP Transport will connect to #{@dsn.server}")
29
+ log_debug("Sentry HTTP Transport will connect to #{@dsn.server}") if @dsn
22
30
  end
23
31
 
24
32
  def send_data(data)
@@ -32,12 +40,14 @@ module Sentry
32
40
  headers = {
33
41
  'Content-Type' => CONTENT_TYPE,
34
42
  'Content-Encoding' => encoding,
35
- 'X-Sentry-Auth' => generate_auth_header,
36
43
  'User-Agent' => USER_AGENT
37
44
  }
38
45
 
46
+ auth_header = generate_auth_header
47
+ headers['X-Sentry-Auth'] = auth_header if auth_header
48
+
39
49
  response = conn.start do |http|
40
- request = ::Net::HTTP::Post.new(@endpoint, headers)
50
+ request = ::Net::HTTP::Post.new(endpoint, headers)
41
51
  request.body = data
42
52
  http.request(request)
43
53
  end
@@ -58,8 +68,52 @@ module Sentry
58
68
 
59
69
  raise Sentry::ExternalError, error_info
60
70
  end
61
- rescue SocketError => e
62
- raise Sentry::ExternalError.new(e.message)
71
+ rescue SocketError, *HTTP_ERRORS => e
72
+ on_error if respond_to?(:on_error)
73
+ raise Sentry::ExternalError.new(e&.message)
74
+ end
75
+
76
+ def endpoint
77
+ @dsn.envelope_endpoint
78
+ end
79
+
80
+ def generate_auth_header
81
+ return nil unless @dsn
82
+
83
+ now = Sentry.utc_now.to_i
84
+ fields = {
85
+ 'sentry_version' => PROTOCOL_VERSION,
86
+ 'sentry_client' => USER_AGENT,
87
+ 'sentry_timestamp' => now,
88
+ 'sentry_key' => @dsn.public_key
89
+ }
90
+ fields['sentry_secret'] = @dsn.secret_key if @dsn.secret_key
91
+ 'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
92
+ end
93
+
94
+ def conn
95
+ server = URI(@dsn.server)
96
+
97
+ # connection respects proxy setting from @transport_configuration, or environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY)
98
+ # Net::HTTP will automatically read the env vars.
99
+ # See https://ruby-doc.org/3.2.2/stdlibs/net/Net/HTTP.html#class-Net::HTTP-label-Proxies
100
+ connection =
101
+ if proxy = normalize_proxy(@transport_configuration.proxy)
102
+ ::Net::HTTP.new(server.hostname, server.port, proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
103
+ else
104
+ ::Net::HTTP.new(server.hostname, server.port)
105
+ end
106
+
107
+ connection.use_ssl = server.scheme == "https"
108
+ connection.read_timeout = @transport_configuration.timeout
109
+ connection.write_timeout = @transport_configuration.timeout if connection.respond_to?(:write_timeout)
110
+ connection.open_timeout = @transport_configuration.open_timeout
111
+
112
+ ssl_configuration.each do |key, value|
113
+ connection.send("#{key}=", value)
114
+ end
115
+
116
+ connection
63
117
  end
64
118
 
65
119
  private
@@ -126,31 +180,6 @@ module Sentry
126
180
  @transport_configuration.encoding == GZIP_ENCODING && data.bytesize >= GZIP_THRESHOLD
127
181
  end
128
182
 
129
- def conn
130
- server = URI(@dsn.server)
131
-
132
- # connection respects proxy setting from @transport_configuration, or environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY)
133
- # Net::HTTP will automatically read the env vars.
134
- # See https://ruby-doc.org/3.2.2/stdlibs/net/Net/HTTP.html#class-Net::HTTP-label-Proxies
135
- connection =
136
- if proxy = normalize_proxy(@transport_configuration.proxy)
137
- ::Net::HTTP.new(server.hostname, server.port, proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
138
- else
139
- ::Net::HTTP.new(server.hostname, server.port)
140
- end
141
-
142
- connection.use_ssl = server.scheme == "https"
143
- connection.read_timeout = @transport_configuration.timeout
144
- connection.write_timeout = @transport_configuration.timeout if connection.respond_to?(:write_timeout)
145
- connection.open_timeout = @transport_configuration.open_timeout
146
-
147
- ssl_configuration.each do |key, value|
148
- connection.send("#{key}=", value)
149
- end
150
-
151
- connection
152
- end
153
-
154
183
  # @param proxy [String, URI, Hash] Proxy config value passed into `config.transport`.
155
184
  # Accepts either a URI formatted string, URI, or a hash with the `uri`, `user`, and `password` keys.
156
185
  # @return [Hash] Normalized proxy config that will be passed into `Net::HTTP`
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "zlib"
5
+
6
+ module Sentry
7
+ # Designed to just report events to Spotlight in development.
8
+ class SpotlightTransport < HTTPTransport
9
+ DEFAULT_SIDECAR_URL = "http://localhost:8969/stream"
10
+ MAX_FAILED_REQUESTS = 3
11
+
12
+ def initialize(configuration)
13
+ super
14
+ @sidecar_url = configuration.spotlight.is_a?(String) ? configuration.spotlight : DEFAULT_SIDECAR_URL
15
+ @failed = 0
16
+ @logged = false
17
+
18
+ log_debug("[Spotlight] initialized for url #{@sidecar_url}")
19
+ end
20
+
21
+ def endpoint
22
+ "/stream"
23
+ end
24
+
25
+ def send_data(data)
26
+ if @failed >= MAX_FAILED_REQUESTS
27
+ unless @logged
28
+ log_debug("[Spotlight] disabling because of too many request failures")
29
+ @logged = true
30
+ end
31
+
32
+ return
33
+ end
34
+
35
+ super
36
+ end
37
+
38
+ def on_error
39
+ @failed += 1
40
+ end
41
+
42
+ # Similar to HTTPTransport connection, but does not support Proxy and SSL
43
+ def conn
44
+ sidecar = URI(@sidecar_url)
45
+ connection = ::Net::HTTP.new(sidecar.hostname, sidecar.port, nil)
46
+ connection.use_ssl = false
47
+ connection
48
+ end
49
+ end
50
+ end
@@ -119,18 +119,6 @@ module Sentry
119
119
  !!delay && delay > Time.now
120
120
  end
121
121
 
122
- def generate_auth_header
123
- now = Sentry.utc_now.to_i
124
- fields = {
125
- 'sentry_version' => PROTOCOL_VERSION,
126
- 'sentry_client' => USER_AGENT,
127
- 'sentry_timestamp' => now,
128
- 'sentry_key' => @dsn.public_key
129
- }
130
- fields['sentry_secret'] = @dsn.secret_key if @dsn.secret_key
131
- 'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
132
- end
133
-
134
122
  def envelope_from_event(event)
135
123
  # Convert to hash
136
124
  event_payload = event.to_hash
@@ -220,3 +208,4 @@ end
220
208
 
221
209
  require "sentry/transport/dummy_transport"
222
210
  require "sentry/transport/http_transport"
211
+ require "sentry/transport/spotlight_transport"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.14.0"
4
+ VERSION = "5.15.1"
5
5
  end
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.14.0
4
+ version: 5.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-27 00:00:00.000000000 Z
11
+ date: 2023-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -100,6 +100,7 @@ files:
100
100
  - lib/sentry/transport/configuration.rb
101
101
  - lib/sentry/transport/dummy_transport.rb
102
102
  - lib/sentry/transport/http_transport.rb
103
+ - lib/sentry/transport/spotlight_transport.rb
103
104
  - lib/sentry/utils/argument_checking_helper.rb
104
105
  - lib/sentry/utils/custom_inspection.rb
105
106
  - lib/sentry/utils/encoding_helper.rb