sentry-ruby 4.1.2 → 4.1.5

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -7
  3. metadata +21 -57
  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 -102
  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 -152
  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 -90
  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/integrable.rb +0 -24
  29. data/lib/sentry/interface.rb +0 -22
  30. data/lib/sentry/interfaces/exception.rb +0 -11
  31. data/lib/sentry/interfaces/request.rb +0 -74
  32. data/lib/sentry/interfaces/single_exception.rb +0 -14
  33. data/lib/sentry/interfaces/stacktrace.rb +0 -57
  34. data/lib/sentry/linecache.rb +0 -44
  35. data/lib/sentry/logger.rb +0 -20
  36. data/lib/sentry/rack.rb +0 -5
  37. data/lib/sentry/rack/capture_exceptions.rb +0 -62
  38. data/lib/sentry/rack/deprecations.rb +0 -19
  39. data/lib/sentry/rack/interface.rb +0 -22
  40. data/lib/sentry/rake.rb +0 -17
  41. data/lib/sentry/scope.rb +0 -214
  42. data/lib/sentry/span.rb +0 -132
  43. data/lib/sentry/transaction.rb +0 -157
  44. data/lib/sentry/transaction_event.rb +0 -29
  45. data/lib/sentry/transport.rb +0 -88
  46. data/lib/sentry/transport/configuration.rb +0 -21
  47. data/lib/sentry/transport/dummy_transport.rb +0 -14
  48. data/lib/sentry/transport/http_transport.rb +0 -62
  49. data/lib/sentry/utils/exception_cause_chain.rb +0 -20
  50. data/lib/sentry/utils/real_ip.rb +0 -70
  51. data/lib/sentry/utils/request_id.rb +0 -16
  52. data/lib/sentry/version.rb +0 -3
  53. data/sentry-ruby.gemspec +0 -27
