sentry-ruby 5.14.0 → 5.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95fd53222ce5360d32645f0bc7577792bdef0a02b9e4b8de27555eabd2ef1844
4
- data.tar.gz: e5eb696315a22747051e5bbdeac314c5ae103cabd59d3fb266b16b0b22345611
3
+ metadata.gz: 8ad04d5359f4cc44d2a2e398d1083b72f11c96efabc4a3b2148327261e327a20
4
+ data.tar.gz: 2800581dce649c81f5a17464f3b5619158900d8c5eb23e35347507dddb594b04
5
5
  SHA512:
6
- metadata.gz: f18df0d05208c0a03352501b4b746f6ccc74799b234198b67b35e709539fde52aa36c56a6297510e8e9e1dc8a62658ac5d81e0023c5935de455effc16ee824fe
7
- data.tar.gz: 47f5db68454ab971d92df8c7fbd95846830edfe09b6b2ea40fef1f5ab39a9db922a5564abe45b29fb55df729bdf53bb1632c566c93b8b7f0d1c96e00c441d0dc
6
+ metadata.gz: d8bce6cfd5f48acb743b6018e5d34e4832de9eb05e68a0c114fd90bb13e8c80fcf6da97cb8e80a64d78e930b3ee6b8ee22711c2efa2e018f43b33d0ff09cf68b
7
+ data.tar.gz: 1f9749bf1ccee5a541c4949dbf2b0f79da9508f6a86aa3d603811b252a49f4ca3054e91dfa7a0e93dac723965e8e316f56c8433ddf796c7d8f38069075b80268
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
@@ -142,6 +142,14 @@ module Sentry
142
142
  # @return [Boolean]
143
143
  attr_accessor :include_local_variables
144
144
 
145
+ # Whether to capture events and traces into Spotlight. Default is false.
146
+ # If you set this to true, Sentry will send events and traces to the local
147
+ # Sidecar proxy at http://localhost:8969/stream.
148
+ # If you want to use a different Sidecar proxy address, set this to String
149
+ # with the proxy URL.
150
+ # @return [Boolean, String]
151
+ attr_accessor :spotlight
152
+
145
153
  # @deprecated Use {#include_local_variables} instead.
146
154
  alias_method :capture_exception_frame_locals, :include_local_variables
147
155
 
@@ -344,6 +352,7 @@ module Sentry
344
352
  self.auto_session_tracking = true
345
353
  self.trusted_proxies = []
346
354
  self.dsn = ENV['SENTRY_DSN']
355
+ self.spotlight = false
347
356
  self.server_name = server_name_from_env
348
357
  self.instrumenter = :sentry
349
358
  self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
@@ -451,7 +460,7 @@ module Sentry
451
460
  def sending_allowed?
452
461
  @errors = []
453
462
 
454
- valid? && capture_in_environment?
463
+ spotlight || (valid? && capture_in_environment?)
455
464
  end
456
465
 
457
466
  def sample_allowed?
@@ -44,7 +44,7 @@ module Sentry
44
44
  prepend Patch
45
45
  end
46
46
 
47
- def sentry_monitor_slug
47
+ def sentry_monitor_slug(name: self.name)
48
48
  @sentry_monitor_slug ||= begin
49
49
  slug = name.gsub('::', '-').downcase
50
50
  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.0"
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.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: 2023-11-27 00:00:00.000000000 Z
11
+ date: 2023-12-05 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