sentry-ruby 5.12.0 → 5.14.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: 857c6d99b1c5d9378a2522ffa1e466f91869500ae425f9d1add4aae399f1852c
4
- data.tar.gz: 726793c0ae09ce3b137cdc7f48f6745c55176a83c8f651b8b493ee5d1290b522
3
+ metadata.gz: 95fd53222ce5360d32645f0bc7577792bdef0a02b9e4b8de27555eabd2ef1844
4
+ data.tar.gz: e5eb696315a22747051e5bbdeac314c5ae103cabd59d3fb266b16b0b22345611
5
5
  SHA512:
6
- metadata.gz: 13ccb78050835c829d738550bc9838347c71abc2139089c29ab466796059259740207d21504bee7cc6f4ca07dbcc982e12be05ebc0b955a4274a4a30bd0470ee
7
- data.tar.gz: d6b4edd6c562b787b9fe652b6ba6ddb3bf16bca937bacbd22fcc44be746643a77e3595460263f72e3e76e73a7b92ff09577d7c665cfac2520886c3a62a62a2ab
6
+ metadata.gz: f18df0d05208c0a03352501b4b746f6ccc74799b234198b67b35e709539fde52aa36c56a6297510e8e9e1dc8a62658ac5d81e0023c5935de455effc16ee824fe
7
+ data.tar.gz: 47f5db68454ab971d92df8c7fbd95846830edfe09b6b2ea40fef1f5ab39a9db922a5564abe45b29fb55df729bdf53bb1632c566c93b8b7f0d1c96e00c441d0dc
data/README.md CHANGED
@@ -33,7 +33,7 @@ If you're using `sentry-raven`, we recommend you to migrate to this new SDK. You
33
33
 
34
34
  ## Requirements
35
35
 
36
- We test on Ruby 2.4, 2.5, 2.6, 2.7, 3.0, and 3.1 at the latest patchlevel/teeny version. We also support JRuby 9.0.
36
+ We test from Ruby 2.4 to Ruby 3.2 at the latest patchlevel/teeny version. We also support JRuby 9.0.
37
37
 
38
38
  If you use self-hosted Sentry, please also make sure its version is above `20.6.0`.
39
39
 
@@ -9,7 +9,7 @@ module Sentry
9
9
  # @return [Hash, nil]
10
10
  attr_accessor :data
11
11
  # @return [String, nil]
12
- attr_accessor :level
12
+ attr_reader :level
13
13
  # @return [Time, Integer, nil]
14
14
  attr_accessor :timestamp
15
15
  # @return [String, nil]
@@ -26,10 +26,10 @@ module Sentry
26
26
  def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
27
27
  @category = category
28
28
  @data = data || {}
29
- @level = level
30
29
  @timestamp = timestamp || Sentry.utc_now.to_i
31
30
  @type = type
32
31
  self.message = message
32
+ self.level = level
33
33
  end
34
34
 
35
35
  # @return [Hash]
@@ -50,6 +50,12 @@ module Sentry
50
50
  @message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
51
51
  end
52
52
 
53
+ # @param level [String]
54
+ # @return [void]
55
+ def level=(level) # needed to meet the Sentry spec
56
+ @level = level == "warn" ? "warning" : level
57
+ end
58
+
53
59
  private
54
60
 
55
61
  def serialized_data
@@ -1,4 +1,4 @@
1
- # frozen_string_literal
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'securerandom'
4
4
  require 'sentry/cron/monitor_config'
@@ -258,6 +258,11 @@ module Sentry
258
258
  # @return [Float, nil]
259
259
  attr_reader :profiles_sample_rate
260
260
 
261
+ # Array of patches to apply.
262
+ # Default is {DEFAULT_PATCHES}
263
+ # @return [Array<Symbol>]
264
+ attr_accessor :enabled_patches
265
+
261
266
  # these are not config options
262
267
  # @!visibility private
263
268
  attr_reader :errors, :gem_specs