@@ -1,24 +0,0 @@
1
- module Sentry
2
- module Integrable
3
- def register_integration(name:, version:)
4
- Sentry.register_integration(name, version)
5
- @integration_name = name
6
- end
7
-
8
- def integration_name
9
- @integration_name
10
- end
11
-
12
- def capture_exception(exception, **options, &block)
13
- options[:hint] ||= {}
14
- options[:hint][:integration] = integration_name
15
- Sentry.capture_exception(exception, **options, &block)
16
- end
17
-
18
- def capture_message(message, **options, &block)
19
- options[:hint] ||= {}
20
- options[:hint][:integration] = integration_name
21
- Sentry.capture_message(message, **options, &block)
22
- end
23
- end
24
- end
@@ -1,22 +0,0 @@
1
- module Sentry
2
- class Interface
3
- def self.inherited(klass)
4
- name = klass.name.split("::").last.downcase.gsub("interface", "")
5
- registered[name.to_sym] = klass
6
- super
7
- end
8
-
9
- def self.registered
10
- @@registered ||= {} # rubocop:disable Style/ClassVars
11
- end
12
-
13
- def to_hash
14
- Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
15
- end
16
- end
17
- end
18
-
19
- require "sentry/interfaces/exception"
20
- require "sentry/interfaces/request"
21
- require "sentry/interfaces/single_exception"
22
- require "sentry/interfaces/stacktrace"
@@ -1,11 +0,0 @@
1
- module Sentry
2
- class ExceptionInterface < Interface
3
- attr_accessor :values
4
-
5
- def to_hash
6
- data = super
7
- data[:values] = data[:values].map(&:to_hash) if data[:values]
8
- data
9
- end
10
- end
11
- end
@@ -1,74 +0,0 @@
1
- module Sentry
2
- class RequestInterface < Interface
3
- REQUEST_ID_HEADERS = %w(action_dispatch.request_id HTTP_X_REQUEST_ID).freeze
4
- IP_HEADERS = [
5
- "REMOTE_ADDR",
6
- "HTTP_CLIENT_IP",
7
- "HTTP_X_REAL_IP",
8
- "HTTP_X_FORWARDED_FOR"
9
- ].freeze
10
-
11
- attr_accessor :url, :method, :data, :query_string, :cookies, :headers, :env
12
-
13
- def initialize
14
- self.headers = {}
15
- self.env = {}
16
- self.cookies = nil
17
- end
18
-
19
- private
20
-
21
- # See Sentry server default limits at
22
- # https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
23
- def read_data_from(request)
24
- if request.form_data?
25
- request.POST
26
- elsif request.body # JSON requests, etc
27
- data = request.body.read(4096 * 4) # Sentry server limit
28
- request.body.rewind
29
- data
30
- end
31
- rescue IOError => e
32
- e.message
33
- end
34
-
35
- def format_headers_for_sentry(env_hash)
36
- env_hash.each_with_object({}) do |(key, value), memo|
37
- begin
38
- key = key.to_s # rack env can contain symbols
39
- value = value.to_s
40
- next memo['X-Request-Id'] ||= Utils::RequestId.read_from(env_hash) if Utils::RequestId::REQUEST_ID_HEADERS.include?(key)
41
- next unless key.upcase == key # Non-upper case stuff isn't either
42
-
43
- # Rack adds in an incorrect HTTP_VERSION key, which causes downstream
44
- # to think this is a Version header. Instead, this is mapped to
45
- # env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
46
- # if the request has legitimately sent a Version header themselves.
47
- # See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
48
- next if key == 'HTTP_VERSION' && value == env_hash['SERVER_PROTOCOL']
49
- next if key == 'HTTP_COOKIE' # Cookies don't go here, they go somewhere else
50
- next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key)
51
-
52
- # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
53
- key = key.sub(/^HTTP_/, "")
54
- key = key.split('_').map(&:capitalize).join('-')
55
- memo[key] = value
56
- rescue StandardError => e
57
- # Rails adds objects to the Rack env that can sometimes raise exceptions
58
- # when `to_s` is called.
59
- # See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134
60
- Sentry.logger.warn(LOGGER_PROGNAME) { "Error raised while formatting headers: #{e.message}" }
61
- next
62
- end
63
- end
64
- end
65
-
66
- def format_env_for_sentry(env_hash)
67
- return env_hash if Sentry.configuration.rack_env_whitelist.empty?
68
-
69
- env_hash.select do |k, _v|
70
- Sentry.configuration.rack_env_whitelist.include? k.to_s
71
- end
72
- end
73
- end
74
- end
@@ -1,14 +0,0 @@
1
- module Sentry
2
- class SingleExceptionInterface < Interface
3
- attr_accessor :type
4
- attr_accessor :value
5
- attr_accessor :module
6
- attr_accessor :stacktrace
7
-
8
- def to_hash
9
- data = super
10
- data[:stacktrace] = data[:stacktrace].to_hash if data[:stacktrace]
11
- data
12
- end
13
- end
14
- end
@@ -1,57 +0,0 @@
1
- module Sentry
2
- class StacktraceInterface < Interface
3
- attr_accessor :frames
4
-
5
- def to_hash
6
- data = super
7
- data[:frames] = data[:frames].map(&:to_hash)
8
- data
9
- end
10
-
11
- # Not actually an interface, but I want to use the same style
12
- class Frame < Interface
13
- attr_accessor :abs_path, :context_line, :function, :in_app,
14
- :lineno, :module, :pre_context, :post_context, :vars
15
-
16
- def initialize(project_root)
17
- @project_root = project_root
18
- end
19
-
20
- def filename
21
- return if abs_path.nil?
22
- return @filename if instance_variable_defined?(:@filename)
23
-
24
- prefix =
25
- if under_project_root? && in_app
26
- @project_root
27
- elsif under_project_root?
28
- longest_load_path || @project_root
29
- else
30
- longest_load_path
31
- end
32
-
33
- @filename = prefix ? abs_path[prefix.to_s.chomp(File::SEPARATOR).length + 1..-1] : abs_path
34
- end
35
-
36
- def to_hash(*args)
37
- data = super(*args)
38
- data[:filename] = filename
39
- data.delete(:vars) unless vars && !vars.empty?
40
- data.delete(:pre_context) unless pre_context && !pre_context.empty?
41
- data.delete(:post_context) unless post_context && !post_context.empty?
42
- data.delete(:context_line) unless context_line && !context_line.empty?
43
- data
44
- end
45
-
46
- private
47
-
48
- def under_project_root?
49
- @project_root && abs_path.start_with?(@project_root)
50
- end
51
-
52
- def longest_load_path
53
- $LOAD_PATH.select { |path| abs_path.start_with?(path.to_s) }.max_by(&:size)
54
- end
55
- end
56
- end
57
- end
@@ -1,44 +0,0 @@
1
- module Sentry
2
- class LineCache
3
- def initialize
4
- @cache = {}
5
- end
6
-
7
- # Any linecache you provide to Sentry must implement this method.
8
- # Returns an Array of Strings representing the lines in the source
9
- # file. The number of lines retrieved is (2 * context) + 1, the middle
10
- # line should be the line requested by lineno. See specs for more information.
11
- def get_file_context(filename, lineno, context)
12
- return nil, nil, nil unless valid_path?(filename)
13
-
14
- lines = Array.new(2 * context + 1) do |i|
15
- getline(filename, lineno - context + i)
16
- end
17
- [lines[0..(context - 1)], lines[context], lines[(context + 1)..-1]]
18
- end
19
-
20
- private
21
-
22
- def valid_path?(path)
23
- lines = getlines(path)
24
- !lines.nil?
25
- end
26
-
27
- def getlines(path)
28
- @cache[path] ||= begin
29
- IO.readlines(path)
30
- rescue
31
- nil
32
- end
33
- end
34
-
35
- def getline(path, n)
36
- return nil if n < 1
37
-
38
- lines = getlines(path)
39
- return nil if lines.nil?
40
-
41
- lines[n - 1]
42
- end
43
- end
44
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'logger'
4
-
5
- module Sentry
6
- class Logger < ::Logger
7
- LOG_PREFIX = "** [Sentry] "
8
- PROGNAME = "sentry"
9
-
10
- def initialize(*)
11
- super
12
- @level = ::Logger::INFO
13
- original_formatter = ::Logger::Formatter.new
14
- @default_formatter = proc do |severity, datetime, _progname, msg|
15
- msg = "#{LOG_PREFIX}#{msg}"
16
- original_formatter.call(severity, datetime, PROGNAME, msg)
17
- end
18
- end
19
- end
20
- end
@@ -1,5 +0,0 @@
1
- require 'rack'
2
-
3
- require 'sentry/rack/capture_exceptions'
4
- require 'sentry/rack/interface'
5
- require 'sentry/rack/deprecations'
@@ -1,62 +0,0 @@
1
- module Sentry
2
- module Rack
3
- class CaptureExceptions
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def call(env)
9
- return @app.call(env) unless Sentry.initialized?
10
-
11
- # make sure the current thread has a clean hub
12
- Sentry.clone_hub_to_current_thread
13
-
14
- Sentry.with_scope do |scope|
15
- scope.clear_breadcrumbs
16
- scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
17
- scope.set_rack_env(env)
18
-
19
- span = Sentry.start_transaction(name: scope.transaction_name, op: transaction_op)
20
- scope.set_span(span)
21
-
22
- begin
23
- response = @app.call(env)
24
- rescue Sentry::Error
25
- finish_span(span, 500)
26
- raise # Don't capture Sentry errors
27
- rescue Exception => e
28
- capture_exception(e)
29
- finish_span(span, 500)
30
- raise
31
- end
32
-
33
- exception = collect_exception(env)
34
- capture_exception(exception) if exception
35
-
36
- finish_span(span, response[0])
37
-
38
- response
39
- end
40
- end
41
-
42
- private
43
-
44
- def collect_exception(env)
45
- env['rack.exception'] || env['sinatra.error']
46
- end
47
-
48
- def transaction_op
49
- "rack.request".freeze
50
- end
51
-
52
- def capture_exception(exception)
53
- Sentry.capture_exception(exception)
54
- end
55
-
56
- def finish_span(span, status_code)
57
- span.set_http_status(status_code)
58
- span.finish
59
- end
60
- end
61
- end
62
- end
@@ -1,19 +0,0 @@
1
- module Sentry
2
- module Rack
3
- class DeprecatedMiddleware
4
- def initialize(_)
5
- raise Sentry::Error.new <<~MSG
6
-
7
- You're seeing this message because #{self.class} has been replaced by Sentry::Rack::CaptureExceptions.
8
- Removing this middleware from your app and upgrading sentry-rails to 4.1.0+ should solve the issue.
9
- MSG
10
- end
11
- end
12
-
13
- class Tracing < DeprecatedMiddleware
14
- end
15
-
16
- class CaptureException < DeprecatedMiddleware
17
- end
18
- end
19
- end
@@ -1,22 +0,0 @@
1
- module Sentry
2
- class RequestInterface
3
- def from_rack(env_hash)
4
- req = ::Rack::Request.new(env_hash)
5
-
6
- if Sentry.configuration.send_default_pii
7
- self.data = read_data_from(req)
8
- self.cookies = req.cookies
9
- else
10
- # need to completely wipe out ip addresses
11
- IP_HEADERS.each { |h| env_hash.delete(h) }
12
- end
13
-
14
- self.url = req.scheme && req.url.split('?').first
15
- self.method = req.request_method
16
- self.query_string = req.query_string
17
-
18
- self.headers = format_headers_for_sentry(env_hash)
19
- self.env = format_env_for_sentry(env_hash)
20
- end
21
- end
22
- end
@@ -1,17 +0,0 @@
1
- require "rake"
2
- require "rake/task"
3
-
4
- module Rake
5
- class Application
6
- alias orig_display_error_messsage display_error_message
7
- def display_error_message(ex)
8
- Sentry.capture_exception(ex, hint: { background: false }) do |scope|
9
- task_name = top_level_tasks.join(' ')
10
- scope.set_transaction_name(task_name)
11
- scope.set_tag("rake_task", task_name)
12
- end if Sentry.initialized?
13
-
14
- orig_display_error_messsage(ex)
15
- end
16
- end
17
- end
@@ -1,214 +0,0 @@
1
- require "sentry/breadcrumb_buffer"
2
- require "etc"
3
-
4
- module Sentry
5
- class Scope
6
- ATTRIBUTES = [:transaction_names, :contexts, :extra, :tags, :user, :level, :breadcrumbs, :fingerprint, :event_processors, :rack_env, :span]
7
-
8
- attr_reader(*ATTRIBUTES)
9
-
10
- def initialize
11
- set_default_value
12
- end
13
-
14
- def clear
15
- set_default_value
16
- end
17
-
18
- def apply_to_event(event, hint = nil)
19
- event.tags = tags.merge(event.tags)
20
- event.user = user.merge(event.user)
21
- event.extra = extra.merge(event.extra)
22
- event.contexts = contexts.merge(event.contexts)
23
-
24
- if span
25
- event.contexts[:trace] = span.get_trace_context
26
- end
27
-
28
- event.fingerprint = fingerprint
29
- event.level = level
30
- event.transaction = transaction_names.last
31
- event.breadcrumbs = breadcrumbs
32
- event.rack_env = rack_env if rack_env
33
-
34
- unless @event_processors.empty?
35
- @event_processors.each do |processor_block|
36
- event = processor_block.call(event, hint)
37
- end
38
- end
39
-
40
- event
41
- end
42
-
43
- def add_breadcrumb(breadcrumb)
44
- breadcrumbs.record(breadcrumb)
45
- end
46
-
47
- def clear_breadcrumbs
48
- @breadcrumbs = BreadcrumbBuffer.new
49
- end
50
-
51
- def dup
52
- copy = super
53
- copy.breadcrumbs = breadcrumbs.dup
54
- copy.contexts = contexts.deep_dup
55
- copy.extra = extra.deep_dup
56
- copy.tags = tags.deep_dup
57
- copy.user = user.deep_dup
58
- copy.transaction_names = transaction_names.deep_dup
59
- copy.fingerprint = fingerprint.deep_dup
60
- copy.span = span.deep_dup
61
- copy
62
- end
63
-
64
- def update_from_scope(scope)
65
- self.breadcrumbs = scope.breadcrumbs
66
- self.contexts = scope.contexts
67
- self.extra = scope.extra
68
- self.tags = scope.tags
69
- self.user = scope.user
70
- self.transaction_names = scope.transaction_names
71
- self.fingerprint = scope.fingerprint
72
- self.span = scope.span
73
- end
74
-
75
- def update_from_options(
76
- contexts: nil,
77
- extra: nil,
78
- tags: nil,
79
- user: nil,
80
- level: nil,
81
- fingerprint: nil
82
- )
83
- self.contexts.merge!(contexts) if contexts
84
- self.extra.merge!(extra) if extra
85
- self.tags.merge!(tags) if tags
86
- self.user = user if user
87
- self.level = level if level
88
- self.fingerprint = fingerprint if fingerprint
89
- end
90
-
91
- def set_rack_env(env)
92
- env = env || {}
93
- @rack_env = env
94
- end
95
-
96
- def set_span(span)
97
- check_argument_type!(span, Span)
98
- @span = span
99
- end
100
-
101
- def set_user(user_hash)
102
- check_argument_type!(user_hash, Hash)
103
- @user = user_hash
104
- end
105
-
106
- def set_extras(extras_hash)
107
- check_argument_type!(extras_hash, Hash)
108
- @extra.merge!(extras_hash)
109
- end
110
-
111
- def set_extra(key, value)
112
- @extra.merge!(key => value)
113
- end
114
-
115
- def set_tags(tags_hash)
116
- check_argument_type!(tags_hash, Hash)
117
- @tags.merge!(tags_hash)
118
- end
119
-
120
- def set_tag(key, value)
121
- @tags.merge!(key => value)
122
- end
123
-
124
- def set_contexts(contexts_hash)
125
- check_argument_type!(contexts_hash, Hash)
126
- @contexts = contexts_hash
127
- end
128
-
129
- def set_context(key, value)
130
- @contexts.merge!(key => value)
131
- end
132
-
133
- def set_level(level)
134
- @level = level
135
- end
136
-
137
- def set_transaction_name(transaction_name)
138
- @transaction_names << transaction_name
139
- end
140
-
141
- def transaction_name
142
- @transaction_names.last
143
- end
144
-
145
- def get_transaction
146
- # transaction will always be the first in the span_recorder
147
- span.span_recorder.spans.first if span
148
- end
149
-
150
- def get_span
151
- span
152
- end
153
-
154
- def set_fingerprint(fingerprint)
155
- check_argument_type!(fingerprint, Array)
156
-
157
- @fingerprint = fingerprint
158
- end
159
-
160
- def add_event_processor(&block)
161
- @event_processors << block
162
- end
163
-
164
- protected
165
-
166
- # for duplicating scopes internally
167
- attr_writer(*ATTRIBUTES)
168
-
169
- private
170
-
171
- def check_argument_type!(argument, expected_type)
172
- unless argument.is_a?(expected_type)
173
- raise ArgumentError, "expect the argument to be a #{expected_type}, got #{argument.class} (#{argument})"
174
- end
175
- end
176
-
177
- def set_default_value
178
- @breadcrumbs = BreadcrumbBuffer.new
179
- @contexts = { :os => self.class.os_context, :runtime => self.class.runtime_context }
180
- @extra = {}
181
- @tags = {}
182
- @user = {}
183
- @level = :error
184
- @fingerprint = []
185
- @transaction_names = []
186
- @event_processors = []
187
- @rack_env = {}
188
- @span = nil
189
- end
190
-
191
- class << self
192
- def os_context
193
- @os_context ||=
194
- begin
195
- uname = Etc.uname
196
- {
197
- name: uname[:sysname] || RbConfig::CONFIG["host_os"],
198
- version: uname[:version],
199
- build: uname[:release],
200
- kernel_version: uname[:version]
201
- }
202
- end
203
- end
204
-
205
- def runtime_context
206
- @runtime_context ||= {
207
- name: RbConfig::CONFIG["ruby_install_name"],
208
- version: RUBY_DESCRIPTION || Sentry.sys_command("ruby -v")
209
- }
210
- end
211
- end
212
-
213
- end
214
- end