sentry-ruby-core 5.17.3 → 5.18.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/Gemfile +2 -0
- data/README.md +9 -9
- data/bin/console +1 -0
- data/lib/sentry/backpressure_monitor.rb +2 -32
- data/lib/sentry/configuration.rb +1 -1
- data/lib/sentry/graphql.rb +9 -0
- data/lib/sentry/hub.rb +12 -1
- data/lib/sentry/metrics/aggregator.rb +3 -31
- data/lib/sentry/metrics.rb +2 -1
- data/lib/sentry/net/http.rb +2 -1
- data/lib/sentry/rack/capture_exceptions.rb +8 -1
- data/lib/sentry/redis.rb +2 -1
- data/lib/sentry/scope.rb +16 -26
- data/lib/sentry/session_flusher.rb +5 -32
- data/lib/sentry/span.rb +23 -3
- data/lib/sentry/test_helper.rb +1 -1
- data/lib/sentry/threaded_periodic_worker.rb +39 -0
- data/lib/sentry/transport.rb +1 -1
- data/lib/sentry/utils/logging_helper.rb +0 -4
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +11 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ec8300501e7004bf7648188108874295436b1330cdf999edb35143d3b371461
|
4
|
+
data.tar.gz: 52508a18bfc34c68494b37abc4f9907bd18b46aebe32e4dba46e16a60a7c685b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7add2e138fa5efa7b0db55b90a94d4d0e06de39b8bacca0b39bef0f9496ab6793990e8ae909cb71465d19d07e29f6ef6bdb3e44a2b0f1b953dfe6a5c332caa1a
|
7
|
+
data.tar.gz: 0f5824802082fba7fa352ad86402e56a230a2daa0b2ffc894c0fb771da6b719e5ee6e3cb864a79f7d75bdcb8600310435ef4b5c97a8acb7504e6232a777f1314
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -13,14 +13,14 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to he
|
|
13
13
|
Sentry SDK for Ruby
|
14
14
|
===========
|
15
15
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| [](https://rubygems.org/gems/sentry-ruby) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-rails) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-sidekiq) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-delayed_job) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-resque) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://rubygems.org/gems/sentry-ruby) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_ruby_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-ruby) |
|
19
|
+
| [](https://rubygems.org/gems/sentry-rails) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-rails) |
|
20
|
+
| [](https://rubygems.org/gems/sentry-sidekiq) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-sidekiq) |
|
21
|
+
| [](https://rubygems.org/gems/sentry-delayed_job) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-delayed_job) |
|
22
|
+
| [](https://rubygems.org/gems/sentry-resque) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-resque) |
|
23
|
+
| [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) | [](https://www.rubydoc.info/gems/sentry-opentelemetry) |
|
24
24
|
|
25
25
|
|
26
26
|
|
@@ -103,6 +103,6 @@ To learn more about sampling transactions, please visit the [official documentat
|
|
103
103
|
|
104
104
|
* [](https://docs.sentry.io/platforms/ruby/)
|
105
105
|
* [](https://forum.sentry.io/c/sdks)
|
106
|
-
* [](https://discord.gg/PXa5Apfe7K)
|
106
|
+
* [](https://discord.gg/PXa5Apfe7K)
|
107
107
|
* [](https://stackoverflow.com/questions/tagged/sentry)
|
108
108
|
* [](https://twitter.com/intent/follow?screen_name=getsentry)
|
data/bin/console
CHANGED
@@ -1,19 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Sentry
|
4
|
-
class BackpressureMonitor
|
5
|
-
include LoggingHelper
|
6
|
-
|
4
|
+
class BackpressureMonitor < ThreadedPeriodicWorker
|
7
5
|
DEFAULT_INTERVAL = 10
|
8
6
|
MAX_DOWNSAMPLE_FACTOR = 10
|
9
7
|
|
10
8
|
def initialize(configuration, client, interval: DEFAULT_INTERVAL)
|
11
|
-
|
9
|
+
super(configuration.logger, interval)
|
12
10
|
@client = client
|
13
|
-
@logger = configuration.logger
|
14
|
-
|
15
|
-
@thread = nil
|
16
|
-
@exited = false
|
17
11
|
|
18
12
|
@healthy = true
|
19
13
|
@downsample_factor = 0
|
@@ -47,29 +41,5 @@ module Sentry
|
|
47
41
|
log_debug("[BackpressureMonitor] health check negative, downsampling with a factor of #{@downsample_factor}")
|
48
42
|
end
|
49
43
|
end
|
50
|
-
|
51
|
-
def kill
|
52
|
-
log_debug("[BackpressureMonitor] killing monitor")
|
53
|
-
|
54
|
-
@exited = true
|
55
|
-
@thread&.kill
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def ensure_thread
|
61
|
-
return if @exited
|
62
|
-
return if @thread&.alive?
|
63
|
-
|
64
|
-
@thread = Thread.new do
|
65
|
-
loop do
|
66
|
-
sleep(@interval)
|
67
|
-
run
|
68
|
-
end
|
69
|
-
end
|
70
|
-
rescue ThreadError
|
71
|
-
log_debug("[BackpressureMonitor] Thread creation failed")
|
72
|
-
@exited = true
|
73
|
-
end
|
74
44
|
end
|
75
45
|
end
|
data/lib/sentry/configuration.rb
CHANGED
@@ -351,7 +351,7 @@ module Sentry
|
|
351
351
|
def initialize
|
352
352
|
self.app_dirs_pattern = nil
|
353
353
|
self.debug = false
|
354
|
-
self.background_worker_threads = Concurrent.processor_count
|
354
|
+
self.background_worker_threads = (Concurrent.processor_count / 2.0).ceil
|
355
355
|
self.background_worker_max_queue = BackgroundWorker::DEFAULT_MAX_QUEUE
|
356
356
|
self.backtrace_cleanup_callback = nil
|
357
357
|
self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Sentry.register_patch(:graphql) do |config|
|
4
|
+
if defined?(::GraphQL::Schema) && defined?(::GraphQL::Tracing::SentryTrace) && ::GraphQL::Schema.respond_to?(:trace_with)
|
5
|
+
::GraphQL::Schema.trace_with(::GraphQL::Tracing::SentryTrace, set_transaction_name: true)
|
6
|
+
else
|
7
|
+
config.logger.warn(Sentry::LOGGER_PROGNAME) { 'You tried to enable the GraphQL integration but no GraphQL gem was detected. Make sure you have the `graphql` gem (>= 2.2.6) in your Gemfile.' }
|
8
|
+
end
|
9
|
+
end
|
data/lib/sentry/hub.rb
CHANGED
@@ -193,7 +193,12 @@ module Sentry
|
|
193
193
|
elsif custom_scope = options[:scope]
|
194
194
|
scope.update_from_scope(custom_scope)
|
195
195
|
elsif !options.empty?
|
196
|
-
scope.update_from_options(**options)
|
196
|
+
unsupported_option_keys = scope.update_from_options(**options)
|
197
|
+
|
198
|
+
configuration.log_debug <<~MSG
|
199
|
+
Options #{unsupported_option_keys} are not supported and will not be applied to the event.
|
200
|
+
You may want to set them under the `extra` option.
|
201
|
+
MSG
|
197
202
|
end
|
198
203
|
|
199
204
|
event = current_client.capture_event(event, scope, hint)
|
@@ -279,6 +284,12 @@ module Sentry
|
|
279
284
|
headers
|
280
285
|
end
|
281
286
|
|
287
|
+
def get_trace_propagation_meta
|
288
|
+
get_trace_propagation_headers.map do |k, v|
|
289
|
+
"<meta name=\"#{k}\" content=\"#{v}\">"
|
290
|
+
end.join("\n")
|
291
|
+
end
|
292
|
+
|
282
293
|
def continue_trace(env, **options)
|
283
294
|
configure_scope { |s| s.generate_propagation_context(env) }
|
284
295
|
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
module Metrics
|
5
|
-
class Aggregator
|
6
|
-
include LoggingHelper
|
7
|
-
|
5
|
+
class Aggregator < ThreadedPeriodicWorker
|
8
6
|
FLUSH_INTERVAL = 5
|
9
7
|
ROLLUP_IN_SECONDS = 10
|
10
8
|
|
@@ -36,8 +34,8 @@ module Sentry
|
|
36
34
|
attr_reader :client, :thread, :buckets, :flush_shift, :code_locations
|
37
35
|
|
38
36
|
def initialize(configuration, client)
|
37
|
+
super(configuration.logger, FLUSH_INTERVAL)
|
39
38
|
@client = client
|
40
|
-
@logger = configuration.logger
|
41
39
|
@before_emit = configuration.metrics.before_emit
|
42
40
|
@enable_code_locations = configuration.metrics.enable_code_locations
|
43
41
|
@stacktrace_builder = configuration.stacktrace_builder
|
@@ -46,8 +44,6 @@ module Sentry
|
|
46
44
|
@default_tags['release'] = configuration.release if configuration.release
|
47
45
|
@default_tags['environment'] = configuration.environment if configuration.environment
|
48
46
|
|
49
|
-
@thread = nil
|
50
|
-
@exited = false
|
51
47
|
@mutex = Mutex.new
|
52
48
|
|
53
49
|
# a nested hash of timestamp -> bucket keys -> Metric instance
|
@@ -120,34 +116,10 @@ module Sentry
|
|
120
116
|
@client.capture_envelope(envelope)
|
121
117
|
end
|
122
118
|
|
123
|
-
|
124
|
-
log_debug('[Metrics::Aggregator] killing thread')
|
125
|
-
|
126
|
-
@exited = true
|
127
|
-
@thread&.kill
|
128
|
-
end
|
119
|
+
alias_method :run, :flush
|
129
120
|
|
130
121
|
private
|
131
122
|
|
132
|
-
def ensure_thread
|
133
|
-
return false if @exited
|
134
|
-
return true if @thread&.alive?
|
135
|
-
|
136
|
-
@thread = Thread.new do
|
137
|
-
loop do
|
138
|
-
# TODO-neel-metrics use event for force flush later
|
139
|
-
sleep(FLUSH_INTERVAL)
|
140
|
-
flush
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
true
|
145
|
-
rescue ThreadError
|
146
|
-
log_debug('[Metrics::Aggregator] thread creation failed')
|
147
|
-
@exited = true
|
148
|
-
false
|
149
|
-
end
|
150
|
-
|
151
123
|
# important to sort for key consistency
|
152
124
|
def serialize_tags(tags)
|
153
125
|
tags.flat_map do |k, v|
|
data/lib/sentry/metrics.rb
CHANGED
@@ -15,6 +15,7 @@ module Sentry
|
|
15
15
|
FRACTIONAL_UNITS = %w[ratio percent]
|
16
16
|
|
17
17
|
OP_NAME = 'metric.timing'
|
18
|
+
SPAN_ORIGIN = 'auto.metric.timing'
|
18
19
|
|
19
20
|
class << self
|
20
21
|
def increment(key, value = 1.0, unit: 'none', tags: {}, timestamp: nil)
|
@@ -37,7 +38,7 @@ module Sentry
|
|
37
38
|
return unless block_given?
|
38
39
|
return yield unless DURATION_UNITS.include?(unit)
|
39
40
|
|
40
|
-
result, value = Sentry.with_child_span(op: OP_NAME, description: key) do |span|
|
41
|
+
result, value = Sentry.with_child_span(op: OP_NAME, description: key, origin: SPAN_ORIGIN) do |span|
|
41
42
|
tags.each { |k, v| span.set_tag(k, v.is_a?(Array) ? v.join(', ') : v.to_s) } if span
|
42
43
|
|
43
44
|
start = Timing.send(unit.to_sym)
|
data/lib/sentry/net/http.rb
CHANGED
@@ -8,6 +8,7 @@ module Sentry
|
|
8
8
|
module Net
|
9
9
|
module HTTP
|
10
10
|
OP_NAME = "http.client"
|
11
|
+
SPAN_ORIGIN = "auto.http.net_http"
|
11
12
|
BREADCRUMB_CATEGORY = "net.http"
|
12
13
|
|
13
14
|
# To explain how the entire thing works, we need to know how the original Net::HTTP#request works
|
@@ -30,7 +31,7 @@ module Sentry
|
|
30
31
|
return super unless started? && Sentry.initialized?
|
31
32
|
return super if from_sentry_sdk?
|
32
33
|
|
33
|
-
Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f) do |sentry_span|
|
34
|
+
Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f, origin: SPAN_ORIGIN) do |sentry_span|
|
34
35
|
request_info = extract_request_info(req)
|
35
36
|
|
36
37
|
if propagate_trace?(request_info[:url], Sentry.configuration)
|
@@ -5,6 +5,7 @@ module Sentry
|
|
5
5
|
class CaptureExceptions
|
6
6
|
ERROR_EVENT_ID_KEY = "sentry.error_event_id"
|
7
7
|
MECHANISM_TYPE = "rack"
|
8
|
+
SPAN_ORIGIN = "auto.http.rack"
|
8
9
|
|
9
10
|
def initialize(app)
|
10
11
|
@app = app
|
@@ -63,7 +64,13 @@ module Sentry
|
|
63
64
|
end
|
64
65
|
|
65
66
|
def start_transaction(env, scope)
|
66
|
-
options = {
|
67
|
+
options = {
|
68
|
+
name: scope.transaction_name,
|
69
|
+
source: scope.transaction_source,
|
70
|
+
op: transaction_op,
|
71
|
+
origin: SPAN_ORIGIN
|
72
|
+
}
|
73
|
+
|
67
74
|
transaction = Sentry.continue_trace(env, **options)
|
68
75
|
Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
|
69
76
|
end
|
data/lib/sentry/redis.rb
CHANGED
@@ -4,6 +4,7 @@ module Sentry
|
|
4
4
|
# @api private
|
5
5
|
class Redis
|
6
6
|
OP_NAME = "db.redis"
|
7
|
+
SPAN_ORIGIN = "auto.db.redis"
|
7
8
|
LOGGER_NAME = :redis_logger
|
8
9
|
|
9
10
|
def initialize(commands, host, port, db)
|
@@ -13,7 +14,7 @@ module Sentry
|
|
13
14
|
def instrument
|
14
15
|
return yield unless Sentry.initialized?
|
15
16
|
|
16
|
-
Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f) do |span|
|
17
|
+
Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f, origin: SPAN_ORIGIN) do |span|
|
17
18
|
yield.tap do
|
18
19
|
record_breadcrumb
|
19
20
|
|
data/lib/sentry/scope.rb
CHANGED
@@ -9,8 +9,8 @@ module Sentry
|
|
9
9
|
include ArgumentCheckingHelper
|
10
10
|
|
11
11
|
ATTRIBUTES = [
|
12
|
-
:
|
13
|
-
:
|
12
|
+
:transaction_name,
|
13
|
+
:transaction_source,
|
14
14
|
:contexts,
|
15
15
|
:extra,
|
16
16
|
:tags,
|
@@ -96,8 +96,8 @@ module Sentry
|
|
96
96
|
copy.extra = extra.deep_dup
|
97
97
|
copy.tags = tags.deep_dup
|
98
98
|
copy.user = user.deep_dup
|
99
|
-
copy.
|
100
|
-
copy.
|
99
|
+
copy.transaction_name = transaction_name.dup
|
100
|
+
copy.transaction_source = transaction_source.dup
|
101
101
|
copy.fingerprint = fingerprint.deep_dup
|
102
102
|
copy.span = span.deep_dup
|
103
103
|
copy.session = session.deep_dup
|
@@ -114,8 +114,8 @@ module Sentry
|
|
114
114
|
self.extra = scope.extra
|
115
115
|
self.tags = scope.tags
|
116
116
|
self.user = scope.user
|
117
|
-
self.
|
118
|
-
self.
|
117
|
+
self.transaction_name = scope.transaction_name
|
118
|
+
self.transaction_source = scope.transaction_source
|
119
119
|
self.fingerprint = scope.fingerprint
|
120
120
|
self.span = scope.span
|
121
121
|
self.propagation_context = scope.propagation_context
|
@@ -128,14 +128,15 @@ module Sentry
|
|
128
128
|
# @param user [Hash]
|
129
129
|
# @param level [String, Symbol]
|
130
130
|
# @param fingerprint [Array]
|
131
|
-
# @return [
|
131
|
+
# @return [Array]
|
132
132
|
def update_from_options(
|
133
133
|
contexts: nil,
|
134
134
|
extra: nil,
|
135
135
|
tags: nil,
|
136
136
|
user: nil,
|
137
137
|
level: nil,
|
138
|
-
fingerprint: nil
|
138
|
+
fingerprint: nil,
|
139
|
+
**options
|
139
140
|
)
|
140
141
|
self.contexts.merge!(contexts) if contexts
|
141
142
|
self.extra.merge!(extra) if extra
|
@@ -143,6 +144,9 @@ module Sentry
|
|
143
144
|
self.user = user if user
|
144
145
|
self.level = level if level
|
145
146
|
self.fingerprint = fingerprint if fingerprint
|
147
|
+
|
148
|
+
# Returns unsupported option keys so we can notify users.
|
149
|
+
options.keys
|
146
150
|
end
|
147
151
|
|
148
152
|
# Sets the scope's rack_env attribute.
|
@@ -227,8 +231,8 @@ module Sentry
|
|
227
231
|
# @param transaction_name [String]
|
228
232
|
# @return [void]
|
229
233
|
def set_transaction_name(transaction_name, source: :custom)
|
230
|
-
@
|
231
|
-
@
|
234
|
+
@transaction_name = transaction_name
|
235
|
+
@transaction_source = source
|
232
236
|
end
|
233
237
|
|
234
238
|
# Sets the currently active session on the scope.
|
@@ -238,20 +242,6 @@ module Sentry
|
|
238
242
|
@session = session
|
239
243
|
end
|
240
244
|
|
241
|
-
# Returns current transaction name.
|
242
|
-
# The "transaction" here does not refer to `Transaction` objects.
|
243
|
-
# @return [String, nil]
|
244
|
-
def transaction_name
|
245
|
-
@transaction_names.last
|
246
|
-
end
|
247
|
-
|
248
|
-
# Returns current transaction source.
|
249
|
-
# The "transaction" here does not refer to `Transaction` objects.
|
250
|
-
# @return [String, nil]
|
251
|
-
def transaction_source
|
252
|
-
@transaction_sources.last
|
253
|
-
end
|
254
|
-
|
255
245
|
# These are high cardinality and thus bad.
|
256
246
|
# @return [Boolean]
|
257
247
|
def transaction_source_low_quality?
|
@@ -307,8 +297,8 @@ module Sentry
|
|
307
297
|
@user = {}
|
308
298
|
@level = :error
|
309
299
|
@fingerprint = []
|
310
|
-
@
|
311
|
-
@
|
300
|
+
@transaction_name = nil
|
301
|
+
@transaction_source = nil
|
312
302
|
@event_processors = []
|
313
303
|
@rack_env = {}
|
314
304
|
@span = nil
|
@@ -1,19 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Sentry
|
4
|
-
class SessionFlusher
|
5
|
-
include LoggingHelper
|
6
|
-
|
4
|
+
class SessionFlusher < ThreadedPeriodicWorker
|
7
5
|
FLUSH_INTERVAL = 60
|
8
6
|
|
9
7
|
def initialize(configuration, client)
|
10
|
-
|
11
|
-
@exited = false
|
8
|
+
super(configuration.logger, FLUSH_INTERVAL)
|
12
9
|
@client = client
|
13
10
|
@pending_aggregates = {}
|
14
11
|
@release = configuration.release
|
15
12
|
@environment = configuration.environment
|
16
|
-
@logger = configuration.logger
|
17
13
|
|
18
14
|
log_debug("[Sessions] Sessions won't be captured without a valid release") unless @release
|
19
15
|
end
|
@@ -25,30 +21,18 @@ module Sentry
|
|
25
21
|
@pending_aggregates = {}
|
26
22
|
end
|
27
23
|
|
24
|
+
alias_method :run, :flush
|
25
|
+
|
28
26
|
def add_session(session)
|
29
|
-
return if @exited
|
30
27
|
return unless @release
|
31
28
|
|
32
|
-
|
33
|
-
ensure_thread
|
34
|
-
rescue ThreadError
|
35
|
-
log_debug("Session flusher thread creation failed")
|
36
|
-
@exited = true
|
37
|
-
return
|
38
|
-
end
|
29
|
+
return unless ensure_thread
|
39
30
|
|
40
31
|
return unless Session::AGGREGATE_STATUSES.include?(session.status)
|
41
32
|
@pending_aggregates[session.aggregation_key] ||= init_aggregates(session.aggregation_key)
|
42
33
|
@pending_aggregates[session.aggregation_key][session.status] += 1
|
43
34
|
end
|
44
35
|
|
45
|
-
def kill
|
46
|
-
log_debug("Killing session flusher")
|
47
|
-
|
48
|
-
@exited = true
|
49
|
-
@thread&.kill
|
50
|
-
end
|
51
|
-
|
52
36
|
private
|
53
37
|
|
54
38
|
def init_aggregates(aggregation_key)
|
@@ -70,16 +54,5 @@ module Sentry
|
|
70
54
|
def attrs
|
71
55
|
{ release: @release, environment: @environment }
|
72
56
|
end
|
73
|
-
|
74
|
-
def ensure_thread
|
75
|
-
return if @thread&.alive?
|
76
|
-
|
77
|
-
@thread = Thread.new do
|
78
|
-
loop do
|
79
|
-
sleep(FLUSH_INTERVAL)
|
80
|
-
flush
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
57
|
end
|
85
58
|
end
|
data/lib/sentry/span.rb
CHANGED
@@ -39,6 +39,11 @@ module Sentry
|
|
39
39
|
# Recommended: If different than server.port.
|
40
40
|
# Example: 16456
|
41
41
|
SERVER_SOCKET_PORT = "server.socket.port"
|
42
|
+
|
43
|
+
FILEPATH = "code.filepath"
|
44
|
+
LINENO = "code.lineno"
|
45
|
+
FUNCTION = "code.function"
|
46
|
+
NAMESPACE = "code.namespace"
|
42
47
|
end
|
43
48
|
|
44
49
|
STATUS_MAP = {
|
@@ -55,6 +60,8 @@ module Sentry
|
|
55
60
|
504 => "deadline_exceeded"
|
56
61
|
}
|
57
62
|
|
63
|
+
DEFAULT_SPAN_ORIGIN = "manual"
|
64
|
+
|
58
65
|
# An uuid that can be used to identify a trace.
|
59
66
|
# @return [String]
|
60
67
|
attr_reader :trace_id
|
@@ -88,6 +95,9 @@ module Sentry
|
|
88
95
|
# Span data
|
89
96
|
# @return [Hash]
|
90
97
|
attr_reader :data
|
98
|
+
# Span origin that tracks what kind of instrumentation created a span
|
99
|
+
# @return [String]
|
100
|
+
attr_reader :origin
|
91
101
|
|
92
102
|
# The SpanRecorder the current span belongs to.
|
93
103
|
# SpanRecorder holds all spans under the same Transaction object (including the Transaction itself).
|
@@ -109,7 +119,8 @@ module Sentry
|
|
109
119
|
parent_span_id: nil,
|
110
120
|
sampled: nil,
|
111
121
|
start_timestamp: nil,
|
112
|
-
timestamp: nil
|
122
|
+
timestamp: nil,
|
123
|
+
origin: nil
|
113
124
|
)
|
114
125
|
@trace_id = trace_id || SecureRandom.uuid.delete("-")
|
115
126
|
@span_id = span_id || SecureRandom.uuid.delete("-").slice(0, 16)
|
@@ -123,6 +134,7 @@ module Sentry
|
|
123
134
|
@status = status
|
124
135
|
@data = {}
|
125
136
|
@tags = {}
|
137
|
+
@origin = origin || DEFAULT_SPAN_ORIGIN
|
126
138
|
end
|
127
139
|
|
128
140
|
# Finishes the span by adding a timestamp.
|
@@ -160,7 +172,8 @@ module Sentry
|
|
160
172
|
op: @op,
|
161
173
|
status: @status,
|
162
174
|
tags: @tags,
|
163
|
-
data: @data
|
175
|
+
data: @data,
|
176
|
+
origin: @origin
|
164
177
|
}
|
165
178
|
|
166
179
|
summary = metrics_summary
|
@@ -178,7 +191,8 @@ module Sentry
|
|
178
191
|
parent_span_id: @parent_span_id,
|
179
192
|
description: @description,
|
180
193
|
op: @op,
|
181
|
-
status: @status
|
194
|
+
status: @status,
|
195
|
+
origin: @origin
|
182
196
|
}
|
183
197
|
end
|
184
198
|
|
@@ -275,6 +289,12 @@ module Sentry
|
|
275
289
|
@tags[key] = value
|
276
290
|
end
|
277
291
|
|
292
|
+
# Sets the origin of the span.
|
293
|
+
# @param origin [String]
|
294
|
+
def set_origin(origin)
|
295
|
+
@origin = origin
|
296
|
+
end
|
297
|
+
|
278
298
|
# Collects gauge metrics on the span for metric summaries.
|
279
299
|
def metrics_local_aggregator
|
280
300
|
@metrics_local_aggregator ||= Sentry::Metrics::LocalAggregator.new
|
data/lib/sentry/test_helper.rb
CHANGED
@@ -20,7 +20,7 @@ module Sentry
|
|
20
20
|
# set transport to DummyTransport, so we can easily intercept the captured events
|
21
21
|
dummy_config.transport.transport_class = Sentry::DummyTransport
|
22
22
|
# make sure SDK allows sending under the current environment
|
23
|
-
dummy_config.enabled_environments
|
23
|
+
dummy_config.enabled_environments += [dummy_config.environment] unless dummy_config.enabled_environments.include?(dummy_config.environment)
|
24
24
|
# disble async event sending
|
25
25
|
dummy_config.background_worker_threads = 0
|
26
26
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
class ThreadedPeriodicWorker
|
5
|
+
include LoggingHelper
|
6
|
+
|
7
|
+
def initialize(logger, internal)
|
8
|
+
@thread = nil
|
9
|
+
@exited = false
|
10
|
+
@interval = internal
|
11
|
+
@logger = logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def ensure_thread
|
15
|
+
return false if @exited
|
16
|
+
return true if @thread&.alive?
|
17
|
+
|
18
|
+
@thread = Thread.new do
|
19
|
+
loop do
|
20
|
+
sleep(@interval)
|
21
|
+
run
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
true
|
26
|
+
rescue ThreadError
|
27
|
+
log_debug("[#{self.class.name}] thread creation failed")
|
28
|
+
@exited = true
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def kill
|
33
|
+
log_debug("[#{self.class.name}] thread killed")
|
34
|
+
|
35
|
+
@exited = true
|
36
|
+
@thread&.kill
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/sentry/transport.rb
CHANGED
@@ -61,7 +61,7 @@ module Sentry
|
|
61
61
|
data, serialized_items = serialize_envelope(envelope)
|
62
62
|
|
63
63
|
if data
|
64
|
-
|
64
|
+
log_debug("[Transport] Sending envelope with items [#{serialized_items.map(&:type).join(', ')}] #{envelope.event_id} to Sentry")
|
65
65
|
send_data(data)
|
66
66
|
end
|
67
67
|
end
|
data/lib/sentry/version.rb
CHANGED
data/lib/sentry-ruby.rb
CHANGED
@@ -20,6 +20,7 @@ require "sentry/span"
|
|
20
20
|
require "sentry/transaction"
|
21
21
|
require "sentry/hub"
|
22
22
|
require "sentry/background_worker"
|
23
|
+
require "sentry/threaded_periodic_worker"
|
23
24
|
require "sentry/session_flusher"
|
24
25
|
require "sentry/backpressure_monitor"
|
25
26
|
require "sentry/cron/monitor_check_ins"
|
@@ -550,6 +551,15 @@ module Sentry
|
|
550
551
|
get_current_hub.get_trace_propagation_headers
|
551
552
|
end
|
552
553
|
|
554
|
+
# Returns the a Hash containing sentry-trace and baggage.
|
555
|
+
# Can be either from the currently active span or the propagation context.
|
556
|
+
#
|
557
|
+
# @return [String]
|
558
|
+
def get_trace_propagation_meta
|
559
|
+
return '' unless initialized?
|
560
|
+
get_current_hub.get_trace_propagation_meta
|
561
|
+
end
|
562
|
+
|
553
563
|
# Continue an incoming trace from a rack env like hash.
|
554
564
|
#
|
555
565
|
# @param env [Hash]
|
@@ -590,3 +600,4 @@ end
|
|
590
600
|
require "sentry/net/http"
|
591
601
|
require "sentry/redis"
|
592
602
|
require "sentry/puma"
|
603
|
+
require "sentry/graphql"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sentry-ruby-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sentry Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sentry-ruby
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
19
|
+
version: 5.18.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
26
|
+
version: 5.18.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: concurrent-ruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- lib/sentry/error_event.rb
|
80
80
|
- lib/sentry/event.rb
|
81
81
|
- lib/sentry/exceptions.rb
|
82
|
+
- lib/sentry/graphql.rb
|
82
83
|
- lib/sentry/hub.rb
|
83
84
|
- lib/sentry/integrable.rb
|
84
85
|
- lib/sentry/interface.rb
|
@@ -115,6 +116,7 @@ files:
|
|
115
116
|
- lib/sentry/session_flusher.rb
|
116
117
|
- lib/sentry/span.rb
|
117
118
|
- lib/sentry/test_helper.rb
|
119
|
+
- lib/sentry/threaded_periodic_worker.rb
|
118
120
|
- lib/sentry/transaction.rb
|
119
121
|
- lib/sentry/transaction_event.rb
|
120
122
|
- lib/sentry/transport.rb
|
@@ -154,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
156
|
- !ruby/object:Gem::Version
|
155
157
|
version: '0'
|
156
158
|
requirements: []
|
157
|
-
rubygems_version: 3.
|
159
|
+
rubygems_version: 3.5.11
|
158
160
|
signing_key:
|
159
161
|
specification_version: 4
|
160
162
|
summary: A gem that provides a client interface for the Sentry error logger
|