@@ -297,6 +302,8 @@ module Sentry
297
302
 
298
303
  PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze
299
304
 
305
+ DEFAULT_PATCHES = %i(redis puma http).freeze
306
+
300
307
  class << self
301
308
  # Post initialization callbacks are called at the end of initialization process
302
309
  # allowing extending the configuration of sentry-ruby by multiple extensions
@@ -340,6 +347,7 @@ module Sentry
340
347
  self.server_name = server_name_from_env
341
348
  self.instrumenter = :sentry
342
349
  self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
350
+ self.enabled_patches = DEFAULT_PATCHES.dup
343
351
 
344
352
  self.before_send = nil
345
353
  self.before_send_transaction = nil
@@ -1,9 +1,11 @@
1
1
  module Sentry
2
2
  module Cron
3
3
  module MonitorCheckIns
4
+ MAX_SLUG_LENGTH = 50
5
+
4
6
  module Patch
5
7
  def perform(*args)
6
- slug = self.class.sentry_monitor_slug || self.class.name
8
+ slug = self.class.sentry_monitor_slug
7
9
  monitor_config = self.class.sentry_monitor_config
8
10
 
9
11
  check_in_id = Sentry.capture_check_in(slug,
@@ -43,7 +45,10 @@ module Sentry
43
45
  end
44
46
 
45
47
  def sentry_monitor_slug
46
- @sentry_monitor_slug
48
+ @sentry_monitor_slug ||= begin
49
+ slug = name.gsub('::', '-').downcase
50
+ slug[-MAX_SLUG_LENGTH..-1] || slug
51
+ end
47
52
  end
48
53
 
49
54
  def sentry_monitor_config
@@ -1,4 +1,4 @@
1
- # frozen_string_literal
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'sentry/cron/monitor_schedule'
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen_string_literal
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
4
  module Cron
@@ -22,6 +22,7 @@ module Sentry
22
22
  else
23
23
  exception.message || ""
24
24
  end
25
+ exception_message = exception_message.inspect unless exception_message.is_a?(String)
25
26
 
26
27
  @value = Utils::EncodingHelper.encode_to_utf_8(exception_message.byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES))
27
28
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "net/http"
4
+ require "resolv"
4
5
 
5
6
  module Sentry
6
7
  # @api private
@@ -77,7 +78,10 @@ module Sentry
77
78
  end
78
79
 
79
80
  def extract_request_info(req)
80
- uri = req.uri || URI.parse("#{use_ssl? ? 'https' : 'http'}://#{address}#{req.path}")
81
+ # IPv6 url could look like '::1/path', and that won't parse without
82
+ # wrapping it in square brackets.
83
+ hostname = address =~ Resolv::IPv6::Regex ? "[#{address}]" : address
84
+ uri = req.uri || URI.parse("#{use_ssl? ? 'https' : 'http'}://#{hostname}#{req.path}")
81
85
  url = "#{uri.scheme}://#{uri.host}#{uri.path}" rescue uri.to_s
82
86
 
83
87
  result = { method: req.method, url: url }
@@ -99,4 +103,4 @@ module Sentry
99
103
  end
100
104
  end
101
105
 
102
- Sentry.register_patch(Sentry::Net::HTTP, Net::HTTP)
106
+ Sentry.register_patch(:http, Sentry::Net::HTTP, Net::HTTP)
@@ -109,7 +109,7 @@ module Sentry
109
109
  }
110
110
 
111
111
  frame_hash[:module] = mod if mod
112
- frame_hash[:lineno] = frame_data[:line] if frame_data[:line]
112
+ frame_hash[:lineno] = frame_data[:line] if frame_data[:line] && frame_data[:line] >= 0
113
113
 
114
114
  frame_hash
115
115
  end
data/lib/sentry/puma.rb CHANGED
@@ -1,10 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ return unless defined?(Puma::Server)
4
+
3
5
  module Sentry
