sentry-ruby 5.3.0 → 5.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.yardopts +2 -0
  5. data/CHANGELOG.md +313 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +31 -0
  8. data/Makefile +4 -0
  9. data/README.md +10 -6
  10. data/Rakefile +13 -0
  11. data/bin/console +18 -0
  12. data/bin/setup +8 -0
  13. data/lib/sentry/background_worker.rb +72 -0
  14. data/lib/sentry/backtrace.rb +124 -0
  15. data/lib/sentry/baggage.rb +81 -0
  16. data/lib/sentry/breadcrumb/sentry_logger.rb +90 -0
  17. data/lib/sentry/breadcrumb.rb +70 -0
  18. data/lib/sentry/breadcrumb_buffer.rb +64 -0
  19. data/lib/sentry/client.rb +207 -0
  20. data/lib/sentry/configuration.rb +543 -0
  21. data/lib/sentry/core_ext/object/deep_dup.rb +61 -0
  22. data/lib/sentry/core_ext/object/duplicable.rb +155 -0
  23. data/lib/sentry/dsn.rb +53 -0
  24. data/lib/sentry/envelope.rb +96 -0
  25. data/lib/sentry/error_event.rb +38 -0
  26. data/lib/sentry/event.rb +178 -0
  27. data/lib/sentry/exceptions.rb +9 -0
  28. data/lib/sentry/hub.rb +241 -0
  29. data/lib/sentry/integrable.rb +26 -0
  30. data/lib/sentry/interface.rb +16 -0
  31. data/lib/sentry/interfaces/exception.rb +43 -0
  32. data/lib/sentry/interfaces/request.rb +134 -0
  33. data/lib/sentry/interfaces/single_exception.rb +65 -0
  34. data/lib/sentry/interfaces/stacktrace.rb +87 -0
  35. data/lib/sentry/interfaces/stacktrace_builder.rb +79 -0
  36. data/lib/sentry/interfaces/threads.rb +42 -0
  37. data/lib/sentry/linecache.rb +47 -0
  38. data/lib/sentry/logger.rb +20 -0
  39. data/lib/sentry/net/http.rb +103 -0
  40. data/lib/sentry/rack/capture_exceptions.rb +82 -0
  41. data/lib/sentry/rack.rb +5 -0
  42. data/lib/sentry/rake.rb +41 -0
  43. data/lib/sentry/redis.rb +107 -0
  44. data/lib/sentry/release_detector.rb +39 -0
  45. data/lib/sentry/scope.rb +339 -0
  46. data/lib/sentry/session.rb +33 -0
  47. data/lib/sentry/session_flusher.rb +90 -0
  48. data/lib/sentry/span.rb +236 -0
  49. data/lib/sentry/test_helper.rb +78 -0
  50. data/lib/sentry/transaction.rb +345 -0
  51. data/lib/sentry/transaction_event.rb +53 -0
  52. data/lib/sentry/transport/configuration.rb +25 -0
  53. data/lib/sentry/transport/dummy_transport.rb +21 -0
  54. data/lib/sentry/transport/http_transport.rb +175 -0
  55. data/lib/sentry/transport.rb +214 -0
  56. data/lib/sentry/utils/argument_checking_helper.rb +13 -0
  57. data/lib/sentry/utils/custom_inspection.rb +14 -0
  58. data/lib/sentry/utils/encoding_helper.rb +22 -0
  59. data/lib/sentry/utils/exception_cause_chain.rb +20 -0
  60. data/lib/sentry/utils/logging_helper.rb +26 -0
  61. data/lib/sentry/utils/real_ip.rb +84 -0
  62. data/lib/sentry/utils/request_id.rb +18 -0
  63. data/lib/sentry/version.rb +5 -0
  64. data/lib/sentry-ruby.rb +511 -0
  65. data/sentry-ruby-core.gemspec +23 -0
  66. data/sentry-ruby.gemspec +24 -0
  67. metadata +66 -16
