sentry-ruby 0.1.3 → 4.1.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/CHANGELOG.md +69 -0
- data/Gemfile +6 -1
- data/README.md +88 -8
- data/Rakefile +3 -1
- data/lib/sentry-ruby.rb +38 -3
- data/lib/sentry/background_worker.rb +37 -0
- data/lib/sentry/benchmarks/benchmark_transport.rb +14 -0
- data/lib/sentry/breadcrumb.rb +7 -7
- data/lib/sentry/breadcrumb/sentry_logger.rb +10 -26
- data/lib/sentry/breadcrumb_buffer.rb +2 -5
- data/lib/sentry/client.rb +25 -7
- data/lib/sentry/configuration.rb +88 -87
- data/lib/sentry/dsn.rb +6 -3
- data/lib/sentry/event.rb +32 -26
- data/lib/sentry/hub.rb +13 -2
- data/lib/sentry/interfaces/request.rb +1 -31
- data/lib/sentry/rack.rb +2 -2
- data/lib/sentry/rack/{capture_exception.rb → capture_exceptions.rb} +20 -11
- data/lib/sentry/rack/interface.rb +22 -0
- data/lib/sentry/rake.rb +17 -0
- data/lib/sentry/scope.rb +27 -5
- data/lib/sentry/span.rb +132 -0
- data/lib/sentry/transaction.rb +157 -0
- data/lib/sentry/transaction_event.rb +29 -0
- data/lib/sentry/transport.rb +16 -24
- data/lib/sentry/transport/http_transport.rb +8 -8
- data/lib/sentry/utils/request_id.rb +16 -0
- data/lib/sentry/version.rb +1 -1
- data/sentry-ruby.gemspec +1 -0
- metadata +25 -4
- data/lib/sentry/transport/state.rb +0 -40
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
class TransactionEvent < Event
|
5
|
+
ATTRIBUTES = %i(
|
6
|
+
event_id level timestamp start_timestamp
|
7
|
+
release environment server_name modules
|
8
|
+
user tags contexts extra
|
9
|
+
transaction platform sdk type
|
10
|
+
)
|
11
|
+
|
12
|
+
attr_accessor(*ATTRIBUTES)
|
13
|
+
attr_accessor :spans
|
14
|
+
|
15
|
+
def start_timestamp=(time)
|
16
|
+
@start_timestamp = time.is_a?(Time) ? time.to_f : time
|
17
|
+
end
|
18
|
+
|
19
|
+
def type
|
20
|
+
"transaction"
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
data = super
|
25
|
+
data[:spans] = @spans.map(&:to_hash) if @spans
|
26
|
+
data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
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,20 +19,25 @@ 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)
|
36
|
+
nil
|
35
37
|
end
|
36
38
|
|
37
39
|
def generate_auth_header
|
38
|
-
now =
|
40
|
+
now = Sentry.utc_now.to_i
|
39
41
|
fields = {
|
40
42
|
'sentry_version' => PROTOCOL_VERSION,
|
41
43
|
'sentry_client' => USER_AGENT,
|
@@ -48,14 +50,15 @@ module Sentry
|
|
48
50
|
|
49
51
|
def encode(event_hash)
|
50
52
|
event_id = event_hash[:event_id] || event_hash['event_id']
|
53
|
+
event_type = event_hash[:type] || event_hash['type']
|
51
54
|
|
52
55
|
envelope = <<~ENVELOPE
|
53
|
-
{"event_id":"#{event_id}","dsn":"#{configuration.dsn.to_s}","sdk":#{Sentry.sdk_meta.to_json},"sent_at":"#{
|
54
|
-
{"type":"
|
55
|
-
#{event_hash
|
56
|
+
{"event_id":"#{event_id}","dsn":"#{configuration.dsn.to_s}","sdk":#{Sentry.sdk_meta.to_json},"sent_at":"#{Sentry.utc_now.iso8601}"}
|
57
|
+
{"type":"#{event_type}","content_type":"application/json"}
|
58
|
+
#{JSON.generate(event_hash)}
|
56
59
|
ENVELOPE
|
57
60
|
|
58
|
-
|
61
|
+
envelope
|
59
62
|
end
|
60
63
|
|
61
64
|
private
|
@@ -64,29 +67,18 @@ module Sentry
|
|
64
67
|
# Convert to hash
|
65
68
|
event_hash = event.to_hash
|
66
69
|
|
67
|
-
unless @state.should_try?
|
68
|
-
failed_for_previous_failure(event_hash)
|
69
|
-
return
|
70
|
-
end
|
71
|
-
|
72
70
|
event_id = event_hash[:event_id] || event_hash['event_id']
|
73
71
|
configuration.logger.info(LOGGER_PROGNAME) { "Sending event #{event_id} to Sentry" }
|
74
72
|
encode(event_hash)
|
75
73
|
end
|
76
74
|
|
77
75
|
def failed_for_exception(e, event)
|
78
|
-
@state.failure
|
79
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")}" }
|
80
77
|
log_not_sending(event)
|
81
78
|
end
|
82
79
|
|
83
|
-
def failed_for_previous_failure(event)
|
84
|
-
configuration.logger.warn(LOGGER_PROGNAME) { "Not sending event due to previous failure(s)." }
|
85
|
-
log_not_sending(event)
|
86
|
-
end
|
87
|
-
|
88
80
|
def log_not_sending(event)
|
89
|
-
configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event: #{Event.get_log_message(event.to_hash)}" }
|
81
|
+
configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event. Unreported Event: #{Event.get_log_message(event.to_hash)}" }
|
90
82
|
end
|
91
83
|
end
|
92
84
|
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,21 +12,20 @@ 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
|
24
21
|
rescue Faraday::Error => e
|
25
22
|
error_info = e.message
|
26
|
-
|
27
|
-
|
23
|
+
|
24
|
+
if e.response
|
25
|
+
error_info += "\nbody: #{e.response[:body]}"
|
26
|
+
error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}" if e.response[:headers]['x-sentry-error']
|
28
27
|
end
|
28
|
+
|
29
29
|
raise Sentry::Error, error_info
|
30
30
|
end
|
31
31
|
|
@@ -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.0
|
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-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -24,6 +24,20 @@ 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: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: A gem that provides a client interface for the Sentry error logger
|
28
42
|
email: accounts@sentry.io
|
29
43
|
executables: []
|
@@ -45,7 +59,9 @@ files:
|
|
45
59
|
- bin/console
|
46
60
|
- bin/setup
|
47
61
|
- lib/sentry-ruby.rb
|
62
|
+
- lib/sentry/background_worker.rb
|
48
63
|
- lib/sentry/backtrace.rb
|
64
|
+
- lib/sentry/benchmarks/benchmark_transport.rb
|
49
65
|
- lib/sentry/breadcrumb.rb
|
50
66
|
- lib/sentry/breadcrumb/sentry_logger.rb
|
51
67
|
- lib/sentry/breadcrumb_buffer.rb
|
@@ -64,15 +80,20 @@ files:
|
|
64
80
|
- lib/sentry/linecache.rb
|
65
81
|
- lib/sentry/logger.rb
|
66
82
|
- lib/sentry/rack.rb
|
67
|
-
- lib/sentry/rack/
|
83
|
+
- lib/sentry/rack/capture_exceptions.rb
|
84
|
+
- lib/sentry/rack/interface.rb
|
85
|
+
- lib/sentry/rake.rb
|
68
86
|
- lib/sentry/scope.rb
|
87
|
+
- lib/sentry/span.rb
|
88
|
+
- lib/sentry/transaction.rb
|
89
|
+
- lib/sentry/transaction_event.rb
|
69
90
|
- lib/sentry/transport.rb
|
70
91
|
- lib/sentry/transport/configuration.rb
|
71
92
|
- lib/sentry/transport/dummy_transport.rb
|
72
93
|
- lib/sentry/transport/http_transport.rb
|
73
|
-
- lib/sentry/transport/state.rb
|
74
94
|
- lib/sentry/utils/exception_cause_chain.rb
|
75
95
|
- lib/sentry/utils/real_ip.rb
|
96
|
+
- lib/sentry/utils/request_id.rb
|
76
97
|
- lib/sentry/version.rb
|
77
98
|
- sentry-ruby.gemspec
|
78
99
|
homepage: https://github.com/getsentry/raven-ruby
|
@@ -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 Time.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 = Time.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
|