4
6
  module Puma
5
7
  module Server
8
+ PUMA_4_AND_PRIOR = Gem::Version.new(::Puma::Const::PUMA_VERSION) < Gem::Version.new("5.0.0")
9
+
6
10
  def lowlevel_error(e, env, status=500)
7
- result = super
11
+ result =
12
+ if PUMA_4_AND_PRIOR
13
+ super(e, env)
14
+ else
15
+ super
16
+ end
8
17
 
9
18
  begin
10
19
  Sentry.capture_exception(e) do |scope|
@@ -20,6 +29,4 @@ module Sentry
20
29
  end
21
30
  end
22
31
 
23
- if defined?(Puma::Server)
24
- Sentry.register_patch(Sentry::Puma::Server, Puma::Server)
25
- end
32
+ Sentry.register_patch(:puma, Sentry::Puma::Server, Puma::Server)
data/lib/sentry/redis.rb CHANGED
@@ -99,8 +99,10 @@ end
99
99
 
100
100
  if defined?(::Redis::Client)
101
101
  if Gem::Version.new(::Redis::VERSION) < Gem::Version.new("5.0")
102
- Sentry.register_patch(Sentry::Redis::OldClientPatch, ::Redis::Client)
102
+ Sentry.register_patch(:redis, Sentry::Redis::OldClientPatch, ::Redis::Client)
103
103
  elsif defined?(RedisClient)
104
- RedisClient.register(Sentry::Redis::GlobalRedisInstrumentation)
104
+ Sentry.register_patch(:redis) do
105
+ RedisClient.register(Sentry::Redis::GlobalRedisInstrumentation)
106
+ end
105
107
  end
106
108
  end
@@ -28,7 +28,7 @@ module Sentry
28
28
  end
29
29
 
30
30
  def detect_release_from_git
31
- Sentry.sys_command("git rev-parse --short HEAD") if File.directory?(".git")
31
+ Sentry.sys_command("git rev-parse HEAD") if File.directory?(".git")
32
32
  end
33
33
 
34
34
  def detect_release_from_env
@@ -3,7 +3,80 @@
3
3
  module Sentry
4
4
  class Transport
5
5
  class Configuration
6
- attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :encoding
6
+
7
+ # The timeout in seconds to open a connection to Sentry, in seconds.
8
+ # Default value is 2.
9
+ #
10
+ # @return [Integer]
11
+ attr_accessor :timeout
12
+
13
+ # The timeout in seconds to read data from Sentry, in seconds.
14
+ # Default value is 1.
15
+ #
16
+ # @return [Integer]
17
+ attr_accessor :open_timeout
18
+
19
+ # The proxy configuration to use to connect to Sentry.
20
+ # Accepts either a URI formatted string, URI, or a hash with the `uri`,
21
+ # `user`, and `password` keys.
22
+ #
23
+ # @example
24
+ # # setup proxy using a string:
25
+ # config.transport.proxy = "https://user:password@proxyhost:8080"
26
+ #
27
+ # # setup proxy using a URI:
28
+ # config.transport.proxy = URI("https://user:password@proxyhost:8080")
29
+ #
30
+ # # setup proxy using a hash:
31
+ # config.transport.proxy = {
32
+ # uri: URI("https://proxyhost:8080"),
33
+ # user: "user",
34
+ # password: "password"
35
+ # }
36
+ #
37
+ # If you're using the default transport (`Sentry::HTTPTransport`),
38
+ # proxy settings will also automatically be read from tne environment
39
+ # variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`).
40
+ #
41
+ # @return [String, URI, Hash, nil]
42
+ attr_accessor :proxy
43
+
44
+ # The SSL configuration to use to connect to Sentry.
45
+ # You can either pass a `Hash` containing `ca_file` and `verification` keys,
46
+ # or you can set those options directly on the `Sentry::HTTPTransport::Configuration` object:
47
+ #
48
+ # @example
49
+ # config.transport.ssl = {
50
+ # ca_file: "/path/to/ca_file",
51
+ # verification: true
52
+ # end
53
+ #
54
+ # @return [Hash, nil]
55
+ attr_accessor :ssl
56
+
57
+ # The path to the CA file to use to verify the SSL connection.
58
+ # Default value is `nil`.
59
+ #
60
+ # @return [String, nil]
61
+ attr_accessor :ssl_ca_file
62
+
63
+ # Whether to verify that the peer certificate is valid in SSL connections.
64
+ # Default value is `true`.
65
+ #
66
+ # @return [Boolean]
67
+ attr_accessor :ssl_verification
68
+
69
+ # The encoding to use to compress the request body.
70
+ # Default value is `Sentry::HTTPTransport::GZIP_ENCODING`.
71
+ #
72
+ # @return [String]
73
+ attr_accessor :encoding
74
+
75
+ # The class to use as a transport to connect to Sentry.
76
+ # If this option not set, it will return `nil`, and Sentry will use
77
+ # `Sentry::HTTPTransport` by default.
78
+ #
79
+ # @return [Class, nil]
7
80
  attr_reader :transport_class
