sentry-ruby-core 4.7.2 → 5.0.2
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/.yardopts +2 -0
- data/Gemfile +6 -2
- data/README.md +9 -7
- data/bin/console +5 -1
- data/lib/sentry/background_worker.rb +33 -3
- data/lib/sentry/backtrace.rb +1 -3
- data/lib/sentry/breadcrumb/sentry_logger.rb +2 -0
- data/lib/sentry/breadcrumb.rb +24 -3
- data/lib/sentry/breadcrumb_buffer.rb +16 -0
- data/lib/sentry/client.rb +49 -3
- data/lib/sentry/configuration.rb +139 -114
- data/lib/sentry/core_ext/object/deep_dup.rb +2 -0
- data/lib/sentry/core_ext/object/duplicable.rb +1 -0
- data/lib/sentry/dsn.rb +2 -0
- data/lib/sentry/envelope.rb +26 -0
- data/lib/sentry/event.rb +58 -17
- data/lib/sentry/exceptions.rb +2 -0
- data/lib/sentry/hub.rb +16 -4
- data/lib/sentry/integrable.rb +2 -0
- data/lib/sentry/interface.rb +3 -10
- data/lib/sentry/interfaces/exception.rb +13 -3
- data/lib/sentry/interfaces/request.rb +34 -18
- data/lib/sentry/interfaces/single_exception.rb +31 -0
- data/lib/sentry/interfaces/stacktrace.rb +14 -0
- data/lib/sentry/interfaces/stacktrace_builder.rb +39 -10
- data/lib/sentry/interfaces/threads.rb +12 -2
- data/lib/sentry/linecache.rb +3 -0
- data/lib/sentry/net/http.rb +52 -64
- data/lib/sentry/rack/capture_exceptions.rb +2 -0
- data/lib/sentry/rack.rb +2 -0
- data/lib/sentry/rake.rb +16 -6
- data/lib/sentry/release_detector.rb +39 -0
- data/lib/sentry/scope.rb +75 -5
- data/lib/sentry/span.rb +84 -8
- data/lib/sentry/transaction.rb +48 -10
- data/lib/sentry/transaction_event.rb +8 -0
- data/lib/sentry/transport/configuration.rb +3 -2
- data/lib/sentry/transport/dummy_transport.rb +2 -0
- data/lib/sentry/transport/http_transport.rb +55 -42
- data/lib/sentry/transport.rb +80 -19
- data/lib/sentry/utils/argument_checking_helper.rb +2 -0
- data/lib/sentry/utils/custom_inspection.rb +14 -0
- data/lib/sentry/utils/exception_cause_chain.rb +10 -10
- data/lib/sentry/utils/logging_helper.rb +6 -4
- data/lib/sentry/utils/real_ip.rb +2 -0
- data/lib/sentry/utils/request_id.rb +2 -0
- data/lib/sentry/version.rb +3 -1
- data/lib/sentry-ruby.rb +142 -29
- data/sentry-ruby-core.gemspec +0 -1
- data/sentry-ruby.gemspec +0 -1
- metadata +6 -16
data/lib/sentry/net/http.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "net/http"
|
2
4
|
|
3
5
|
module Sentry
|
6
|
+
# @api private
|
4
7
|
module Net
|
5
8
|
module HTTP
|
6
9
|
OP_NAME = "net.http"
|
@@ -20,90 +23,67 @@ module Sentry
|
|
20
23
|
# end
|
21
24
|
# ```
|
22
25
|
#
|
23
|
-
# So
|
24
|
-
#
|
25
|
-
# 1. #request is called.
|
26
|
-
# - But because the request hasn't started yet, it calls #start (which then calls #do_start)
|
27
|
-
# - At this moment @sentry_span is still nil, so #set_sentry_trace_header returns early
|
28
|
-
# 2. #do_start then creates a new Span and assigns it to @sentry_span
|
29
|
-
# 3. #request is called for the second time.
|
30
|
-
# - This time @sentry_span should present. So #set_sentry_trace_header will set the sentry-trace header on the request object
|
31
|
-
# 4. Once the request finished, it
|
32
|
-
# - Records a breadcrumb if http_logger is set
|
33
|
-
# - Finishes the Span inside @sentry_span and clears the instance variable
|
34
|
-
#
|
26
|
+
# So we're only instrumenting request when `Net::HTTP` is already started
|
35
27
|
def request(req, body = nil, &block)
|
36
|
-
|
28
|
+
return super unless started?
|
29
|
+
|
30
|
+
sentry_span = start_sentry_span
|
31
|
+
set_sentry_trace_header(req, sentry_span)
|
37
32
|
|
38
33
|
super.tap do |res|
|
39
34
|
record_sentry_breadcrumb(req, res)
|
40
|
-
record_sentry_span(req, res)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def do_start
|
45
|
-
super.tap do
|
46
|
-
start_sentry_span
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def do_finish
|
51
|
-
super.tap do
|
52
|
-
finish_sentry_span
|
35
|
+
record_sentry_span(req, res, sentry_span)
|
53
36
|
end
|
54
37
|
end
|
55
38
|
|
56
39
|
private
|
57
40
|
|
58
|
-
def set_sentry_trace_header(req)
|
59
|
-
return unless
|
41
|
+
def set_sentry_trace_header(req, sentry_span)
|
42
|
+
return unless sentry_span
|
60
43
|
|
61
|
-
trace = Sentry.get_current_client.generate_sentry_trace(
|
44
|
+
trace = Sentry.get_current_client.generate_sentry_trace(sentry_span)
|
62
45
|
req[SENTRY_TRACE_HEADER_NAME] = trace if trace
|
63
46
|
end
|
64
47
|
|
65
48
|
def record_sentry_breadcrumb(req, res)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
49
|
+
return unless Sentry.initialized? && Sentry.configuration.breadcrumbs_logger.include?(:http_logger)
|
50
|
+
return if from_sentry_sdk?
|
51
|
+
|
52
|
+
request_info = extract_request_info(req)
|
53
|
+
|
54
|
+
crumb = Sentry::Breadcrumb.new(
|
55
|
+
level: :info,
|
56
|
+
category: OP_NAME,
|
57
|
+
type: :info,
|
58
|
+
data: {
|
59
|
+
status: res.code.to_i,
|
60
|
+
**request_info
|
61
|
+
}
|
62
|
+
)
|
63
|
+
Sentry.add_breadcrumb(crumb)
|
82
64
|
end
|
83
65
|
|
84
|
-
def record_sentry_span(req, res)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
66
|
+
def record_sentry_span(req, res, sentry_span)
|
67
|
+
return unless Sentry.initialized? && sentry_span
|
68
|
+
|
69
|
+
request_info = extract_request_info(req)
|
70
|
+
sentry_span.set_description("#{request_info[:method]} #{request_info[:url]}")
|
71
|
+
sentry_span.set_data(:status, res.code.to_i)
|
72
|
+
finish_sentry_span(sentry_span)
|
90
73
|
end
|
91
74
|
|
92
75
|
def start_sentry_span
|
93
|
-
|
94
|
-
|
95
|
-
|
76
|
+
return unless Sentry.initialized? && transaction = Sentry.get_current_scope.get_transaction
|
77
|
+
return if from_sentry_sdk?
|
78
|
+
return if transaction.sampled == false
|
96
79
|
|
97
|
-
|
98
|
-
@sentry_span = child_span
|
99
|
-
end
|
80
|
+
transaction.start_child(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f)
|
100
81
|
end
|
101
82
|
|
102
|
-
def finish_sentry_span
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
83
|
+
def finish_sentry_span(sentry_span)
|
84
|
+
return unless Sentry.initialized? && sentry_span
|
85
|
+
|
86
|
+
sentry_span.set_timestamp(Sentry.utc_now.to_f)
|
107
87
|
end
|
108
88
|
|
109
89
|
def from_sentry_sdk?
|
@@ -112,9 +92,17 @@ module Sentry
|
|
112
92
|
end
|
113
93
|
|
114
94
|
def extract_request_info(req)
|
115
|
-
uri = req.uri
|
95
|
+
uri = req.uri || URI.parse("#{use_ssl? ? 'https' : 'http'}://#{address}#{req.path}")
|
116
96
|
url = "#{uri.scheme}://#{uri.host}#{uri.path}" rescue uri.to_s
|
117
|
-
|
97
|
+
|
98
|
+
result = { method: req.method, url: url }
|
99
|
+
|
100
|
+
if Sentry.configuration.send_default_pii
|
101
|
+
result[:url] = result[:url] + "?#{uri.query}"
|
102
|
+
result[:body] = req.body
|
103
|
+
end
|
104
|
+
|
105
|
+
result
|
118
106
|
end
|
119
107
|
end
|
120
108
|
end
|
data/lib/sentry/rack.rb
CHANGED
data/lib/sentry/rake.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rake"
|
2
4
|
require "rake/task"
|
3
5
|
|
4
6
|
module Sentry
|
5
7
|
module Rake
|
6
8
|
module Application
|
9
|
+
# @api private
|
7
10
|
def display_error_message(ex)
|
8
|
-
Sentry.capture_exception(ex
|
11
|
+
Sentry.capture_exception(ex) do |scope|
|
9
12
|
task_name = top_level_tasks.join(' ')
|
10
13
|
scope.set_transaction_name(task_name)
|
11
14
|
scope.set_tag("rake_task", task_name)
|
@@ -16,16 +19,23 @@ module Sentry
|
|
16
19
|
end
|
17
20
|
|
18
21
|
module Task
|
22
|
+
# @api private
|
19
23
|
def execute(args=nil)
|
20
24
|
return super unless Sentry.initialized? && Sentry.get_current_hub
|
21
25
|
|
22
|
-
|
23
|
-
super
|
24
|
-
end
|
26
|
+
super
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
|
-
|
31
|
-
Rake
|
32
|
+
# @api private
|
33
|
+
module Rake
|
34
|
+
class Application
|
35
|
+
prepend(Sentry::Rake::Application)
|
36
|
+
end
|
37
|
+
|
38
|
+
class Task
|
39
|
+
prepend(Sentry::Rake::Task)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
# @api private
|
5
|
+
class ReleaseDetector
|
6
|
+
class << self
|
7
|
+
def detect_release(project_root:, running_on_heroku:)
|
8
|
+
detect_release_from_env ||
|
9
|
+
detect_release_from_git ||
|
10
|
+
detect_release_from_capistrano(project_root) ||
|
11
|
+
detect_release_from_heroku(running_on_heroku)
|
12
|
+
end
|
13
|
+
|
14
|
+
def detect_release_from_heroku(running_on_heroku)
|
15
|
+
return unless running_on_heroku
|
16
|
+
ENV['HEROKU_SLUG_COMMIT']
|
17
|
+
end
|
18
|
+
|
19
|
+
def detect_release_from_capistrano(project_root)
|
20
|
+
revision_file = File.join(project_root, 'REVISION')
|
21
|
+
revision_log = File.join(project_root, '..', 'revisions.log')
|
22
|
+
|
23
|
+
if File.exist?(revision_file)
|
24
|
+
File.read(revision_file).strip
|
25
|
+
elsif File.exist?(revision_log)
|
26
|
+
File.open(revision_log).to_a.last.strip.sub(/.*as release ([0-9]+).*/, '\1')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def detect_release_from_git
|
31
|
+
Sentry.sys_command("git rev-parse --short HEAD") if File.directory?(".git")
|
32
|
+
end
|
33
|
+
|
34
|
+
def detect_release_from_env
|
35
|
+
ENV['SENTRY_RELEASE']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/sentry/scope.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "sentry/breadcrumb_buffer"
|
2
4
|
require "etc"
|
3
5
|
|
@@ -9,15 +11,22 @@ module Sentry
|
|
9
11
|
|
10
12
|
attr_reader(*ATTRIBUTES)
|
11
13
|
|
14
|
+
# @param max_breadcrumbs [Integer] the maximum number of breadcrumbs to be stored in the scope.
|
12
15
|
def initialize(max_breadcrumbs: nil)
|
13
16
|
@max_breadcrumbs = max_breadcrumbs
|
14
17
|
set_default_value
|
15
18
|
end
|
16
19
|
|
20
|
+
# Resets the scope's attributes to defaults.
|
21
|
+
# @return [void]
|
17
22
|
def clear
|
18
23
|
set_default_value
|
19
24
|
end
|
20
25
|
|
26
|
+
# Applies stored attributes and event processors to the given event.
|
27
|
+
# @param event [Event]
|
28
|
+
# @param hint [Hash] the hint data that'll be passed to event processors.
|
29
|
+
# @return [Event]
|
21
30
|
def apply_to_event(event, hint = nil)
|
22
31
|
event.tags = tags.merge(event.tags)
|
23
32
|
event.user = user.merge(event.user)
|
@@ -43,14 +52,20 @@ module Sentry
|
|
43
52
|
event
|
44
53
|
end
|
45
54
|
|
55
|
+
# Adds the breadcrumb to the scope's breadcrumbs buffer.
|
56
|
+
# @param breadcrumb [Breadcrumb]
|
57
|
+
# @return [void]
|
46
58
|
def add_breadcrumb(breadcrumb)
|
47
59
|
breadcrumbs.record(breadcrumb)
|
48
60
|
end
|
49
61
|
|
62
|
+
# Clears the scope's breadcrumbs buffer
|
63
|
+
# @return [void]
|
50
64
|
def clear_breadcrumbs
|
51
65
|
set_new_breadcrumb_buffer
|
52
66
|
end
|
53
67
|
|
68
|
+
# @return [Scope]
|
54
69
|
def dup
|
55
70
|
copy = super
|
56
71
|
copy.breadcrumbs = breadcrumbs.dup
|
@@ -64,6 +79,9 @@ module Sentry
|
|
64
79
|
copy
|
65
80
|
end
|
66
81
|
|
82
|
+
# Updates the scope's data from a given scope.
|
83
|
+
# @param scope [Scope]
|
84
|
+
# @return [void]
|
67
85
|
def update_from_scope(scope)
|
68
86
|
self.breadcrumbs = scope.breadcrumbs
|
69
87
|
self.contexts = scope.contexts
|
@@ -75,6 +93,14 @@ module Sentry
|
|
75
93
|
self.span = scope.span
|
76
94
|
end
|
77
95
|
|
96
|
+
# Updates the scope's data from the given options.
|
97
|
+
# @param contexts [Hash]
|
98
|
+
# @param extras [Hash]
|
99
|
+
# @param tags [Hash]
|
100
|
+
# @param user [Hash]
|
101
|
+
# @param level [String, Symbol]
|
102
|
+
# @param fingerprint [Array]
|
103
|
+
# @return [void]
|
78
104
|
def update_from_options(
|
79
105
|
contexts: nil,
|
80
106
|
extra: nil,
|
@@ -91,75 +117,118 @@ module Sentry
|
|
91
117
|
self.fingerprint = fingerprint if fingerprint
|
92
118
|
end
|
93
119
|
|
120
|
+
# Sets the scope's rack_env attribute.
|
121
|
+
# @param env [Hash]
|
122
|
+
# @return [Hash]
|
94
123
|
def set_rack_env(env)
|
95
124
|
env = env || {}
|
96
125
|
@rack_env = env
|
97
126
|
end
|
98
127
|
|
128
|
+
# Sets the scope's span attribute.
|
129
|
+
# @param span [Span]
|
130
|
+
# @return [Span]
|
99
131
|
def set_span(span)
|
100
132
|
check_argument_type!(span, Span)
|
101
133
|
@span = span
|
102
134
|
end
|
103
135
|
|
136
|
+
# @!macro set_user
|
104
137
|
def set_user(user_hash)
|
105
138
|
check_argument_type!(user_hash, Hash)
|
106
139
|
@user = user_hash
|
107
140
|
end
|
108
141
|
|
142
|
+
# @!macro set_extras
|
109
143
|
def set_extras(extras_hash)
|
110
144
|
check_argument_type!(extras_hash, Hash)
|
111
145
|
@extra.merge!(extras_hash)
|
112
146
|
end
|
113
147
|
|
148
|
+
# Adds a new key-value pair to current extras.
|
149
|
+
# @param key [String, Symbol]
|
150
|
+
# @param value [Object]
|
151
|
+
# @return [Hash]
|
114
152
|
def set_extra(key, value)
|
115
|
-
|
153
|
+
set_extras(key => value)
|
116
154
|
end
|
117
155
|
|
156
|
+
# @!macro set_tags
|
118
157
|
def set_tags(tags_hash)
|
119
158
|
check_argument_type!(tags_hash, Hash)
|
120
159
|
@tags.merge!(tags_hash)
|
121
160
|
end
|
122
161
|
|
162
|
+
# Adds a new key-value pair to current tags.
|
163
|
+
# @param key [String, Symbol]
|
164
|
+
# @param value [Object]
|
165
|
+
# @return [Hash]
|
123
166
|
def set_tag(key, value)
|
124
|
-
|
167
|
+
set_tags(key => value)
|
125
168
|
end
|
126
169
|
|
170
|
+
# Updates the scope's contexts attribute by merging with the old value.
|
171
|
+
# @param contexts [Hash]
|
172
|
+
# @return [Hash]
|
127
173
|
def set_contexts(contexts_hash)
|
128
174
|
check_argument_type!(contexts_hash, Hash)
|
129
|
-
@contexts.merge!(contexts_hash)
|
175
|
+
@contexts.merge!(contexts_hash) do |key, old, new|
|
176
|
+
new.merge(old)
|
177
|
+
end
|
130
178
|
end
|
131
179
|
|
180
|
+
# @!macro set_context
|
132
181
|
def set_context(key, value)
|
133
182
|
check_argument_type!(value, Hash)
|
134
|
-
|
183
|
+
set_contexts(key => value)
|
135
184
|
end
|
136
185
|
|
186
|
+
# Sets the scope's level attribute.
|
187
|
+
# @param level [String, Symbol]
|
188
|
+
# @return [void]
|
137
189
|
def set_level(level)
|
138
190
|
@level = level
|
139
191
|
end
|
140
192
|
|
193
|
+
# Appends a new transaction name to the scope.
|
194
|
+
# The "transaction" here does not refer to `Transaction` objects.
|
195
|
+
# @param transaction_name [String]
|
196
|
+
# @return [void]
|
141
197
|
def set_transaction_name(transaction_name)
|
142
198
|
@transaction_names << transaction_name
|
143
199
|
end
|
144
200
|
|
201
|
+
# Returns current transaction name.
|
202
|
+
# The "transaction" here does not refer to `Transaction` objects.
|
203
|
+
# @return [String, nil]
|
145
204
|
def transaction_name
|
146
205
|
@transaction_names.last
|
147
206
|
end
|
148
207
|
|
208
|
+
# Returns the associated Transaction object.
|
209
|
+
# @return [Transaction, nil]
|
149
210
|
def get_transaction
|
150
211
|
span.transaction if span
|
151
212
|
end
|
152
213
|
|
214
|
+
# Returns the associated Span object.
|
215
|
+
# @return [Span, nil]
|
153
216
|
def get_span
|
154
217
|
span
|
155
218
|
end
|
156
219
|
|
220
|
+
# Sets the scope's fingerprint attribute.
|
221
|
+
# @param fingerprint [Array]
|
222
|
+
# @return [Array]
|
157
223
|
def set_fingerprint(fingerprint)
|
158
224
|
check_argument_type!(fingerprint, Array)
|
159
225
|
|
160
226
|
@fingerprint = fingerprint
|
161
227
|
end
|
162
228
|
|
229
|
+
# Adds a new event processor [Proc] to the scope.
|
230
|
+
# @param block [Proc]
|
231
|
+
# @return [void]
|
163
232
|
def add_event_processor(&block)
|
164
233
|
@event_processors << block
|
165
234
|
end
|
@@ -189,8 +258,8 @@ module Sentry
|
|
189
258
|
@breadcrumbs = BreadcrumbBuffer.new(@max_breadcrumbs)
|
190
259
|
end
|
191
260
|
|
192
|
-
|
193
261
|
class << self
|
262
|
+
# @return [Hash]
|
194
263
|
def os_context
|
195
264
|
@os_context ||=
|
196
265
|
begin
|
@@ -204,6 +273,7 @@ module Sentry
|
|
204
273
|
end
|
205
274
|
end
|
206
275
|
|
276
|
+
# @return [Hash]
|
207
277
|
def runtime_context
|
208
278
|
@runtime_context ||= {
|
209
279
|
name: RbConfig::CONFIG["ruby_install_name"],
|
data/lib/sentry/span.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "securerandom"
|
3
4
|
|
4
5
|
module Sentry
|
@@ -17,9 +18,49 @@ module Sentry
|
|
17
18
|
504 => "deadline_exceeded"
|
18
19
|
}
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
# An uuid that can be used to identify a trace.
|
22
|
+
# @return [String]
|
23
|
+
attr_reader :trace_id
|
24
|
+
# An uuid that can be used to identify the span.
|
25
|
+
# @return [String]
|
26
|
+
attr_reader :span_id
|
27
|
+
# Span parent's span_id.
|
28
|
+
# @return [String]
|
29
|
+
attr_reader :parent_span_id
|
30
|
+
# Sampling result of the span.
|
31
|
+
# @return [Boolean, nil]
|
32
|
+
attr_reader :sampled
|
33
|
+
# Starting timestamp of the span.
|
34
|
+
# @return [Float]
|
35
|
+
attr_reader :start_timestamp
|
36
|
+
# Finishing timestamp of the span.
|
37
|
+
# @return [Float]
|
38
|
+
attr_reader :timestamp
|
39
|
+
# Span description
|
40
|
+
# @return [String]
|
41
|
+
attr_reader :description
|
42
|
+
# Span operation
|
43
|
+
# @return [String]
|
44
|
+
attr_reader :op
|
45
|
+
# Span status
|
46
|
+
# @return [String]
|
47
|
+
attr_reader :status
|
48
|
+
# Span tags
|
49
|
+
# @return [Hash]
|
50
|
+
attr_reader :tags
|
51
|
+
# Span data
|
52
|
+
# @return [Hash]
|
53
|
+
attr_reader :data
|
54
|
+
|
55
|
+
# The SpanRecorder the current span belongs to.
|
56
|
+
# SpanRecorder holds all spans under the same Transaction object (including the Transaction itself).
|
57
|
+
# @return [SpanRecorder]
|
58
|
+
attr_accessor :span_recorder
|
59
|
+
|
60
|
+
# The Transaction object the Span belongs to.
|
61
|
+
# Every span needs to be attached to a Transaction and their child spans will also inherit the same transaction.
|
62
|
+
# @return [Transaction]
|
63
|
+
attr_accessor :transaction
|
23
64
|
|
24
65
|
def initialize(
|
25
66
|
description: nil,
|
@@ -44,6 +85,8 @@ module Sentry
|
|
44
85
|
@tags = {}
|
45
86
|
end
|
46
87
|
|
88
|
+
# Finishes the span by adding a timestamp.
|
89
|
+
# @return [self]
|
47
90
|
def finish
|
48
91
|
# already finished
|
49
92
|
return if @timestamp
|
@@ -52,6 +95,8 @@ module Sentry
|
|
52
95
|
self
|
53
96
|
end
|
54
97
|
|
98
|
+
# Generates a trace string that can be used to connect other transactions.
|
99
|
+
# @return [String]
|
55
100
|
def to_sentry_trace
|
56
101
|
sampled_flag = ""
|
57
102
|
sampled_flag = @sampled ? 1 : 0 unless @sampled.nil?
|
@@ -59,6 +104,7 @@ module Sentry
|
|
59
104
|
"#{@trace_id}-#{@span_id}-#{sampled_flag}"
|
60
105
|
end
|
61
106
|
|
107
|
+
# @return [Hash]
|
62
108
|
def to_hash
|
63
109
|
{
|
64
110
|
trace_id: @trace_id,
|
@@ -74,6 +120,8 @@ module Sentry
|
|
74
120
|
}
|
75
121
|
end
|
76
122
|
|
123
|
+
# Returns the span's context that can be used to embed in an Event.
|
124
|
+
# @return [Hash]
|
77
125
|
def get_trace_context
|
78
126
|
{
|
79
127
|
trace_id: @trace_id,
|
@@ -85,9 +133,11 @@ module Sentry
|
|
85
133
|
}
|
86
134
|
end
|
87
135
|
|
88
|
-
|
89
|
-
|
90
|
-
|
136
|
+
# Starts a child span with given attributes.
|
137
|
+
# @param attributes [Hash] the attributes for the child span.
|
138
|
+
def start_child(**attributes)
|
139
|
+
attributes = attributes.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
|
140
|
+
new_span = Span.new(**attributes)
|
91
141
|
new_span.transaction = transaction
|
92
142
|
new_span.span_recorder = span_recorder
|
93
143
|
|
@@ -98,8 +148,17 @@ module Sentry
|
|
98
148
|
new_span
|
99
149
|
end
|
100
150
|
|
101
|
-
|
102
|
-
|
151
|
+
# Starts a child span, yield it to the given block, and then finish the span after the block is executed.
|
152
|
+
# @example
|
153
|
+
# span.with_child_span do |child_span|
|
154
|
+
# # things happen here will be recorded in a child span
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# @param attributes [Hash] the attributes for the child span.
|
158
|
+
# @param block [Proc] the action to be recorded in the child span.
|
159
|
+
# @yieldparam child_span [Span]
|
160
|
+
def with_child_span(**attributes, &block)
|
161
|
+
child_span = start_child(**attributes)
|
103
162
|
|
104
163
|
yield(child_span)
|
105
164
|
|
@@ -110,22 +169,33 @@ module Sentry
|
|
110
169
|
dup
|
111
170
|
end
|
112
171
|
|
172
|
+
# Sets the span's operation.
|
173
|
+
# @param op [String] operation of the span.
|
113
174
|
def set_op(op)
|
114
175
|
@op = op
|
115
176
|
end
|
116
177
|
|
178
|
+
# Sets the span's description.
|
179
|
+
# @param description [String] description of the span.
|
117
180
|
def set_description(description)
|
118
181
|
@description = description
|
119
182
|
end
|
120
183
|
|
184
|
+
|
185
|
+
# Sets the span's status.
|
186
|
+
# @param satus [String] status of the span.
|
121
187
|
def set_status(status)
|
122
188
|
@status = status
|
123
189
|
end
|
124
190
|
|
191
|
+
# Sets the span's finish timestamp.
|
192
|
+
# @param timestamp [Float] finished time in float format (most precise).
|
125
193
|
def set_timestamp(timestamp)
|
126
194
|
@timestamp = timestamp
|
127
195
|
end
|
128
196
|
|
197
|
+
# Sets the span's status with given http status code.
|
198
|
+
# @param status_code [String] example: "500".
|
129
199
|
def set_http_status(status_code)
|
130
200
|
status_code = status_code.to_i
|
131
201
|
set_data("status_code", status_code)
|
@@ -139,10 +209,16 @@ module Sentry
|
|
139
209
|
set_status(status)
|
140
210
|
end
|
141
211
|
|
212
|
+
# Inserts a key-value pair to the span's data payload.
|
213
|
+
# @param key [String, Symbol]
|
214
|
+
# @param value [Object]
|
142
215
|
def set_data(key, value)
|
143
216
|
@data[key] = value
|
144
217
|
end
|
145
218
|
|
219
|
+
# Sets a tag to the span.
|
220
|
+
# @param key [String, Symbol]
|
221
|
+
# @param value [String]
|
146
222
|
def set_tag(key, value)
|
147
223
|
@tags[key] = value
|
148
224
|
end
|