sentry-ruby 4.1.0 → 4.1.5.pre.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -7
  3. metadata +31 -59
  4. data/.craft.yml +0 -19
  5. data/.gitignore +0 -11
  6. data/.rspec +0 -3
  7. data/.travis.yml +0 -6
  8. data/CHANGELOG.md +0 -89
  9. data/CODE_OF_CONDUCT.md +0 -74
  10. data/Gemfile +0 -16
  11. data/Rakefile +0 -8
  12. data/bin/console +0 -14
  13. data/bin/setup +0 -8
  14. data/lib/sentry-ruby.rb +0 -141
  15. data/lib/sentry/background_worker.rb +0 -37
  16. data/lib/sentry/backtrace.rb +0 -128
  17. data/lib/sentry/benchmarks/benchmark_transport.rb +0 -14
  18. data/lib/sentry/breadcrumb.rb +0 -25
  19. data/lib/sentry/breadcrumb/sentry_logger.rb +0 -87
  20. data/lib/sentry/breadcrumb_buffer.rb +0 -47
  21. data/lib/sentry/client.rb +0 -86
  22. data/lib/sentry/configuration.rb +0 -399
  23. data/lib/sentry/core_ext/object/deep_dup.rb +0 -57
  24. data/lib/sentry/core_ext/object/duplicable.rb +0 -153
  25. data/lib/sentry/dsn.rb +0 -48
  26. data/lib/sentry/event.rb +0 -177
  27. data/lib/sentry/hub.rb +0 -137
  28. data/lib/sentry/interface.rb +0 -22
  29. data/lib/sentry/interfaces/exception.rb +0 -11
  30. data/lib/sentry/interfaces/request.rb +0 -74
  31. data/lib/sentry/interfaces/single_exception.rb +0 -14
  32. data/lib/sentry/interfaces/stacktrace.rb +0 -57
  33. data/lib/sentry/linecache.rb +0 -44
  34. data/lib/sentry/logger.rb +0 -20
  35. data/lib/sentry/rack.rb +0 -4
  36. data/lib/sentry/rack/capture_exceptions.rb +0 -54
  37. data/lib/sentry/rack/interface.rb +0 -22
  38. data/lib/sentry/rake.rb +0 -17
  39. data/lib/sentry/scope.rb +0 -214
  40. data/lib/sentry/span.rb +0 -132
  41. data/lib/sentry/transaction.rb +0 -157
  42. data/lib/sentry/transaction_event.rb +0 -29
  43. data/lib/sentry/transport.rb +0 -87
  44. data/lib/sentry/transport/configuration.rb +0 -21
  45. data/lib/sentry/transport/dummy_transport.rb +0 -14
  46. data/lib/sentry/transport/http_transport.rb +0 -62
  47. data/lib/sentry/utils/exception_cause_chain.rb +0 -20
  48. data/lib/sentry/utils/real_ip.rb +0 -70
  49. data/lib/sentry/utils/request_id.rb +0 -16
  50. data/lib/sentry/version.rb +0 -3
  51. data/sentry-ruby.gemspec +0 -27
