sentry-ruby 4.1.0 → 4.1.5.pre.beta.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 +4 -4
- data/README.md +7 -7
- metadata +31 -59
- data/.craft.yml +0 -19
- data/.gitignore +0 -11
- data/.rspec +0 -3
- data/.travis.yml +0 -6
- data/CHANGELOG.md +0 -89
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -16
- data/Rakefile +0 -8
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/lib/sentry-ruby.rb +0 -141
- data/lib/sentry/background_worker.rb +0 -37
- data/lib/sentry/backtrace.rb +0 -128
- data/lib/sentry/benchmarks/benchmark_transport.rb +0 -14
- data/lib/sentry/breadcrumb.rb +0 -25
- data/lib/sentry/breadcrumb/sentry_logger.rb +0 -87
- data/lib/sentry/breadcrumb_buffer.rb +0 -47
- data/lib/sentry/client.rb +0 -86
- data/lib/sentry/configuration.rb +0 -399
- data/lib/sentry/core_ext/object/deep_dup.rb +0 -57
- data/lib/sentry/core_ext/object/duplicable.rb +0 -153
- data/lib/sentry/dsn.rb +0 -48
- data/lib/sentry/event.rb +0 -177
- data/lib/sentry/hub.rb +0 -137
- data/lib/sentry/interface.rb +0 -22
- data/lib/sentry/interfaces/exception.rb +0 -11
- data/lib/sentry/interfaces/request.rb +0 -74
- data/lib/sentry/interfaces/single_exception.rb +0 -14
- data/lib/sentry/interfaces/stacktrace.rb +0 -57
- data/lib/sentry/linecache.rb +0 -44
- data/lib/sentry/logger.rb +0 -20
- data/lib/sentry/rack.rb +0 -4
- data/lib/sentry/rack/capture_exceptions.rb +0 -54
- data/lib/sentry/rack/interface.rb +0 -22
- data/lib/sentry/rake.rb +0 -17
- data/lib/sentry/scope.rb +0 -214
- data/lib/sentry/span.rb +0 -132
- data/lib/sentry/transaction.rb +0 -157
- data/lib/sentry/transaction_event.rb +0 -29
- data/lib/sentry/transport.rb +0 -87
- data/lib/sentry/transport/configuration.rb +0 -21
- data/lib/sentry/transport/dummy_transport.rb +0 -14
- data/lib/sentry/transport/http_transport.rb +0 -62
- data/lib/sentry/utils/exception_cause_chain.rb +0 -20
- data/lib/sentry/utils/real_ip.rb +0 -70
- data/lib/sentry/utils/request_id.rb +0 -16
- data/lib/sentry/version.rb +0 -3
- data/sentry-ruby.gemspec +0 -27
data/bin/setup
DELETED
data/lib/sentry-ruby.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
require "forwardable"
|
2
|
-
require "time"
|
3
|
-
|
4
|
-
require "sentry/version"
|
5
|
-
require "sentry/core_ext/object/deep_dup"
|
6
|
-
require "sentry/configuration"
|
7
|
-
require "sentry/logger"
|
8
|
-
require "sentry/event"
|
9
|
-
require "sentry/transaction_event"
|
10
|
-
require "sentry/span"
|
11
|
-
require "sentry/transaction"
|
12
|
-
require "sentry/hub"
|
13
|
-
require "sentry/background_worker"
|
14
|
-
|
15
|
-
def safely_require(lib)
|
16
|
-
begin
|
17
|
-
require lib
|
18
|
-
rescue LoadError
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
safely_require "sentry/rake"
|
23
|
-
safely_require "sentry/rack"
|
24
|
-
|
25
|
-
module Sentry
|
26
|
-
class Error < StandardError
|
27
|
-
end
|
28
|
-
|
29
|
-
META = { "name" => "sentry.ruby", "version" => Sentry::VERSION }.freeze
|
30
|
-
|
31
|
-
LOGGER_PROGNAME = "sentry".freeze
|
32
|
-
|
33
|
-
THREAD_LOCAL = :sentry_hub
|
34
|
-
|
35
|
-
def self.sdk_meta
|
36
|
-
META
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.utc_now
|
40
|
-
Time.now.utc
|
41
|
-
end
|
42
|
-
|
43
|
-
class << self
|
44
|
-
extend Forwardable
|
45
|
-
|
46
|
-
def_delegators :get_current_scope, :set_tags, :set_extras, :set_user
|
47
|
-
|
48
|
-
attr_accessor :background_worker
|
49
|
-
|
50
|
-
def init(&block)
|
51
|
-
config = Configuration.new
|
52
|
-
yield(config)
|
53
|
-
client = Client.new(config)
|
54
|
-
scope = Scope.new
|
55
|
-
hub = Hub.new(client, scope)
|
56
|
-
Thread.current[THREAD_LOCAL] = hub
|
57
|
-
@main_hub = hub
|
58
|
-
@background_worker = Sentry::BackgroundWorker.new(config)
|
59
|
-
end
|
60
|
-
|
61
|
-
def initialized?
|
62
|
-
!!@main_hub
|
63
|
-
end
|
64
|
-
|
65
|
-
def get_main_hub
|
66
|
-
@main_hub
|
67
|
-
end
|
68
|
-
|
69
|
-
def logger
|
70
|
-
configuration.logger
|
71
|
-
end
|
72
|
-
|
73
|
-
def add_breadcrumb(breadcrumb, &block)
|
74
|
-
get_current_scope.breadcrumbs.record(breadcrumb, &block)
|
75
|
-
end
|
76
|
-
|
77
|
-
def configuration
|
78
|
-
get_current_client.configuration
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_current_client
|
82
|
-
get_current_hub.current_client
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_current_hub
|
86
|
-
# we need to assign a hub to the current thread if it doesn't have one yet
|
87
|
-
#
|
88
|
-
# ideally, we should do this proactively whenever a new thread is created
|
89
|
-
# but it's impossible for the SDK to keep track every new thread
|
90
|
-
# so we need to use this rather passive way to make sure the app doesn't crash
|
91
|
-
Thread.current[THREAD_LOCAL] || clone_hub_to_current_thread
|
92
|
-
end
|
93
|
-
|
94
|
-
def clone_hub_to_current_thread
|
95
|
-
Thread.current[THREAD_LOCAL] = get_main_hub.clone
|
96
|
-
end
|
97
|
-
|
98
|
-
def get_current_scope
|
99
|
-
get_current_hub.current_scope
|
100
|
-
end
|
101
|
-
|
102
|
-
def with_scope(&block)
|
103
|
-
get_current_hub.with_scope(&block)
|
104
|
-
end
|
105
|
-
|
106
|
-
def configure_scope(&block)
|
107
|
-
get_current_hub.configure_scope(&block)
|
108
|
-
end
|
109
|
-
|
110
|
-
def send_event(event)
|
111
|
-
get_current_client.send_event(event)
|
112
|
-
end
|
113
|
-
|
114
|
-
def capture_event(event)
|
115
|
-
get_current_hub.capture_event(event)
|
116
|
-
end
|
117
|
-
|
118
|
-
def capture_exception(exception, **options, &block)
|
119
|
-
get_current_hub.capture_exception(exception, **options, &block)
|
120
|
-
end
|
121
|
-
|
122
|
-
def capture_message(message, **options, &block)
|
123
|
-
get_current_hub.capture_message(message, **options, &block)
|
124
|
-
end
|
125
|
-
|
126
|
-
def start_transaction(**options)
|
127
|
-
get_current_hub.start_transaction(**options)
|
128
|
-
end
|
129
|
-
|
130
|
-
def last_event_id
|
131
|
-
get_current_hub.last_event_id
|
132
|
-
end
|
133
|
-
|
134
|
-
def sys_command(command)
|
135
|
-
result = `#{command} 2>&1` rescue nil
|
136
|
-
return if result.nil? || result.empty? || ($CHILD_STATUS && $CHILD_STATUS.exitstatus != 0)
|
137
|
-
|
138
|
-
result.strip
|
139
|
-
end
|
140
|
-
end
|
141
|
-
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
|
data/lib/sentry/backtrace.rb
DELETED
@@ -1,128 +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
|
-
attr_reader :configuration
|
86
|
-
|
87
|
-
def self.parse(backtrace, configuration:)
|
88
|
-
ruby_lines = backtrace.is_a?(Array) ? backtrace : backtrace.split(/\n\s*/)
|
89
|
-
|
90
|
-
ruby_lines = configuration.backtrace_cleanup_callback.call(ruby_lines) if configuration&.backtrace_cleanup_callback
|
91
|
-
|
92
|
-
in_app_pattern ||= begin
|
93
|
-
project_root = configuration.project_root&.to_s
|
94
|
-
Regexp.new("^(#{project_root}/)?#{configuration.app_dirs_pattern || APP_DIRS_PATTERN}")
|
95
|
-
end
|
96
|
-
|
97
|
-
lines = ruby_lines.to_a.map do |unparsed_line|
|
98
|
-
Line.parse(unparsed_line, in_app_pattern)
|
99
|
-
end
|
100
|
-
|
101
|
-
new(lines)
|
102
|
-
end
|
103
|
-
|
104
|
-
def initialize(lines)
|
105
|
-
@lines = lines
|
106
|
-
end
|
107
|
-
|
108
|
-
def inspect
|
109
|
-
"<Backtrace: " + lines.map(&:inspect).join(", ") + ">"
|
110
|
-
end
|
111
|
-
|
112
|
-
def to_s
|
113
|
-
content = []
|
114
|
-
lines.each do |line|
|
115
|
-
content << line
|
116
|
-
end
|
117
|
-
content.join("\n")
|
118
|
-
end
|
119
|
-
|
120
|
-
def ==(other)
|
121
|
-
if other.respond_to?(:lines)
|
122
|
-
lines == other.lines
|
123
|
-
else
|
124
|
-
false
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
data/lib/sentry/breadcrumb.rb
DELETED
@@ -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)
|