sentry-ruby 4.1.4 → 4.2.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -2
  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 -120
  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 -190
  15. data/lib/sentry/background_worker.rb +0 -37
  16. data/lib/sentry/backtrace.rb +0 -126
  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 -96
  22. data/lib/sentry/configuration.rb +0 -396
  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 -171
  27. data/lib/sentry/hub.rb +0 -143
  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 -113
  32. data/lib/sentry/interfaces/single_exception.rb +0 -14
  33. data/lib/sentry/interfaces/stacktrace.rb +0 -90
  34. data/lib/sentry/linecache.rb +0 -44
  35. data/lib/sentry/logger.rb +0 -20
  36. data/lib/sentry/rack.rb +0 -4
  37. data/lib/sentry/rack/capture_exceptions.rb +0 -68
  38. data/lib/sentry/rack/deprecations.rb +0 -19
  39. data/lib/sentry/rake.rb +0 -17
  40. data/lib/sentry/scope.rb +0 -210
  41. data/lib/sentry/span.rb +0 -133
  42. data/lib/sentry/transaction.rb +0 -157
  43. data/lib/sentry/transaction_event.rb +0 -29
  44. data/lib/sentry/transport.rb +0 -88
  45. data/lib/sentry/transport/configuration.rb +0 -21
  46. data/lib/sentry/transport/dummy_transport.rb +0 -14
  47. data/lib/sentry/transport/http_transport.rb +0 -62
  48. data/lib/sentry/utils/argument_checking_helper.rb +0 -11
  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