@@ -1,57 +0,0 @@
1
- require 'sentry/core_ext/object/duplicable'
2
-
3
- #########################################
4
- # This file was copied from Rails 5.2 #
5
- #########################################
6
-
7
- class Object
8
- # Returns a deep copy of object if it's duplicable. If it's
9
- # not duplicable, returns +self+.
10
- #
11
- # object = Object.new
12
- # dup = object.deep_dup
13
- # dup.instance_variable_set(:@a, 1)
14
- #
15
- # object.instance_variable_defined?(:@a) # => false
16
- # dup.instance_variable_defined?(:@a) # => true
17
- def deep_dup
18
- duplicable? ? dup : self
19
- end
20
- end
21
-
22
- class Array
23
- # Returns a deep copy of array.
24
- #
25
- # array = [1, [2, 3]]
26
- # dup = array.deep_dup
27
- # dup[1][2] = 4
28
- #
29
- # array[1][2] # => nil
30
- # dup[1][2] # => 4
31
- def deep_dup
32
- map(&:deep_dup)
33
- end
34
- end
35
-
36
- class Hash
37
- # Returns a deep copy of hash.
38
- #
39
- # hash = { a: { b: 'b' } }
40
- # dup = hash.deep_dup
41
- # dup[:a][:c] = 'c'
42
- #
43
- # hash[:a][:c] # => nil
44
- # dup[:a][:c] # => "c"
45
- def deep_dup
46
- hash = dup
47
- each_pair do |key, value|
48
- if key.frozen? && ::String === key
49
- hash[key] = value.deep_dup
50
- else
51
- hash.delete(key)
52
- hash[key.deep_dup] = value.deep_dup
53
- end
54
- end
55
- hash
56
- end
57
- end
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #########################################
4
- # This file was copied from Rails 5.2 #
5
- #########################################
6
-
7
- #--
8
- # Most objects are cloneable, but not all. For example you can't dup methods:
9
- #
10
- # method(:puts).dup # => TypeError: allocator undefined for Method
11
- #
12
- # Classes may signal their instances are not duplicable removing +dup+/+clone+
13
- # or raising exceptions from them. So, to dup an arbitrary object you normally
14
- # use an optimistic approach and are ready to catch an exception, say:
15
- #
16
- # arbitrary_object.dup rescue object
17
- #
18
- # Rails dups objects in a few critical spots where they are not that arbitrary.
19
- # That rescue is very expensive (like 40 times slower than a predicate), and it
20
- # is often triggered.
21
- #
22
- # That's why we hardcode the following cases and check duplicable? instead of
23
- # using that rescue idiom.
24
- #++
25
- class Object
26
- # Can you safely dup this object?
27
- #
28
- # False for method objects;
29
- # true otherwise.
30
- def duplicable?
31
- true
32
- end
33
- end
34
-
35
- class NilClass
36
- begin
37
- nil.dup
38
- rescue TypeError
39
- # +nil+ is not duplicable:
40
- #
41
- # nil.duplicable? # => false
42
- # nil.dup # => TypeError: can't dup NilClass
43
- def duplicable?
44
- false
45
- end
46
- end
47
- end
48
-
49
- class FalseClass
50
- begin
51
- false.dup
52
- rescue TypeError
53
- # +false+ is not duplicable:
54
- #
55
- # false.duplicable? # => false
56
- # false.dup # => TypeError: can't dup FalseClass
57
- def duplicable?
58
- false
59
- end
60
- end
61
- end
62
-
63
- class TrueClass
64
- begin
65
- true.dup
66
- rescue TypeError
67
- # +true+ is not duplicable:
68
- #
69
- # true.duplicable? # => false
70
- # true.dup # => TypeError: can't dup TrueClass
71
- def duplicable?
72
- false
73
- end
74
- end
75
- end
76
-
77
- class Symbol
78
- begin
79
- :symbol.dup # Ruby 2.4.x.
80
- "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
81
- rescue TypeError
82
- # Symbols are not duplicable:
83
- #
84
- # :my_symbol.duplicable? # => false
85
- # :my_symbol.dup # => TypeError: can't dup Symbol
86
- def duplicable?
87
- false
88
- end
89
- end
90
- end
91
-
92
- class Numeric
93
- begin
94
- 1.dup
95
- rescue TypeError
96
- # Numbers are not duplicable:
97
- #
98
- # 3.duplicable? # => false
99
- # 3.dup # => TypeError: can't dup Integer
100
- def duplicable?
101
- false
102
- end
103
- end
104
- end
105
-
106
- require "bigdecimal"
107
- class BigDecimal
108
- # BigDecimals are duplicable:
109
- #
110
- # BigDecimal("1.2").duplicable? # => true
111
- # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
112
- def duplicable?
113
- true
114
- end
115
- end
116
-
117
- class Method
118
- # Methods are not duplicable:
119
- #
120
- # method(:puts).duplicable? # => false
121
- # method(:puts).dup # => TypeError: allocator undefined for Method
122
- def duplicable?
123
- false
124
- end
125
- end
126
-
127
- class Complex
128
- begin
129
- Complex(1).dup
130
- rescue TypeError
131
- # Complexes are not duplicable:
132
- #
133
- # Complex(1).duplicable? # => false
134
- # Complex(1).dup # => TypeError: can't copy Complex
135
- def duplicable?
136
- false
137
- end
138
- end
139
- end
140
-
141
- class Rational
142
- begin
143
- Rational(1).dup
144
- rescue TypeError
145
- # Rationals are not duplicable:
146
- #
147
- # Rational(1).duplicable? # => false
148
- # Rational(1).dup # => TypeError: can't copy Rational
149
- def duplicable?
150
- false
151
- end
152
- end
153
- end
@@ -1,48 +0,0 @@
1
- require "uri"
2
-
3
- module Sentry
4
- class DSN
5
- PORT_MAP = { 'http' => 80, 'https' => 443 }.freeze
6
- REQUIRED_ATTRIBUTES = %w(host path public_key project_id).freeze
7
-
8
- attr_reader :scheme, :secret_key, :port, *REQUIRED_ATTRIBUTES
9
-
10
- def initialize(dsn_string)
11
- @raw_value = dsn_string
12
-
13
- uri = URI.parse(dsn_string)
14
- uri_path = uri.path.split('/')
15
-
16
- if uri.user
17
- # DSN-style string
18
- @project_id = uri_path.pop
19
- @public_key = uri.user
20
- @secret_key = !(uri.password.nil? || uri.password.empty?) ? uri.password : nil
21
- end
22
-
23
- @scheme = uri.scheme
24
- @host = uri.host
25
- @port = uri.port if uri.port
26
- @path = uri_path.join('/')
27
- end
28
-
29
- def valid?
30
- REQUIRED_ATTRIBUTES.all? { |k| public_send(k) }
31
- end
32
-
33
- def to_s
34
- @raw_value
35
- end
36
-
37
- def server
38
- server = "#{scheme}://#{host}"
39
- server += ":#{port}" unless port == PORT_MAP[scheme]
40
- server += path
41
- server
42
- end
43
-
44
- def envelope_endpoint
45
- "#{path}/api/#{project_id}/envelope/"
46
- end
47
- end
48
- end
@@ -1,177 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'socket'
4
- require 'securerandom'
5
- require 'sentry/interface'
6
- require 'sentry/backtrace'
7
- require 'sentry/utils/real_ip'
8
- require 'sentry/utils/request_id'
9
-
10
- module Sentry
11
- class Event
12
- ATTRIBUTES = %i(
13
- event_id level timestamp
14
- release environment server_name modules
15
- message user tags contexts extra
16
- fingerprint breadcrumbs backtrace transaction
17
- platform sdk type
18
- )
19
-
20
- attr_accessor(*ATTRIBUTES)
21
- attr_reader :configuration, :request, :exception, :stacktrace
22
-
23
- def initialize(configuration:, message: nil)
24
- # this needs to go first because some setters rely on configuration
25
- @configuration = configuration
26
-
27
- # Set some simple default values
28
- @event_id = SecureRandom.uuid.delete("-")
29
- @timestamp = Sentry.utc_now.iso8601
30
- @platform = :ruby
31
- @sdk = Sentry.sdk_meta
32
-
33
- @user = {}
34
- @extra = {}
35
- @contexts = {}
36
- @tags = {}
37
-
38
- @fingerprint = []
39
-
40
- @server_name = configuration.server_name
41
- @environment = configuration.environment
42
- @release = configuration.release
43
- @modules = configuration.gem_specs if configuration.send_modules
44
-
45
- @message = message || ""
46
-
47
- self.level = :error
48
- end
49
-
50
- class << self
51
- def get_log_message(event_hash)
52
- message = event_hash[:message] || event_hash['message']
53
- message = get_message_from_exception(event_hash) if message.nil? || message.empty?
54
- message = '<no message value>' if message.nil? || message.empty?
55
- message
56
- end
57
-
58
- def get_message_from_exception(event_hash)
59
- (
60
- event_hash &&
61
- event_hash[:exception] &&
62
- event_hash[:exception][:values] &&
63
- event_hash[:exception][:values][0] &&
64
- "#{event_hash[:exception][:values][0][:type]}: #{event_hash[:exception][:values][0][:value]}"
65
- )
66
- end
67
- end
68
-
69
- def timestamp=(time)
70
- @timestamp = time.is_a?(Time) ? time.to_f : time
71
- end
72
-
73
- def level=(new_level) # needed to meet the Sentry spec
74
- @level = new_level.to_s == "warn" ? :warning : new_level
75
- end
76
-
77
- def rack_env=(env)
78
- unless request || env.empty?
79
- @request = Sentry::RequestInterface.new.tap do |int|
80
- int.from_rack(env)
81
- end
82
-
83
- if configuration.send_default_pii && ip = calculate_real_ip_from_rack(env.dup)
84
- user[:ip_address] = ip
85
- end
86
- if request_id = Utils::RequestId.read_from(env)
87
- tags[:request_id] = request_id
88
- end
89
- end
90
- end
91
-
92
- def type
93
- "event"
94
- end
95
-
96
- def to_hash
97
- data = serialize_attributes
98
- data[:breadcrumbs] = breadcrumbs.to_hash if breadcrumbs
99
- data[:stacktrace] = stacktrace.to_hash if stacktrace
100
- data[:request] = request.to_hash if request
101
- data[:exception] = exception.to_hash if exception
102
-
103
- data
104
- end
105
-
106
- def to_json_compatible
107
- JSON.parse(JSON.generate(to_hash))
108
- end
109
-
110
- def add_exception_interface(exc)
111
- if exc.respond_to?(:sentry_context)
112
- @extra.merge!(exc.sentry_context)
113
- end
114
-
115
- @exception = Sentry::ExceptionInterface.new.tap do |exc_int|
116
- exceptions = Sentry::Utils::ExceptionCauseChain.exception_to_array(exc).reverse
117
- backtraces = Set.new
118
- exc_int.values = exceptions.map do |e|
119
- SingleExceptionInterface.new.tap do |int|
120
- int.type = e.class.to_s
121
- int.value = e.to_s
122
- int.module = e.class.to_s.split('::')[0...-1].join('::')
123
-
124
- int.stacktrace =
125
- if e.backtrace && !backtraces.include?(e.backtrace.object_id)
126
- backtraces << e.backtrace.object_id
127
- StacktraceInterface.new.tap do |stacktrace|
128
- stacktrace.frames = stacktrace_interface_from(e.backtrace)
129
- end
130
- end
131
- end
132
- end
133
- end
134
- end
135
-
136
- def stacktrace_interface_from(backtrace)
137
- project_root = configuration.project_root.to_s
138
-
139
- Backtrace.parse(backtrace, configuration: configuration).lines.reverse.each_with_object([]) do |line, memo|
140
- frame = StacktraceInterface::Frame.new(project_root)
141
- frame.abs_path = line.file if line.file
142
- frame.function = line.method if line.method
143
- frame.lineno = line.number
144
- frame.in_app = line.in_app
145
- frame.module = line.module_name if line.module_name
146
-
147
- if configuration.context_lines && frame.abs_path
148
- frame.pre_context, frame.context_line, frame.post_context = \
149
- configuration.linecache.get_file_context(frame.abs_path, frame.lineno, configuration.context_lines)
150
- end
151
-
152
- memo << frame if frame.filename
153
- end
154
- end
155
-
156
- private
157
-
158
- def serialize_attributes
159
- self.class::ATTRIBUTES.each_with_object({}) do |att, memo|
160
- if value = public_send(att)
161
- memo[att] = value
162
- end
163
- end
164
- end
165
-
166
- # When behind a proxy (or if the user is using a proxy), we can't use
167
- # REMOTE_ADDR to determine the Event IP, and must use other headers instead.
168
- def calculate_real_ip_from_rack(env)
169
- Utils::RealIp.new(
170
- :remote_addr => env["REMOTE_ADDR"],
171
- :client_ip => env["HTTP_CLIENT_IP"],
172
- :real_ip => env["HTTP_X_REAL_IP"],
173
- :forwarded_for => env["HTTP_X_FORWARDED_FOR"]
174
- ).calculate_ip
175
- end
176
- end
177
- end
@@ -1,137 +0,0 @@
1
- require "sentry/scope"
2
- require "sentry/client"
3
-
4
- module Sentry
5
- class Hub
6
- attr_reader :last_event_id
7
-
8
- def initialize(client, scope)
9
- first_layer = Layer.new(client, scope)
10
- @stack = [first_layer]
11
- @last_event_id = nil
12
- end
13
-
14
- def new_from_top
15
- Hub.new(current_client, current_scope)
16
- end
17
-
18
- def current_client
19
- current_layer&.client
20
- end
21
-
22
- def current_scope
23
- current_layer&.scope
24
- end
25
-
26
- def clone
27
- layer = current_layer
28
-
29
- if layer
30
- scope = layer.scope&.dup
31
-
32
- Hub.new(layer.client, scope)
33
- end
34
- end
35
-
36
- def bind_client(client)
37
- layer = current_layer
38
-
39
- if layer
40
- layer.client = client
41
- end
42
- end
43
-
44
- def configure_scope(&block)
45
- block.call(current_scope)
46
- end
47
-
48
- def with_scope(&block)
49
- push_scope
50
- yield(current_scope)
51
- ensure
52
- pop_scope
53
- end
54
-
55
- def push_scope
56
- new_scope =
57
- if current_scope
58
- current_scope.dup
59
- else
60
- Scope.new
61
- end
62
-
63
- @stack << Layer.new(current_client, new_scope)
64
- end
65
-
66
- def pop_scope
67
- @stack.pop
68
- end
69
-
70
- def start_transaction(transaction: nil, **options)
71
- transaction ||= Transaction.new(**options)
72
- transaction.set_initial_sample_desicion
73
- transaction
74
- end
75
-
76
- def capture_exception(exception, **options, &block)
77
- return unless current_client
78
-
79
- event = current_client.event_from_exception(exception)
80
-
81
- return unless event
82
-
83
- options[:hint] ||= {}
84
- options[:hint] = options[:hint].merge(exception: exception)
85
- capture_event(event, **options, &block)
86
- end
87
-
88
- def capture_message(message, **options, &block)
89
- return unless current_client
90
-
91
- options[:hint] ||= {}
92
- options[:hint] = options[:hint].merge(message: message)
93
- event = current_client.event_from_message(message)
94
- capture_event(event, **options, &block)
95
- end
96
-
97
- def capture_event(event, **options, &block)
98
- return unless current_client
99
-
100
- hint = options.delete(:hint) || {}
101
- scope = current_scope.dup
102
-
103
- if block
104
- block.call(scope)
105
- elsif custom_scope = options[:scope]
106
- scope.update_from_scope(custom_scope)
107
- elsif !options.empty?
108
- scope.update_from_options(**options)
109
- end
110
-
111
- event = current_client.capture_event(event, scope, hint)
112
-
113
- @last_event_id = event.event_id
114
- event
115
- end
116
-
117
- def add_breadcrumb(breadcrumb)
118
- current_scope.add_breadcrumb(breadcrumb)
119
- end
120
-
121
- private
122
-
123
- def current_layer
124
- @stack.last
125
- end
126
-
127
- class Layer
128
- attr_accessor :client
129
- attr_reader :scope
130
-
131
- def initialize(client, scope)
132
- @client = client
133
- @scope = scope
134
- end
135
- end
136
- end
137
- end