@@ -0,0 +1,339 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sentry/breadcrumb_buffer"
4
+ require "etc"
5
+
6
+ module Sentry
7
+ class Scope
8
+ include ArgumentCheckingHelper
9
+
10
+ ATTRIBUTES = [
11
+ :transaction_names,
12
+ :transaction_sources,
13
+ :contexts,
14
+ :extra,
15
+ :tags,
16
+ :user,
17
+ :level,
18
+ :breadcrumbs,
19
+ :fingerprint,
20
+ :event_processors,
21
+ :rack_env,
22
+ :span,
23
+ :session
24
+ ]
25
+
26
+ attr_reader(*ATTRIBUTES)
27
+
28
+ # @param max_breadcrumbs [Integer] the maximum number of breadcrumbs to be stored in the scope.
29
+ def initialize(max_breadcrumbs: nil)
30
+ @max_breadcrumbs = max_breadcrumbs
31
+ set_default_value
32
+ end
33
+
34
+ # Resets the scope's attributes to defaults.
35
+ # @return [void]
36
+ def clear
37
+ set_default_value
38
+ end
39
+
40
+ # Applies stored attributes and event processors to the given event.
41
+ # @param event [Event]
42
+ # @param hint [Hash] the hint data that'll be passed to event processors.
43
+ # @return [Event]
44
+ def apply_to_event(event, hint = nil)
45
+ event.tags = tags.merge(event.tags)
46
+ event.user = user.merge(event.user)
47
+ event.extra = extra.merge(event.extra)
48
+ event.contexts = contexts.merge(event.contexts)
49
+ event.transaction = transaction_name if transaction_name
50
+ event.transaction_info = { source: transaction_source } if transaction_source
51
+
52
+ if span
53
+ event.contexts[:trace] = span.get_trace_context
54
+ end
55
+
56
+ event.fingerprint = fingerprint
57
+ event.level = level
58
+ event.breadcrumbs = breadcrumbs
59
+ event.rack_env = rack_env if rack_env
60
+
61
+ all_event_processors = self.class.global_event_processors + @event_processors
62
+
63
+ unless all_event_processors.empty?
64
+ all_event_processors.each do |processor_block|
65
+ event = processor_block.call(event, hint)
66
+ end
67
+ end
68
+
69
+ event
70
+ end
71
+
72
+ # Adds the breadcrumb to the scope's breadcrumbs buffer.
73
+ # @param breadcrumb [Breadcrumb]
74
+ # @return [void]
75
+ def add_breadcrumb(breadcrumb)
76
+ breadcrumbs.record(breadcrumb)
77
+ end
78
+
79
+ # Clears the scope's breadcrumbs buffer
80
+ # @return [void]
81
+ def clear_breadcrumbs
82
+ set_new_breadcrumb_buffer
83
+ end
84
+
85
+ # @return [Scope]
86
+ def dup
87
+ copy = super
88
+ copy.breadcrumbs = breadcrumbs.dup
89
+ copy.contexts = contexts.deep_dup
90
+ copy.extra = extra.deep_dup
91
+ copy.tags = tags.deep_dup
92
+ copy.user = user.deep_dup
93
+ copy.transaction_names = transaction_names.dup
94
+ copy.transaction_sources = transaction_sources.dup
95
+ copy.fingerprint = fingerprint.deep_dup
96
+ copy.span = span.deep_dup
97
+ copy.session = session.deep_dup
98
+ copy
99
+ end
100
+
101
+ # Updates the scope's data from a given scope.
102
+ # @param scope [Scope]
103
+ # @return [void]
104
+ def update_from_scope(scope)
105
+ self.breadcrumbs = scope.breadcrumbs
106
+ self.contexts = scope.contexts
107
+ self.extra = scope.extra
108
+ self.tags = scope.tags
109
+ self.user = scope.user
110
+ self.transaction_names = scope.transaction_names
111
+ self.transaction_sources = scope.transaction_sources
112
+ self.fingerprint = scope.fingerprint
113
+ self.span = scope.span
114
+ end
115
+
116
+ # Updates the scope's data from the given options.
117
+ # @param contexts [Hash]
118
+ # @param extras [Hash]
119
+ # @param tags [Hash]
120
+ # @param user [Hash]
121
+ # @param level [String, Symbol]
122
+ # @param fingerprint [Array]
123
+ # @return [void]
124
+ def update_from_options(
125
+ contexts: nil,
126
+ extra: nil,
127
+ tags: nil,
128
+ user: nil,
129
+ level: nil,
130
+ fingerprint: nil
131
+ )
132
+ self.contexts.merge!(contexts) if contexts
133
+ self.extra.merge!(extra) if extra
134
+ self.tags.merge!(tags) if tags
135
+ self.user = user if user
136
+ self.level = level if level
137
+ self.fingerprint = fingerprint if fingerprint
138
+ end
139
+
140
+ # Sets the scope's rack_env attribute.
141
+ # @param env [Hash]
142
+ # @return [Hash]
143
+ def set_rack_env(env)
144
+ env = env || {}
145
+ @rack_env = env
146
+ end
147
+
148
+ # Sets the scope's span attribute.
149
+ # @param span [Span]
150
+ # @return [Span]
151
+ def set_span(span)
152
+ check_argument_type!(span, Span)
153
+ @span = span
154
+ end
155
+
156
+ # @!macro set_user
157
+ def set_user(user_hash)
158
+ check_argument_type!(user_hash, Hash)
159
+ @user = user_hash
160
+ end
161
+
162
+ # @!macro set_extras
163
+ def set_extras(extras_hash)
164
+ check_argument_type!(extras_hash, Hash)
165
+ @extra.merge!(extras_hash)
166
+ end
167
+
168
+ # Adds a new key-value pair to current extras.
169
+ # @param key [String, Symbol]
170
+ # @param value [Object]
171
+ # @return [Hash]
172
+ def set_extra(key, value)
173
+ set_extras(key => value)
174
+ end
175
+
176
+ # @!macro set_tags
177
+ def set_tags(tags_hash)
178
+ check_argument_type!(tags_hash, Hash)
179
+ @tags.merge!(tags_hash)
180
+ end
181
+
182
+ # Adds a new key-value pair to current tags.
183
+ # @param key [String, Symbol]
184
+ # @param value [Object]
185
+ # @return [Hash]
186
+ def set_tag(key, value)
187
+ set_tags(key => value)
188
+ end
189
+
190
+ # Updates the scope's contexts attribute by merging with the old value.
191
+ # @param contexts [Hash]
192
+ # @return [Hash]
193
+ def set_contexts(contexts_hash)
194
+ check_argument_type!(contexts_hash, Hash)
195
+ @contexts.merge!(contexts_hash) do |key, old, new|
196
+ old.merge(new)
197
+ end
198
+ end
199
+
200
+ # @!macro set_context
201
+ def set_context(key, value)
202
+ check_argument_type!(value, Hash)
203
+ set_contexts(key => value)
204
+ end
205
+
206
+ # Sets the scope's level attribute.
207
+ # @param level [String, Symbol]
208
+ # @return [void]
209
+ def set_level(level)
210
+ @level = level
211
+ end
212
+
213
+ # Appends a new transaction name to the scope.
214
+ # The "transaction" here does not refer to `Transaction` objects.
215
+ # @param transaction_name [String]
216
+ # @return [void]
217
+ def set_transaction_name(transaction_name, source: :custom)
218
+ @transaction_names << transaction_name
219
+ @transaction_sources << source
220
+ end
221
+
222
+ # Sets the currently active session on the scope.
223
+ # @param session [Session, nil]
224
+ # @return [void]
225
+ def set_session(session)
226
+ @session = session
227
+ end
228
+
229
+ # Returns current transaction name.
230
+ # The "transaction" here does not refer to `Transaction` objects.
231
+ # @return [String, nil]
232
+ def transaction_name
233
+ @transaction_names.last
234
+ end
235
+
236
+ # Returns current transaction source.
237
+ # The "transaction" here does not refer to `Transaction` objects.
238
+ # @return [String, nil]
239
+ def transaction_source
240
+ @transaction_sources.last
241
+ end
242
+
243
+ # Returns the associated Transaction object.
244
+ # @return [Transaction, nil]
245
+ def get_transaction
246
+ span.transaction if span
247
+ end
248
+
249
+ # Returns the associated Span object.
250
+ # @return [Span, nil]
251
+ def get_span
252
+ span
253
+ end
254
+
255
+ # Sets the scope's fingerprint attribute.
256
+ # @param fingerprint [Array]
257
+ # @return [Array]
258
+ def set_fingerprint(fingerprint)
259
+ check_argument_type!(fingerprint, Array)
260
+
261
+ @fingerprint = fingerprint
262
+ end
263
+
264
+ # Adds a new event processor [Proc] to the scope.
265
+ # @param block [Proc]
266
+ # @return [void]
267
+ def add_event_processor(&block)
268
+ @event_processors << block
269
+ end
270
+
271
+ protected
272
+
273
+ # for duplicating scopes internally
274
+ attr_writer(*ATTRIBUTES)
275
+
276
+ private
277
+
278
+ def set_default_value
279
+ @contexts = { :os => self.class.os_context, :runtime => self.class.runtime_context }
280
+ @extra = {}
281
+ @tags = {}
282
+ @user = {}
283
+ @level = :error
284
+ @fingerprint = []
285
+ @transaction_names = []
286
+ @transaction_sources = []
287
+ @event_processors = []
288
+ @rack_env = {}
289
+ @span = nil
290
+ @session = nil
291
+ set_new_breadcrumb_buffer
292
+ end
293
+
294
+ def set_new_breadcrumb_buffer
295
+ @breadcrumbs = BreadcrumbBuffer.new(@max_breadcrumbs)
296
+ end
297
+
298
+ class << self
299
+ # @return [Hash]
300
+ def os_context
301
+ @os_context ||=
302
+ begin
303
+ uname = Etc.uname
304
+ {
305
+ name: uname[:sysname] || RbConfig::CONFIG["host_os"],
306
+ version: uname[:version],
307
+ build: uname[:release],
308
+ kernel_version: uname[:version]
309
+ }
310
+ end
311
+ end
312
+
313
+ # @return [Hash]
314
+ def runtime_context
315
+ @runtime_context ||= {
316
+ name: RbConfig::CONFIG["ruby_install_name"],
317
+ version: RUBY_DESCRIPTION || Sentry.sys_command("ruby -v")
318
+ }
319
+ end
320
+
321
+ # Returns the global event processors array.
322
+ # @return [Array<Proc>]
323
+ def global_event_processors
324
+ @global_event_processors ||= []
325
+ end
326
+
327
+ # Adds a new global event processor [Proc].
328
+ # Sometimes we need a global event processor without needing to configure scope.
329
+ # These run before scope event processors.
330
+ #
331
+ # @param block [Proc]
332
+ # @return [void]
333
+ def add_global_event_processor(&block)
334
+ global_event_processors << block
335
+ end
336
+ end
337
+
338
+ end
339
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ class Session
5
+ attr_reader :started, :status, :aggregation_key
6
+
7
+ # TODO-neel add :crashed after adding handled mechanism
8
+ STATUSES = %i(ok errored exited)
9
+ AGGREGATE_STATUSES = %i(errored exited)
10
+
11
+ def initialize
12
+ @started = Sentry.utc_now
13
+ @status = :ok
14
+
15
+ # truncate seconds from the timestamp since we only care about
16
+ # minute level granularity for aggregation
17
+ @aggregation_key = Time.utc(@started.year, @started.month, @started.day, @started.hour, @started.min)
18
+ end
19
+
20
+ # TODO-neel add :crashed after adding handled mechanism
21
+ def update_from_exception(_exception = nil)
22
+ @status = :errored
23
+ end
24
+
25
+ def close
26
+ @status = :exited if @status == :ok
27
+ end
28
+
29
+ def deep_dup
30
+ dup
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ class SessionFlusher
5
+ include LoggingHelper
6
+
7
+ FLUSH_INTERVAL = 60
8
+
9
+ def initialize(configuration, client)
10
+ @thread = nil
11
+ @exited = false
12
+ @client = client
13
+ @pending_aggregates = {}
14
+ @release = configuration.release
15
+ @environment = configuration.environment
16
+ @logger = configuration.logger
17
+
18
+ log_debug("[Sessions] Sessions won't be captured without a valid release") unless @release
19
+ end
20
+
21
+ def flush
22
+ return if @pending_aggregates.empty?
23
+ envelope = pending_envelope
24
+
25
+ Sentry.background_worker.perform do
26
+ @client.transport.send_envelope(envelope)
27
+ end
28
+
29
+ @pending_aggregates = {}
30
+ end
31
+
32
+ def add_session(session)
33
+ return if @exited
34
+ return unless @release
35
+
36
+ begin
37
+ ensure_thread
38
+ rescue ThreadError
39
+ log_debug("Session flusher thread creation failed")
40
+ @exited = true
41
+ return
42
+ end
43
+
44
+ return unless Session::AGGREGATE_STATUSES.include?(session.status)
45
+ @pending_aggregates[session.aggregation_key] ||= init_aggregates(session.aggregation_key)
46
+ @pending_aggregates[session.aggregation_key][session.status] += 1
47
+ end
48
+
49
+ def kill
50
+ log_debug("Killing session flusher")
51
+
52
+ @exited = true
53
+ @thread&.kill
54
+ end
55
+
56
+ private
57
+
58
+ def init_aggregates(aggregation_key)
59
+ aggregates = { started: aggregation_key.iso8601 }
60
+ Session::AGGREGATE_STATUSES.each { |k| aggregates[k] = 0 }
61
+ aggregates
62
+ end
63
+
64
+ def pending_envelope
65
+ envelope = Envelope.new
66
+
67
+ header = { type: 'sessions' }
68
+ payload = { attrs: attrs, aggregates: @pending_aggregates.values }
69
+
70
+ envelope.add_item(header, payload)
71
+ envelope
72
+ end
73
+
74
+ def attrs
75
+ { release: @release, environment: @environment }
76
+ end
77
+
78
+ def ensure_thread
79
+ return if @thread&.alive?
80
+
81
+ @thread = Thread.new do
82
+ loop do
83
+ sleep(FLUSH_INTERVAL)
84
+ flush
85
+ end
86
+ end
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Sentry
6
+ class Span
7
+ STATUS_MAP = {
8
+ 400 => "invalid_argument",
9
+ 401 => "unauthenticated",
10
+ 403 => "permission_denied",
11
+ 404 => "not_found",
12
+ 409 => "already_exists",
13
+ 429 => "resource_exhausted",
14
+ 499 => "cancelled",
15
+ 500 => "internal_error",
16
+ 501 => "unimplemented",
17
+ 503 => "unavailable",
18
+ 504 => "deadline_exceeded"
19
+ }
20
+
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_reader :transaction
64
+
65
+ def initialize(
66
+ transaction:,
67
+ description: nil,
68
+ op: nil,
69
+ status: nil,
70
+ trace_id: nil,
71
+ span_id: nil,
72
+ parent_span_id: nil,
73
+ sampled: nil,
74
+ start_timestamp: nil,
75
+ timestamp: nil
76
+ )
77
+ @trace_id = trace_id || SecureRandom.uuid.delete("-")
78
+ @span_id = span_id || SecureRandom.hex(8)
79
+ @parent_span_id = parent_span_id
80
+ @sampled = sampled
81
+ @start_timestamp = start_timestamp || Sentry.utc_now.to_f
82
+ @timestamp = timestamp
83
+ @description = description
84
+ @transaction = transaction
85
+ @op = op
86
+ @status = status
87
+ @data = {}
88
+ @tags = {}
89
+ end
90
+
91
+ # Finishes the span by adding a timestamp.
92
+ # @return [self]
93
+ def finish(end_timestamp: nil)
94
+ @timestamp = end_timestamp || @timestamp || Sentry.utc_now.to_f
95
+ self
96
+ end
97
+
98
+ # Generates a trace string that can be used to connect other transactions.
99
+ # @return [String]
100
+ def to_sentry_trace
101
+ sampled_flag = ""
102
+ sampled_flag = @sampled ? 1 : 0 unless @sampled.nil?
103
+
104
+ "#{@trace_id}-#{@span_id}-#{sampled_flag}"
105
+ end
106
+
107
+ # Generates a W3C Baggage header string for distributed tracing
108
+ # from the incoming baggage stored on the transaction.
109
+ # @return [String, nil]
110
+ def to_baggage
111
+ transaction.get_baggage&.serialize
112
+ end
113
+
114
+ # @return [Hash]
115
+ def to_hash
116
+ {
117
+ trace_id: @trace_id,
118
+ span_id: @span_id,
119
+ parent_span_id: @parent_span_id,
120
+ start_timestamp: @start_timestamp,
121
+ timestamp: @timestamp,
122
+ description: @description,
123
+ op: @op,
124
+ status: @status,
125
+ tags: @tags,
126
+ data: @data
127
+ }
128
+ end
129
+
130
+ # Returns the span's context that can be used to embed in an Event.
131
+ # @return [Hash]
132
+ def get_trace_context
133
+ {
134
+ trace_id: @trace_id,
135
+ span_id: @span_id,
136
+ parent_span_id: @parent_span_id,
137
+ description: @description,
138
+ op: @op,
139
+ status: @status
140
+ }
141
+ end
142
+
143
+ # Starts a child span with given attributes.
144
+ # @param attributes [Hash] the attributes for the child span.
145
+ def start_child(**attributes)
146
+ attributes = attributes.dup.merge(transaction: @transaction, trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
147
+ new_span = Span.new(**attributes)
148
+ new_span.span_recorder = span_recorder
149
+
150
+ if span_recorder
151
+ span_recorder.add(new_span)
152
+ end
153
+
154
+ new_span
155
+ end
156
+
157
+ # Starts a child span, yield it to the given block, and then finish the span after the block is executed.
158
+ # @example
159
+ # span.with_child_span do |child_span|
160
+ # # things happen here will be recorded in a child span
161
+ # end
162
+ #
163
+ # @param attributes [Hash] the attributes for the child span.
164
+ # @param block [Proc] the action to be recorded in the child span.
165
+ # @yieldparam child_span [Span]
166
+ def with_child_span(**attributes, &block)
167
+ child_span = start_child(**attributes)
168
+
169
+ yield(child_span)
170
+
171
+ child_span.finish
172
+ rescue
173
+ child_span.set_http_status(500)
174
+ child_span.finish
175
+ raise
176
+ end
177
+
178
+ def deep_dup
179
+ dup
180
+ end
181
+
182
+ # Sets the span's operation.
183
+ # @param op [String] operation of the span.
184
+ def set_op(op)
185
+ @op = op
186
+ end
187
+
188
+ # Sets the span's description.
189
+ # @param description [String] description of the span.
190
+ def set_description(description)
191
+ @description = description
192
+ end
193
+
194
+
195
+ # Sets the span's status.
196
+ # @param satus [String] status of the span.
197
+ def set_status(status)
198
+ @status = status
199
+ end
200
+
201
+ # Sets the span's finish timestamp.
202
+ # @param timestamp [Float] finished time in float format (most precise).
203
+ def set_timestamp(timestamp)
204
+ @timestamp = timestamp
205
+ end
206
+
207
+ # Sets the span's status with given http status code.
208
+ # @param status_code [String] example: "500".
209
+ def set_http_status(status_code)
210
+ status_code = status_code.to_i
211
+ set_data("status_code", status_code)
212
+
213
+ status =
214
+ if status_code >= 200 && status_code < 299
215
+ "ok"
216
+ else
217
+ STATUS_MAP[status_code]
218
+ end
219
+ set_status(status)
220
+ end
221
+
222
+ # Inserts a key-value pair to the span's data payload.
223
+ # @param key [String, Symbol]
224
+ # @param value [Object]
225
+ def set_data(key, value)
226
+ @data[key] = value
227
+ end
228
+
229
+ # Sets a tag to the span.
230
+ # @param key [String, Symbol]
231
+ # @param value [String]
232
+ def set_tag(key, value)
233
+ @tags[key] = value
234
+ end
235
+ end
236
+ end