sentry-ruby 0.2.0 → 4.1.1
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/CHANGELOG.md +70 -0
- data/Gemfile +1 -1
- data/README.md +88 -8
- data/lib/sentry-ruby.rb +36 -12
- data/lib/sentry/background_worker.rb +37 -0
- data/lib/sentry/breadcrumb.rb +7 -7
- data/lib/sentry/breadcrumb/sentry_logger.rb +10 -12
- data/lib/sentry/breadcrumb_buffer.rb +2 -5
- data/lib/sentry/client.rb +14 -8
- data/lib/sentry/configuration.rb +25 -38
- data/lib/sentry/event.rb +10 -6
- data/lib/sentry/hub.rb +7 -2
- data/lib/sentry/interfaces/request.rb +1 -31
- data/lib/sentry/rack.rb +3 -3
- data/lib/sentry/rack/{capture_exception.rb → capture_exceptions.rb} +20 -11
- data/lib/sentry/rack/deprecations.rb +19 -0
- data/lib/sentry/rack/interface.rb +22 -0
- data/lib/sentry/rake.rb +17 -0
- data/lib/sentry/scope.rb +5 -5
- data/lib/sentry/span.rb +12 -26
- data/lib/sentry/transaction.rb +44 -0
- data/lib/sentry/transport.rb +9 -19
- data/lib/sentry/transport/http_transport.rb +3 -6
- data/lib/sentry/utils/request_id.rb +16 -0
- data/lib/sentry/version.rb +1 -1
- data/sentry-ruby.gemspec +1 -0
- metadata +28 -5
- data/lib/sentry/rack/tracing.rb +0 -39
- data/lib/sentry/transport/state.rb +0 -40
data/lib/sentry/rake.rb
ADDED
@@ -0,0 +1,17 @@
|
|
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
|
data/lib/sentry/scope.rb
CHANGED
@@ -15,7 +15,7 @@ module Sentry
|
|
15
15
|
set_default_value
|
16
16
|
end
|
17
17
|
|
18
|
-
def apply_to_event(event)
|
18
|
+
def apply_to_event(event, hint = nil)
|
19
19
|
event.tags = tags.merge(event.tags)
|
20
20
|
event.user = user.merge(event.user)
|
21
21
|
event.extra = extra.merge(event.extra)
|
@@ -26,14 +26,14 @@ module Sentry
|
|
26
26
|
end
|
27
27
|
|
28
28
|
event.fingerprint = fingerprint
|
29
|
-
event.level
|
29
|
+
event.level = level
|
30
30
|
event.transaction = transaction_names.last
|
31
31
|
event.breadcrumbs = breadcrumbs
|
32
|
-
event.rack_env = rack_env
|
32
|
+
event.rack_env = rack_env if rack_env
|
33
33
|
|
34
34
|
unless @event_processors.empty?
|
35
35
|
@event_processors.each do |processor_block|
|
36
|
-
event = processor_block.call(event)
|
36
|
+
event = processor_block.call(event, hint)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -57,7 +57,7 @@ module Sentry
|
|
57
57
|
copy.user = user.deep_dup
|
58
58
|
copy.transaction_names = transaction_names.deep_dup
|
59
59
|
copy.fingerprint = fingerprint.deep_dup
|
60
|
-
copy.span = span
|
60
|
+
copy.span = span.deep_dup
|
61
61
|
copy
|
62
62
|
end
|
63
63
|
|
data/lib/sentry/span.rb
CHANGED
@@ -35,16 +35,12 @@ module Sentry
|
|
35
35
|
@tags = {}
|
36
36
|
end
|
37
37
|
|
38
|
-
def set_span_recorder
|
39
|
-
@span_recorder = SpanRecorder.new(1000)
|
40
|
-
@span_recorder.add(self)
|
41
|
-
end
|
42
|
-
|
43
38
|
def finish
|
44
39
|
# already finished
|
45
40
|
return if @timestamp
|
46
41
|
|
47
42
|
@timestamp = Sentry.utc_now.to_f
|
43
|
+
self
|
48
44
|
end
|
49
45
|
|
50
46
|
def to_sentry_trace
|
@@ -81,14 +77,19 @@ module Sentry
|
|
81
77
|
|
82
78
|
def start_child(**options)
|
83
79
|
options = options.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
|
84
|
-
|
85
|
-
|
80
|
+
Span.new(options)
|
81
|
+
end
|
86
82
|
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
def with_child_span(**options, &block)
|
84
|
+
child_span = start_child(**options)
|
85
|
+
|
86
|
+
yield(child_span)
|
87
|
+
|
88
|
+
child_span.finish
|
89
|
+
end
|
90
90
|
|
91
|
-
|
91
|
+
def deep_dup
|
92
|
+
dup
|
92
93
|
end
|
93
94
|
|
94
95
|
def set_op(op)
|
@@ -127,20 +128,5 @@ module Sentry
|
|
127
128
|
def set_tag(key, value)
|
128
129
|
@tags[key] = value
|
129
130
|
end
|
130
|
-
|
131
|
-
class SpanRecorder
|
132
|
-
attr_reader :max_length, :spans
|
133
|
-
|
134
|
-
def initialize(max_length)
|
135
|
-
@max_length = max_length
|
136
|
-
@spans = []
|
137
|
-
end
|
138
|
-
|
139
|
-
def add(span)
|
140
|
-
if @spans.count < @max_length
|
141
|
-
@spans << span
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
131
|
end
|
146
132
|
end
|
data/lib/sentry/transaction.rb
CHANGED
@@ -20,6 +20,11 @@ module Sentry
|
|
20
20
|
set_span_recorder
|
21
21
|
end
|
22
22
|
|
23
|
+
def set_span_recorder
|
24
|
+
@span_recorder = SpanRecorder.new(1000)
|
25
|
+
@span_recorder.add(self)
|
26
|
+
end
|
27
|
+
|
23
28
|
def self.from_sentry_trace(sentry_trace, **options)
|
24
29
|
return unless sentry_trace
|
25
30
|
|
@@ -37,6 +42,30 @@ module Sentry
|
|
37
42
|
hash
|
38
43
|
end
|
39
44
|
|
45
|
+
def start_child(**options)
|
46
|
+
child_span = super
|
47
|
+
child_span.span_recorder = @span_recorder
|
48
|
+
|
49
|
+
if @sampled
|
50
|
+
@span_recorder.add(child_span)
|
51
|
+
end
|
52
|
+
|
53
|
+
child_span
|
54
|
+
end
|
55
|
+
|
56
|
+
def deep_dup
|
57
|
+
copy = super
|
58
|
+
copy.set_span_recorder
|
59
|
+
|
60
|
+
@span_recorder.spans.each do |span|
|
61
|
+
# span_recorder's first span is the current span, which should not be added to the copy's spans
|
62
|
+
next if span == self
|
63
|
+
copy.span_recorder.add(span.dup)
|
64
|
+
end
|
65
|
+
|
66
|
+
copy
|
67
|
+
end
|
68
|
+
|
40
69
|
def set_initial_sample_desicion(sampling_context = {})
|
41
70
|
unless Sentry.configuration.tracing_enabled?
|
42
71
|
@sampled = false
|
@@ -109,5 +138,20 @@ module Sentry
|
|
109
138
|
result += " <#{@name}>" if @name
|
110
139
|
result
|
111
140
|
end
|
141
|
+
|
142
|
+
class SpanRecorder
|
143
|
+
attr_reader :max_length, :spans
|
144
|
+
|
145
|
+
def initialize(max_length)
|
146
|
+
@max_length = max_length
|
147
|
+
@spans = []
|
148
|
+
end
|
149
|
+
|
150
|
+
def add(span)
|
151
|
+
if @spans.count < @max_length
|
152
|
+
@spans << span
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
112
156
|
end
|
113
157
|
end
|
data/lib/sentry/transport.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
require "json"
|
2
2
|
require "base64"
|
3
|
-
require "sentry/transport/state"
|
4
3
|
|
5
4
|
module Sentry
|
6
5
|
class Transport
|
7
6
|
PROTOCOL_VERSION = '5'
|
8
7
|
USER_AGENT = "sentry-ruby/#{Sentry::VERSION}"
|
9
|
-
CONTENT_TYPE = 'application/json'
|
10
8
|
|
11
|
-
attr_accessor :configuration
|
9
|
+
attr_accessor :configuration
|
12
10
|
|
13
11
|
def initialize(configuration)
|
14
12
|
@configuration = configuration
|
15
13
|
@transport_configuration = configuration.transport
|
16
14
|
@dsn = configuration.dsn
|
17
|
-
@state = State.new
|
18
15
|
end
|
19
16
|
|
20
17
|
def send_data(data, options = {})
|
@@ -22,13 +19,17 @@ module Sentry
|
|
22
19
|
end
|
23
20
|
|
24
21
|
def send_event(event)
|
25
|
-
|
22
|
+
unless configuration.sending_allowed?
|
23
|
+
configuration.logger.debug(LOGGER_PROGNAME) { "Event not sent: #{configuration.error_messages}" }
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
encoded_data = prepare_encoded_event(event)
|
26
28
|
|
27
29
|
return nil unless encoded_data
|
28
30
|
|
29
|
-
send_data(encoded_data
|
31
|
+
send_data(encoded_data)
|
30
32
|
|
31
|
-
state.success
|
32
33
|
event
|
33
34
|
rescue => e
|
34
35
|
failed_for_exception(e, event)
|
@@ -57,7 +58,7 @@ module Sentry
|
|
57
58
|
#{JSON.generate(event_hash)}
|
58
59
|
ENVELOPE
|
59
60
|
|
60
|
-
|
61
|
+
envelope
|
61
62
|
end
|
62
63
|
|
63
64
|
private
|
@@ -66,27 +67,16 @@ module Sentry
|
|
66
67
|
# Convert to hash
|
67
68
|
event_hash = event.to_hash
|
68
69
|
|
69
|
-
unless @state.should_try?
|
70
|
-
failed_for_previous_failure(event_hash)
|
71
|
-
return
|
72
|
-
end
|
73
|
-
|
74
70
|
event_id = event_hash[:event_id] || event_hash['event_id']
|
75
71
|
configuration.logger.info(LOGGER_PROGNAME) { "Sending event #{event_id} to Sentry" }
|
76
72
|
encode(event_hash)
|
77
73
|
end
|
78
74
|
|
79
75
|
def failed_for_exception(e, event)
|
80
|
-
@state.failure
|
81
76
|
configuration.logger.warn(LOGGER_PROGNAME) { "Unable to record event with remote Sentry server (#{e.class} - #{e.message}):\n#{e.backtrace[0..10].join("\n")}" }
|
82
77
|
log_not_sending(event)
|
83
78
|
end
|
84
79
|
|
85
|
-
def failed_for_previous_failure(event)
|
86
|
-
configuration.logger.warn(LOGGER_PROGNAME) { "Not sending event due to previous failure(s)." }
|
87
|
-
log_not_sending(event)
|
88
|
-
end
|
89
|
-
|
90
80
|
def log_not_sending(event)
|
91
81
|
configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event. Unreported Event: #{Event.get_log_message(event.to_hash)}" }
|
92
82
|
end
|
@@ -2,6 +2,7 @@ require 'faraday'
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class HTTPTransport < Transport
|
5
|
+
CONTENT_TYPE = 'application/json'
|
5
6
|
attr_reader :conn, :adapter
|
6
7
|
|
7
8
|
def initialize(*args)
|
@@ -11,13 +12,9 @@ module Sentry
|
|
11
12
|
@endpoint = @dsn.envelope_endpoint
|
12
13
|
end
|
13
14
|
|
14
|
-
def send_data(data
|
15
|
-
unless configuration.sending_allowed?
|
16
|
-
logger.debug(LOGGER_PROGNAME) { "Event not sent: #{configuration.error_messages}" }
|
17
|
-
end
|
18
|
-
|
15
|
+
def send_data(data)
|
19
16
|
conn.post @endpoint do |req|
|
20
|
-
req.headers['Content-Type'] =
|
17
|
+
req.headers['Content-Type'] = CONTENT_TYPE
|
21
18
|
req.headers['X-Sentry-Auth'] = generate_auth_header
|
22
19
|
req.body = data
|
23
20
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sentry
|
2
|
+
module Utils
|
3
|
+
module RequestId
|
4
|
+
REQUEST_ID_HEADERS = %w(action_dispatch.request_id HTTP_X_REQUEST_ID).freeze
|
5
|
+
|
6
|
+
# Request ID based on ActionDispatch::RequestId
|
7
|
+
def self.read_from(env_hash)
|
8
|
+
REQUEST_ID_HEADERS.each do |key|
|
9
|
+
request_id = env_hash[key]
|
10
|
+
return request_id if request_id
|
11
|
+
end
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/sentry/version.rb
CHANGED
data/sentry-ruby.gemspec
CHANGED
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:
|
4
|
+
version: 4.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sentry Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -24,6 +24,26 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: concurrent-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.0.2
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.0'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.0.2
|
27
47
|
description: A gem that provides a client interface for the Sentry error logger
|
28
48
|
email: accounts@sentry.io
|
29
49
|
executables: []
|
@@ -45,6 +65,7 @@ files:
|
|
45
65
|
- bin/console
|
46
66
|
- bin/setup
|
47
67
|
- lib/sentry-ruby.rb
|
68
|
+
- lib/sentry/background_worker.rb
|
48
69
|
- lib/sentry/backtrace.rb
|
49
70
|
- lib/sentry/benchmarks/benchmark_transport.rb
|
50
71
|
- lib/sentry/breadcrumb.rb
|
@@ -65,8 +86,10 @@ files:
|
|
65
86
|
- lib/sentry/linecache.rb
|
66
87
|
- lib/sentry/logger.rb
|
67
88
|
- lib/sentry/rack.rb
|
68
|
-
- lib/sentry/rack/
|
69
|
-
- lib/sentry/rack/
|
89
|
+
- lib/sentry/rack/capture_exceptions.rb
|
90
|
+
- lib/sentry/rack/deprecations.rb
|
91
|
+
- lib/sentry/rack/interface.rb
|
92
|
+
- lib/sentry/rake.rb
|
70
93
|
- lib/sentry/scope.rb
|
71
94
|
- lib/sentry/span.rb
|
72
95
|
- lib/sentry/transaction.rb
|
@@ -75,9 +98,9 @@ files:
|
|
75
98
|
- lib/sentry/transport/configuration.rb
|
76
99
|
- lib/sentry/transport/dummy_transport.rb
|
77
100
|
- lib/sentry/transport/http_transport.rb
|
78
|
-
- lib/sentry/transport/state.rb
|
79
101
|
- lib/sentry/utils/exception_cause_chain.rb
|
80
102
|
- lib/sentry/utils/real_ip.rb
|
103
|
+
- lib/sentry/utils/request_id.rb
|
81
104
|
- lib/sentry/version.rb
|
82
105
|
- sentry-ruby.gemspec
|
83
106
|
homepage: https://github.com/getsentry/raven-ruby
|
data/lib/sentry/rack/tracing.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
module Rack
|
3
|
-
class Tracing
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
Sentry.clone_hub_to_current_thread unless Sentry.get_current_hub
|
10
|
-
|
11
|
-
if Sentry.configuration.traces_sample_rate.to_f == 0.0
|
12
|
-
return @app.call(env)
|
13
|
-
end
|
14
|
-
|
15
|
-
Sentry.with_scope do |scope|
|
16
|
-
scope.clear_breadcrumbs
|
17
|
-
scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
|
18
|
-
span = Sentry.start_transaction(name: scope.transaction_name, op: "rack.request")
|
19
|
-
scope.set_span(span)
|
20
|
-
|
21
|
-
begin
|
22
|
-
response = @app.call(env)
|
23
|
-
rescue
|
24
|
-
finish_span(span, 500)
|
25
|
-
raise
|
26
|
-
end
|
27
|
-
|
28
|
-
finish_span(span, response[0])
|
29
|
-
response
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def finish_span(span, status_code)
|
34
|
-
span.set_http_status(status_code)
|
35
|
-
span.finish
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
class Transport
|
3
|
-
class State
|
4
|
-
def initialize
|
5
|
-
reset
|
6
|
-
end
|
7
|
-
|
8
|
-
def should_try?
|
9
|
-
return true if @status == :online
|
10
|
-
|
11
|
-
interval = @retry_after || [@retry_number, 6].min**2
|
12
|
-
return true if Sentry.utc_now - @last_check >= interval
|
13
|
-
|
14
|
-
false
|
15
|
-
end
|
16
|
-
|
17
|
-
def failure(retry_after = nil)
|
18
|
-
@status = :error
|
19
|
-
@retry_number += 1
|
20
|
-
@last_check = Sentry.utc_now
|
21
|
-
@retry_after = retry_after
|
22
|
-
end
|
23
|
-
|
24
|
-
def success
|
25
|
-
reset
|
26
|
-
end
|
27
|
-
|
28
|
-
def reset
|
29
|
-
@status = :online
|
30
|
-
@retry_number = 0
|
31
|
-
@last_check = nil
|
32
|
-
@retry_after = nil
|
33
|
-
end
|
34
|
-
|
35
|
-
def failed?
|
36
|
-
@status == :error
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|