data/lib/sentry-ruby.rb DELETED
@@ -1,190 +0,0 @@
1
- require "forwardable"
2
- require "time"
3
-
4
- require "sentry/version"
5
- require "sentry/core_ext/object/deep_dup"
6
- require "sentry/utils/argument_checking_helper"
7
- require "sentry/configuration"
8
- require "sentry/logger"
9
- require "sentry/event"
10
- require "sentry/transaction_event"
11
- require "sentry/span"
12
- require "sentry/transaction"
13
- require "sentry/hub"
14
- require "sentry/background_worker"
15
-
16
- def safely_require(lib)
17
- begin
18
- require lib
19
- rescue LoadError
20
- end
21
- end
22
-
23
- safely_require "sentry/rake"
24
- safely_require "sentry/rack"
25
-
26
- module Sentry
27
- class Error < StandardError
28
- end
29
-
30
- META = { "name" => "sentry.ruby", "version" => Sentry::VERSION }.freeze
31
-
32
- LOGGER_PROGNAME = "sentry".freeze
33
-
34
- THREAD_LOCAL = :sentry_hub
35
-
36
- def self.sdk_meta
37
- META
38
- end
39
-
40
- def self.utc_now
41
- Time.now.utc
42
- end
43
-
44
- class << self
45
- # Returns a hash that contains all the integrations that have been registered to the main SDK.
46
- def integrations
47
- @integrations ||= {}
48
- end
49
-
50
- # Registers the SDK integration with its name and version.
51
- def register_integration(name, version)
52
- meta = { name: "sentry.ruby.#{name}", version: version }.freeze
53
- integrations[name.to_s] = meta
54
- end
55
- end
56
-
57
- class << self
58
- extend Forwardable
59
-
60
- def_delegators :get_current_client, :configuration, :send_event
61
- def_delegators :get_current_scope, :set_tags, :set_extras, :set_user
62
-
63
- attr_accessor :background_worker
64
-
65
- def init(&block)
66
- config = Configuration.new
67
- yield(config)
68
- client = Client.new(config)
69
- scope = Scope.new
70
- hub = Hub.new(client, scope)
71
- Thread.current[THREAD_LOCAL] = hub
72
- @main_hub = hub
73
- @background_worker = Sentry::BackgroundWorker.new(config)
74
- end
75
-
76
- # Returns the main thread's active hub.
77
- def get_main_hub
78
- @main_hub
79
- end
80
-
81
- # Takes an instance of Sentry::Breadcrumb and stores it to the current active scope.
82
- def add_breadcrumb(breadcrumb)
83
- get_current_scope.breadcrumbs.record(breadcrumb)
84
- end
85
-
86
- # Returns the current active hub.
87
- # If the current thread doesn't have an active hub, it will clone the main thread's active hub,
88
- # stores it in the current thread, and then returns it.
89
- def get_current_hub
90
- # we need to assign a hub to the current thread if it doesn't have one yet
91
- #
92
- # ideally, we should do this proactively whenever a new thread is created
93
- # but it's impossible for the SDK to keep track every new thread
94
- # so we need to use this rather passive way to make sure the app doesn't crash
95
- Thread.current[THREAD_LOCAL] || clone_hub_to_current_thread
96
- end
97
-
98
- # Returns the current active client.
99
- def get_current_client
100
- get_current_hub&.current_client
101
- end
102
-
103
- # Returns the current active scope.
104
- def get_current_scope
105
- get_current_hub&.current_scope
106
- end
107
-
108
- # Clones the main thread's active hub and stores it to the current thread.
109
- def clone_hub_to_current_thread
110
- Thread.current[THREAD_LOCAL] = get_main_hub.clone
111
- end
112
-
113
- # Takes a block and yields the current active scope.
114
- #
115
- # ```ruby
116
- # Sentry.configure_scope do |scope|
117
- # scope.set_tags(foo: "bar")
118
- # end
119
- #
120
- # Sentry.capture_message("test message") # this event will have tags { foo: "bar" }
121
- # ```
122
- #
123
- def configure_scope(&block)
124
- get_current_hub&.configure_scope(&block)
125
- end
126
-
127
- # Takes a block and yields a temporary scope.
128
- # The temporary scope will inherit all the attributes from the current active scope and replace it to be the active
129
- # scope inside the block. For example:
130
- #
131
- # ```ruby
132
- # Sentry.configure_scope do |scope|
133
- # scope.set_tags(foo: "bar")
134
- # end
135
- #
136
- # Sentry.capture_message("test message") # this event will have tags { foo: "bar" }
137
- #
138
- # Sentry.with_scope do |temp_scope|
139
- # temp_scope.set_tags(foo: "baz")
140
- # Sentry.capture_message("test message 2") # this event will have tags { foo: "baz" }
141
- # end
142
- #
143
- # Sentry.capture_message("test message 3") # this event will have tags { foo: "bar" }
144
- # ```
145
- #
146
- def with_scope(&block)
147
- get_current_hub&.with_scope(&block)
148
- end
149
-
150
- # Takes an exception and reports it to Sentry via the currently active hub.
151
- def capture_exception(exception, **options, &block)
152
- get_current_hub&.capture_exception(exception, **options, &block)
153
- end
154
-
155
- # Takes a message string and reports it to Sentry via the currently active hub.
156
- def capture_message(message, **options, &block)
157
- get_current_hub&.capture_message(message, **options, &block)
158
- end
159
-
160
- # Takes an instance of Sentry::Event and dispatches it to the currently active hub.
161
- def capture_event(event)
162
- get_current_hub&.capture_event(event)
163
- end
164
-
165
- # Takes or initializes a new Sentry::Transaction and makes a sampling decision for it.
166
- def start_transaction(**options)
167
- get_current_hub&.start_transaction(**options)
168
- end
169
-
170
- # Returns the id of the lastly reported Sentry::Event.
171
- def last_event_id
172
- get_current_hub&.last_event_id
173
- end
174
-
175
- def sys_command(command)
176
- result = `#{command} 2>&1` rescue nil
177
- return if result.nil? || result.empty? || ($CHILD_STATUS && $CHILD_STATUS.exitstatus != 0)
178
-
179
- result.strip
180
- end
181
-
182
- def initialized?
183
- !!@main_hub
184
- end
185
-
186
- def logger
187
- configuration.logger
188
- end
189
- end
190
- end
@@ -1,37 +0,0 @@
1
- require "concurrent/executor/thread_pool_executor"
2
- require "concurrent/executor/immediate_executor"
3
-
4
- module Sentry
5
- class BackgroundWorker
6
- attr_reader :max_queue, :number_of_threads
7
-
8
- def initialize(configuration)
9
- @max_queue = 30
10
- @number_of_threads = configuration.background_worker_threads
11
-
12
- @executor =
13
- if configuration.async
14
- configuration.logger.debug(LOGGER_PROGNAME) { "config.async is set, BackgroundWorker is disabled" }
15
- Concurrent::ImmediateExecutor.new
16
- elsif @number_of_threads == 0
17
- configuration.logger.debug(LOGGER_PROGNAME) { "config.background_worker_threads is set to 0, all events will be sent synchronously" }
18
- Concurrent::ImmediateExecutor.new
19
- else
20
- configuration.logger.debug(LOGGER_PROGNAME) { "initialized a background worker with #{@number_of_threads} threads" }
21
-
22
- Concurrent::ThreadPoolExecutor.new(
23
- min_threads: 0,
24
- max_threads: @number_of_threads,
25
- max_queue: @max_queue,
26
- fallback_policy: :discard
27
- )
28
- end
29
- end
30
-
31
- def perform(&block)
32
- @executor.post do
33
- block.call
34
- end
35
- end
36
- end
37
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ## Inspired by Rails' and Airbrake's backtrace parsers.
4
-
5
- module Sentry
6
- # Front end to parsing the backtrace for each notice
7
- class Backtrace
8
- # Handles backtrace parsing line by line
9
- class Line
10
- RB_EXTENSION = ".rb"
11
- # regexp (optional leading X: on windows, or JRuby9000 class-prefix)
12
- RUBY_INPUT_FORMAT = /
13
- ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
14
- (\d+)
15
- (?: :in \s `([^']+)')?$
16
- /x.freeze
17
-
18
- # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
19
- JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/.freeze
20
-
21
- # The file portion of the line (such as app/models/user.rb)
22
- attr_reader :file
23
-
24
- # The line number portion of the line
25
- attr_reader :number
26
-
27
- # The method of the line (such as index)
28
- attr_reader :method
29
-
30
- # The module name (JRuby)
31
- attr_reader :module_name
32
-
33
- attr_reader :in_app_pattern
34
-
35
- # Parses a single line of a given backtrace
36
- # @param [String] unparsed_line The raw line from +caller+ or some backtrace
37
- # @return [Line] The parsed backtrace line
38
- def self.parse(unparsed_line, in_app_pattern)
39
- ruby_match = unparsed_line.match(RUBY_INPUT_FORMAT)
40
- if ruby_match
41
- _, file, number, method = ruby_match.to_a
42
- file.sub!(/\.class$/, RB_EXTENSION)
43
- module_name = nil
44
- else
45
- java_match = unparsed_line.match(JAVA_INPUT_FORMAT)
46
- _, module_name, method, file, number = java_match.to_a
47
- end
48
- new(file, number, method, module_name, in_app_pattern)
49
- end
50
-
51
- def initialize(file, number, method, module_name, in_app_pattern)
52
- @file = file
53
- @module_name = module_name
54
- @number = number.to_i
55
- @method = method
56
- @in_app_pattern = in_app_pattern
57
- end
58
-
59
- def in_app
60
- if file =~ in_app_pattern
61
- true
62
- else
63
- false
64
- end
65
- end
66
-
67
- # Reconstructs the line in a readable fashion
68
- def to_s
69
- "#{file}:#{number}:in `#{method}'"
70
- end
71
-
72
- def ==(other)
73
- to_s == other.to_s
74
- end
75
-
76
- def inspect
77
- "<Line:#{self}>"
78
- end
79
- end
80
-
81
- APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test)/.freeze
82
-
83
- # holder for an Array of Backtrace::Line instances
84
- attr_reader :lines
85
-
86
- def self.parse(backtrace, project_root, app_dirs_pattern, &backtrace_cleanup_callback)
87
- ruby_lines = backtrace.is_a?(Array) ? backtrace : backtrace.split(/\n\s*/)
88
-
89
- ruby_lines = backtrace_cleanup_callback.call(ruby_lines) if backtrace_cleanup_callback
90
-
91
- in_app_pattern ||= begin
92
- Regexp.new("^(#{project_root}/)?#{app_dirs_pattern || APP_DIRS_PATTERN}")
93
- end
94
-
95
- lines = ruby_lines.to_a.map do |unparsed_line|
96
- Line.parse(unparsed_line, in_app_pattern)
97
- end
98
-
99
- new(lines)
100
- end
101
-
102
- def initialize(lines)
103
- @lines = lines
104
- end
105
-
106
- def inspect
107
- "<Backtrace: " + lines.map(&:inspect).join(", ") + ">"
108
- end
109
-
110
- def to_s
111
- content = []
112
- lines.each do |line|
113
- content << line
114
- end
115
- content.join("\n")
116
- end
117
-
118
- def ==(other)
119
- if other.respond_to?(:lines)
120
- lines == other.lines
121
- else
122
- false
123
- end
124
- end
125
- end
126
- end
@@ -1,14 +0,0 @@
1
- module Sentry
2
- class BenchmarkTransport < Transport
3
- attr_accessor :events
4
-
5
- def initialize(*)
6
- super
7
- @events = []
8
- end
9
-
10
- def send_event(event)
11
- @events << encode(event.to_hash)
12
- end
13
- end
14
- end
@@ -1,25 +0,0 @@
1
- module Sentry
2
- class Breadcrumb
3
- attr_accessor :category, :data, :message, :level, :timestamp, :type
4
-
5
- def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
6
- @category = category
7
- @data = data || {}
8
- @level = level
9
- @message = message
10
- @timestamp = timestamp || Sentry.utc_now.to_i
11
- @type = type
12
- end
13
-
14
- def to_hash
15
- {
16
- :category => @category,
17
- :data => @data,
18
- :level => @level,
19
- :message => @message,
20
- :timestamp => @timestamp,
21
- :type => @type
22
- }
23
- end
24
- end
25
- end
@@ -1,87 +0,0 @@
1
- require 'logger'
2
-
3
- module Sentry
4
- class Breadcrumb
5
- module SentryLogger
6
- LEVELS = {
7
- ::Logger::DEBUG => 'debug',
8
- ::Logger::INFO => 'info',
9
- ::Logger::WARN => 'warn',
10
- ::Logger::ERROR => 'error',
11
- ::Logger::FATAL => 'fatal'
12
- }.freeze
13
-
14
- def add(*args, &block)
15
- super
16
- add_breadcrumb(*args, &block)
17
- end
18
-
19
- def add_breadcrumb(severity, message = nil, progname = nil)
20
- # because the breadcrumbs now belongs to different Hub's Scope in different threads
21
- # we need to make sure the current thread's Hub has been set before adding breadcrumbs
22
- return unless Sentry.get_current_hub
23
-
24
- category = "logger"
25
-
26
- # this is because the nature of Ruby Logger class:
27
- #
28
- # when given 1 argument, the argument will become both message and progname
29
- #
30
- # ```
31
- # logger.info("foo")
32
- # # message == progname == "foo"
33
- # ```
34
- #
35
- # and to specify progname with a different message,
36
- # we need to pass the progname as the argument and pass the message as a proc
37
- #
38
- # ```
39
- # logger.info("progname") { "the message" }
40
- # ```
41
- #
42
- # so the condition below is to replicate the similar behavior
43
- if message.nil?
44
- if block_given?
45
- message = yield
46
- category = progname
47
- else
48
- message = progname
49
- end
50
- end
51
-
52
- return if ignored_logger?(progname) || message.empty?
53
-
54
- # some loggers will add leading/trailing space as they (incorrectly, mind you)
55
- # think of logging as a shortcut to std{out,err}
56
- message = message.to_s.strip
57
-
58
- last_crumb = current_breadcrumbs.peek
59
- # try to avoid dupes from logger broadcasts
60
- if last_crumb.nil? || last_crumb.message != message
61
- level = Sentry::Breadcrumb::SentryLogger::LEVELS.fetch(severity, nil)
62
- crumb = Sentry::Breadcrumb.new(
63
- level: level,
64
- category: category,
65
- message: message,
66
- type: severity >= 3 ? "error" : level
67
- )
68
-
69
- Sentry.add_breadcrumb(crumb)
70
- end
71
- end
72
-
73
- private
74
-
75
- def ignored_logger?(progname)
76
- progname == LOGGER_PROGNAME ||
77
- Sentry.configuration.exclude_loggers.include?(progname)
78
- end
79
-
80
- def current_breadcrumbs
81
- Sentry.get_current_scope.breadcrumbs
82
- end
83
- end
84
- end
85
- end
86
-
87
- ::Logger.send(:prepend, Sentry::Breadcrumb::SentryLogger)