8
81
 
9
82
  def initialize
@@ -128,12 +128,15 @@ module Sentry
128
128
 
129
129
  def conn
130
130
  server = URI(@dsn.server)
131
-
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
132
135
  connection =
133
136
  if proxy = normalize_proxy(@transport_configuration.proxy)
134
137
  ::Net::HTTP.new(server.hostname, server.port, proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
135
138
  else
136
- ::Net::HTTP.new(server.hostname, server.port, nil)
139
+ ::Net::HTTP.new(server.hostname, server.port)
137
140
  end
138
141
 
139
142
  connection.use_ssl = server.scheme == "https"
@@ -148,6 +151,9 @@ module Sentry
148
151
  connection
149
152
  end
150
153
 
154
+ # @param proxy [String, URI, Hash] Proxy config value passed into `config.transport`.
155
+ # Accepts either a URI formatted string, URI, or a hash with the `uri`, `user`, and `password` keys.
156
+ # @return [Hash] Normalized proxy config that will be passed into `Net::HTTP`
151
157
  def normalize_proxy(proxy)
152
158
  return proxy unless proxy
153
159
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sentry
4
- VERSION = "5.12.0"
4
+ VERSION = "5.14.0"
5
5
  end
data/lib/sentry-ruby.rb CHANGED
@@ -75,15 +75,15 @@ module Sentry
75
75
  ##### Patch Registration #####
76
76
 
77
77
  # @!visibility private
78
- def register_patch(patch = nil, target = nil, &block)
78
+ def register_patch(key, patch = nil, target = nil, &block)
79
79
  if patch && block
80
80
  raise ArgumentError.new("Please provide either a patch and its target OR a block, but not both")
81
81
  end
82
82
 
83
83
  if block
84
- registered_patches << block
84
+ registered_patches[key] = block
85
85
  else
86
- registered_patches << proc do
86
+ registered_patches[key] = proc do
87
87
  target.send(:prepend, patch) unless target.ancestors.include?(patch)
88
88
  end
89
89
  end
@@ -91,14 +91,14 @@ module Sentry
91
91
 
92
92
  # @!visibility private
93
93
  def apply_patches(config)
94
- registered_patches.each do |patch|
95
- patch.call(config)
94
+ registered_patches.each do |key, patch|
95
+ patch.call(config) if config.enabled_patches.include?(key)
96
96
  end
97
97
  end
98
98
 
99
99
  # @!visibility private
100
100
  def registered_patches
101
- @registered_patches ||= []
101
+ @registered_patches ||= {}
102
102
  end
103
103
 
104
104
  ##### Integrations #####
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.12.0
4
+ version: 5.14.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-10-10 00:00:00.000000000 Z
11
+ date: 2023-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby