sentry-ruby 5.4.2 → 5.16.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/.rspec +0 -1
- data/Gemfile +13 -14
- data/README.md +11 -8
- data/Rakefile +8 -1
- data/lib/sentry/background_worker.rb +8 -1
- data/lib/sentry/backpressure_monitor.rb +75 -0
- data/lib/sentry/backtrace.rb +1 -1
- data/lib/sentry/baggage.rb +70 -0
- data/lib/sentry/breadcrumb.rb +8 -2
- data/lib/sentry/check_in_event.rb +60 -0
- data/lib/sentry/client.rb +77 -19
- data/lib/sentry/configuration.rb +177 -29
- data/lib/sentry/cron/configuration.rb +23 -0
- data/lib/sentry/cron/monitor_check_ins.rb +75 -0
- data/lib/sentry/cron/monitor_config.rb +53 -0
- data/lib/sentry/cron/monitor_schedule.rb +42 -0
- data/lib/sentry/envelope.rb +2 -5
- data/lib/sentry/event.rb +7 -29
- data/lib/sentry/hub.rb +100 -4
- data/lib/sentry/integrable.rb +6 -0
- data/lib/sentry/interfaces/request.rb +6 -16
- data/lib/sentry/interfaces/single_exception.rb +13 -3
- data/lib/sentry/net/http.rb +37 -46
- data/lib/sentry/profiler.rb +233 -0
- data/lib/sentry/propagation_context.rb +134 -0
- data/lib/sentry/puma.rb +32 -0
- data/lib/sentry/rack/capture_exceptions.rb +4 -5
- data/lib/sentry/rake.rb +1 -14
- data/lib/sentry/redis.rb +41 -23
- data/lib/sentry/release_detector.rb +1 -1
- data/lib/sentry/scope.rb +81 -16
- data/lib/sentry/session.rb +5 -7
- data/lib/sentry/span.rb +57 -10
- data/lib/sentry/test_helper.rb +19 -11
- data/lib/sentry/transaction.rb +183 -30
- data/lib/sentry/transaction_event.rb +51 -0
- data/lib/sentry/transport/configuration.rb +74 -1
- data/lib/sentry/transport/http_transport.rb +68 -37
- data/lib/sentry/transport/spotlight_transport.rb +50 -0
- data/lib/sentry/transport.rb +39 -24
- data/lib/sentry/utils/argument_checking_helper.rb +9 -3
- data/lib/sentry/utils/encoding_helper.rb +22 -0
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +116 -41
- metadata +14 -3
- data/CODE_OF_CONDUCT.md +0 -74
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sentry/baggage"
|
5
|
+
|
6
|
+
module Sentry
|
7
|
+
class PropagationContext
|
8
|
+
SENTRY_TRACE_REGEXP = Regexp.new(
|
9
|
+
"^[ \t]*" + # whitespace
|
10
|
+
"([0-9a-f]{32})?" + # trace_id
|
11
|
+
"-?([0-9a-f]{16})?" + # span_id
|
12
|
+
"-?([01])?" + # sampled
|
13
|
+
"[ \t]*$" # whitespace
|
14
|
+
)
|
15
|
+
|
16
|
+
# An uuid that can be used to identify a trace.
|
17
|
+
# @return [String]
|
18
|
+
attr_reader :trace_id
|
19
|
+
# An uuid that can be used to identify the span.
|
20
|
+
# @return [String]
|
21
|
+
attr_reader :span_id
|
22
|
+
# Span parent's span_id.
|
23
|
+
# @return [String, nil]
|
24
|
+
attr_reader :parent_span_id
|
25
|
+
# The sampling decision of the parent transaction.
|
26
|
+
# @return [Boolean, nil]
|
27
|
+
attr_reader :parent_sampled
|
28
|
+
# Is there an incoming trace or not?
|
29
|
+
# @return [Boolean]
|
30
|
+
attr_reader :incoming_trace
|
31
|
+
# This is only for accessing the current baggage variable.
|
32
|
+
# Please use the #get_baggage method for interfacing outside this class.
|
33
|
+
# @return [Baggage, nil]
|
34
|
+
attr_reader :baggage
|
35
|
+
|
36
|
+
def initialize(scope, env = nil)
|
37
|
+
@scope = scope
|
38
|
+
@parent_span_id = nil
|
39
|
+
@parent_sampled = nil
|
40
|
+
@baggage = nil
|
41
|
+
@incoming_trace = false
|
42
|
+
|
43
|
+
if env
|
44
|
+
sentry_trace_header = env["HTTP_SENTRY_TRACE"] || env[SENTRY_TRACE_HEADER_NAME]
|
45
|
+
baggage_header = env["HTTP_BAGGAGE"] || env[BAGGAGE_HEADER_NAME]
|
46
|
+
|
47
|
+
if sentry_trace_header
|
48
|
+
sentry_trace_data = self.class.extract_sentry_trace(sentry_trace_header)
|
49
|
+
|
50
|
+
if sentry_trace_data
|
51
|
+
@trace_id, @parent_span_id, @parent_sampled = sentry_trace_data
|
52
|
+
|
53
|
+
@baggage = if baggage_header && !baggage_header.empty?
|
54
|
+
Baggage.from_incoming_header(baggage_header)
|
55
|
+
else
|
56
|
+
# If there's an incoming sentry-trace but no incoming baggage header,
|
57
|
+
# for instance in traces coming from older SDKs,
|
58
|
+
# baggage will be empty and frozen and won't be populated as head SDK.
|
59
|
+
Baggage.new({})
|
60
|
+
end
|
61
|
+
|
62
|
+
@baggage.freeze!
|
63
|
+
@incoming_trace = true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@trace_id ||= SecureRandom.uuid.delete("-")
|
69
|
+
@span_id = SecureRandom.uuid.delete("-").slice(0, 16)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Extract the trace_id, parent_span_id and parent_sampled values from a sentry-trace header.
|
73
|
+
#
|
74
|
+
# @param sentry_trace [String] the sentry-trace header value from the previous transaction.
|
75
|
+
# @return [Array, nil]
|
76
|
+
def self.extract_sentry_trace(sentry_trace)
|
77
|
+
match = SENTRY_TRACE_REGEXP.match(sentry_trace)
|
78
|
+
return nil if match.nil?
|
79
|
+
|
80
|
+
trace_id, parent_span_id, sampled_flag = match[1..3]
|
81
|
+
parent_sampled = sampled_flag.nil? ? nil : sampled_flag != "0"
|
82
|
+
|
83
|
+
[trace_id, parent_span_id, parent_sampled]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the trace context that can be used to embed in an Event.
|
87
|
+
# @return [Hash]
|
88
|
+
def get_trace_context
|
89
|
+
{
|
90
|
+
trace_id: trace_id,
|
91
|
+
span_id: span_id,
|
92
|
+
parent_span_id: parent_span_id
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns the sentry-trace header from the propagation context.
|
97
|
+
# @return [String]
|
98
|
+
def get_traceparent
|
99
|
+
"#{trace_id}-#{span_id}"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the Baggage from the propagation context or populates as head SDK if empty.
|
103
|
+
# @return [Baggage, nil]
|
104
|
+
def get_baggage
|
105
|
+
populate_head_baggage if @baggage.nil? || @baggage.mutable
|
106
|
+
@baggage
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns the Dynamic Sampling Context from the baggage.
|
110
|
+
# @return [String, nil]
|
111
|
+
def get_dynamic_sampling_context
|
112
|
+
get_baggage&.dynamic_sampling_context
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def populate_head_baggage
|
118
|
+
return unless Sentry.initialized?
|
119
|
+
|
120
|
+
configuration = Sentry.configuration
|
121
|
+
|
122
|
+
items = {
|
123
|
+
"trace_id" => trace_id,
|
124
|
+
"environment" => configuration.environment,
|
125
|
+
"release" => configuration.release,
|
126
|
+
"public_key" => configuration.dsn&.public_key,
|
127
|
+
"user_segment" => @scope.user && @scope.user["segment"]
|
128
|
+
}
|
129
|
+
|
130
|
+
items.compact!
|
131
|
+
@baggage = Baggage.new(items, mutable: false)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/sentry/puma.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
return unless defined?(Puma::Server)
|
4
|
+
|
5
|
+
module Sentry
|
6
|
+
module Puma
|
7
|
+
module Server
|
8
|
+
PUMA_4_AND_PRIOR = Gem::Version.new(::Puma::Const::PUMA_VERSION) < Gem::Version.new("5.0.0")
|
9
|
+
|
10
|
+
def lowlevel_error(e, env, status=500)
|
11
|
+
result =
|
12
|
+
if PUMA_4_AND_PRIOR
|
13
|
+
super(e, env)
|
14
|
+
else
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
Sentry.capture_exception(e) do |scope|
|
20
|
+
scope.set_rack_env(env)
|
21
|
+
end
|
22
|
+
rescue
|
23
|
+
# if anything happens, we don't want to break the app
|
24
|
+
end
|
25
|
+
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Sentry.register_patch(:puma, Sentry::Puma::Server, Puma::Server)
|
@@ -18,7 +18,7 @@ module Sentry
|
|
18
18
|
Sentry.with_scope do |scope|
|
19
19
|
Sentry.with_session_tracking do
|
20
20
|
scope.clear_breadcrumbs
|
21
|
-
scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
|
21
|
+
scope.set_transaction_name(env["PATH_INFO"], source: :url) if env["PATH_INFO"]
|
22
22
|
scope.set_rack_env(env)
|
23
23
|
|
24
24
|
transaction = start_transaction(env, scope)
|
@@ -52,7 +52,7 @@ module Sentry
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def transaction_op
|
55
|
-
"
|
55
|
+
"http.server".freeze
|
56
56
|
end
|
57
57
|
|
58
58
|
def capture_exception(exception, env)
|
@@ -62,9 +62,8 @@ module Sentry
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def start_transaction(env, scope)
|
65
|
-
|
66
|
-
|
67
|
-
transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, **options) if sentry_trace
|
65
|
+
options = { name: scope.transaction_name, source: scope.transaction_source, op: transaction_op }
|
66
|
+
transaction = Sentry.continue_trace(env, **options)
|
68
67
|
Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
|
69
68
|
end
|
70
69
|
|
data/lib/sentry/rake.rb
CHANGED
@@ -10,22 +10,13 @@ module Sentry
|
|
10
10
|
def display_error_message(ex)
|
11
11
|
Sentry.capture_exception(ex) do |scope|
|
12
12
|
task_name = top_level_tasks.join(' ')
|
13
|
-
scope.set_transaction_name(task_name)
|
13
|
+
scope.set_transaction_name(task_name, source: :task)
|
14
14
|
scope.set_tag("rake_task", task_name)
|
15
15
|
end if Sentry.initialized? && !Sentry.configuration.skip_rake_integration
|
16
16
|
|
17
17
|
super
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
|
-
module Task
|
22
|
-
# @api private
|
23
|
-
def execute(args=nil)
|
24
|
-
return super unless Sentry.initialized? && Sentry.get_current_hub
|
25
|
-
|
26
|
-
super
|
27
|
-
end
|
28
|
-
end
|
29
20
|
end
|
30
21
|
end
|
31
22
|
|
@@ -34,8 +25,4 @@ module Rake
|
|
34
25
|
class Application
|
35
26
|
prepend(Sentry::Rake::Application)
|
36
27
|
end
|
37
|
-
|
38
|
-
class Task
|
39
|
-
prepend(Sentry::Rake::Task)
|
40
|
-
end
|
41
28
|
end
|
data/lib/sentry/redis.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Sentry
|
4
4
|
# @api private
|
5
5
|
class Redis
|
6
|
-
OP_NAME = "db.redis
|
6
|
+
OP_NAME = "db.redis"
|
7
7
|
LOGGER_NAME = :redis_logger
|
8
8
|
|
9
9
|
def initialize(commands, host, port, db)
|
@@ -13,9 +13,17 @@ module Sentry
|
|
13
13
|
def instrument
|
14
14
|
return yield unless Sentry.initialized?
|
15
15
|
|
16
|
-
|
16
|
+
Sentry.with_child_span(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f) do |span|
|
17
17
|
yield.tap do
|
18
18
|
record_breadcrumb
|
19
|
+
|
20
|
+
if span
|
21
|
+
span.set_description(commands_description)
|
22
|
+
span.set_data(Span::DataConventions::DB_SYSTEM, "redis")
|
23
|
+
span.set_data(Span::DataConventions::DB_NAME, db)
|
24
|
+
span.set_data(Span::DataConventions::SERVER_ADDRESS, host)
|
25
|
+
span.set_data(Span::DataConventions::SERVER_PORT, port)
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
@@ -24,19 +32,8 @@ module Sentry
|
|
24
32
|
|
25
33
|
attr_reader :commands, :host, :port, :db
|
26
34
|
|
27
|
-
def record_span
|
28
|
-
return yield unless (transaction = Sentry.get_current_scope.get_transaction) && transaction.sampled
|
29
|
-
|
30
|
-
sentry_span = transaction.start_child(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f)
|
31
|
-
|
32
|
-
yield.tap do
|
33
|
-
sentry_span.set_description(commands_description)
|
34
|
-
sentry_span.set_data(:server, server_description)
|
35
|
-
sentry_span.set_timestamp(Sentry.utc_now.to_f)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
35
|
def record_breadcrumb
|
36
|
+
return unless Sentry.initialized?
|
40
37
|
return unless Sentry.configuration.breadcrumbs_logger.include?(LOGGER_NAME)
|
41
38
|
|
42
39
|
Sentry.add_breadcrumb(
|
@@ -61,10 +58,16 @@ module Sentry
|
|
61
58
|
def parsed_commands
|
62
59
|
commands.map do |statement|
|
63
60
|
command, key, *arguments = statement
|
61
|
+
command_set = { command: command.to_s.upcase }
|
62
|
+
command_set[:key] = key if Utils::EncodingHelper.valid_utf_8?(key)
|
64
63
|
|
65
|
-
|
66
|
-
command_set[:arguments] = arguments
|
64
|
+
if Sentry.configuration.send_default_pii
|
65
|
+
command_set[:arguments] = arguments
|
66
|
+
.select { |a| Utils::EncodingHelper.valid_utf_8?(a) }
|
67
|
+
.join(" ")
|
67
68
|
end
|
69
|
+
|
70
|
+
command_set
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
@@ -72,19 +75,34 @@ module Sentry
|
|
72
75
|
"#{host}:#{port}/#{db}"
|
73
76
|
end
|
74
77
|
|
75
|
-
module
|
78
|
+
module OldClientPatch
|
76
79
|
def logging(commands, &block)
|
77
|
-
Sentry::Redis.new(commands, host, port, db).instrument
|
78
|
-
|
79
|
-
|
80
|
+
Sentry::Redis.new(commands, host, port, db).instrument { super }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
module GlobalRedisInstrumentation
|
85
|
+
def call(command, redis_config)
|
86
|
+
Sentry::Redis
|
87
|
+
.new([command], redis_config.host, redis_config.port, redis_config.db)
|
88
|
+
.instrument { super }
|
89
|
+
end
|
90
|
+
|
91
|
+
def call_pipelined(commands, redis_config)
|
92
|
+
Sentry::Redis
|
93
|
+
.new(commands, redis_config.host, redis_config.port, redis_config.db)
|
94
|
+
.instrument { super }
|
80
95
|
end
|
81
96
|
end
|
82
97
|
end
|
83
98
|
end
|
84
99
|
|
85
100
|
if defined?(::Redis::Client)
|
86
|
-
|
87
|
-
|
88
|
-
|
101
|
+
if Gem::Version.new(::Redis::VERSION) < Gem::Version.new("5.0")
|
102
|
+
Sentry.register_patch(:redis, Sentry::Redis::OldClientPatch, ::Redis::Client)
|
103
|
+
elsif defined?(RedisClient)
|
104
|
+
Sentry.register_patch(:redis) do
|
105
|
+
RedisClient.register(Sentry::Redis::GlobalRedisInstrumentation)
|
106
|
+
end
|
89
107
|
end
|
90
108
|
end
|
data/lib/sentry/scope.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "sentry/breadcrumb_buffer"
|
4
|
+
require "sentry/propagation_context"
|
4
5
|
require "etc"
|
5
6
|
|
6
7
|
module Sentry
|
7
8
|
class Scope
|
8
9
|
include ArgumentCheckingHelper
|
9
10
|
|
10
|
-
ATTRIBUTES = [
|
11
|
+
ATTRIBUTES = [
|
12
|
+
:transaction_names,
|
13
|
+
:transaction_sources,
|
14
|
+
:contexts,
|
15
|
+
:extra,
|
16
|
+
:tags,
|
17
|
+
:user,
|
18
|
+
:level,
|
19
|
+
:breadcrumbs,
|
20
|
+
:fingerprint,
|
21
|
+
:event_processors,
|
22
|
+
:rack_env,
|
23
|
+
:span,
|
24
|
+
:session,
|
25
|
+
:propagation_context
|
26
|
+
]
|
11
27
|
|
12
28
|
attr_reader(*ATTRIBUTES)
|
13
29
|
|
@@ -28,23 +44,30 @@ module Sentry
|
|
28
44
|
# @param hint [Hash] the hint data that'll be passed to event processors.
|
29
45
|
# @return [Event]
|
30
46
|
def apply_to_event(event, hint = nil)
|
31
|
-
event.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
47
|
+
unless event.is_a?(CheckInEvent)
|
48
|
+
event.tags = tags.merge(event.tags)
|
49
|
+
event.user = user.merge(event.user)
|
50
|
+
event.extra = extra.merge(event.extra)
|
51
|
+
event.contexts = contexts.merge(event.contexts)
|
52
|
+
event.transaction = transaction_name if transaction_name
|
53
|
+
event.transaction_info = { source: transaction_source } if transaction_source
|
54
|
+
event.fingerprint = fingerprint
|
55
|
+
event.level = level
|
56
|
+
event.breadcrumbs = breadcrumbs
|
57
|
+
event.rack_env = rack_env if rack_env
|
58
|
+
end
|
36
59
|
|
37
60
|
if span
|
38
|
-
event.contexts[:trace]
|
61
|
+
event.contexts[:trace] ||= span.get_trace_context
|
62
|
+
else
|
63
|
+
event.contexts[:trace] ||= propagation_context.get_trace_context
|
64
|
+
event.dynamic_sampling_context ||= propagation_context.get_dynamic_sampling_context
|
39
65
|
end
|
40
66
|
|
41
|
-
|
42
|
-
event.level = level
|
43
|
-
event.breadcrumbs = breadcrumbs
|
44
|
-
event.rack_env = rack_env if rack_env
|
67
|
+
all_event_processors = self.class.global_event_processors + @event_processors
|
45
68
|
|
46
|
-
unless
|
47
|
-
|
69
|
+
unless all_event_processors.empty?
|
70
|
+
all_event_processors.each do |processor_block|
|
48
71
|
event = processor_block.call(event, hint)
|
49
72
|
end
|
50
73
|
end
|
@@ -73,10 +96,12 @@ module Sentry
|
|
73
96
|
copy.extra = extra.deep_dup
|
74
97
|
copy.tags = tags.deep_dup
|
75
98
|
copy.user = user.deep_dup
|
76
|
-
copy.transaction_names = transaction_names.
|
99
|
+
copy.transaction_names = transaction_names.dup
|
100
|
+
copy.transaction_sources = transaction_sources.dup
|
77
101
|
copy.fingerprint = fingerprint.deep_dup
|
78
102
|
copy.span = span.deep_dup
|
79
103
|
copy.session = session.deep_dup
|
104
|
+
copy.propagation_context = propagation_context.deep_dup
|
80
105
|
copy
|
81
106
|
end
|
82
107
|
|
@@ -90,8 +115,10 @@ module Sentry
|
|
90
115
|
self.tags = scope.tags
|
91
116
|
self.user = scope.user
|
92
117
|
self.transaction_names = scope.transaction_names
|
118
|
+
self.transaction_sources = scope.transaction_sources
|
93
119
|
self.fingerprint = scope.fingerprint
|
94
120
|
self.span = scope.span
|
121
|
+
self.propagation_context = scope.propagation_context
|
95
122
|
end
|
96
123
|
|
97
124
|
# Updates the scope's data from the given options.
|
@@ -173,6 +200,10 @@ module Sentry
|
|
173
200
|
# @return [Hash]
|
174
201
|
def set_contexts(contexts_hash)
|
175
202
|
check_argument_type!(contexts_hash, Hash)
|
203
|
+
contexts_hash.values.each do |val|
|
204
|
+
check_argument_type!(val, Hash)
|
205
|
+
end
|
206
|
+
|
176
207
|
@contexts.merge!(contexts_hash) do |key, old, new|
|
177
208
|
old.merge(new)
|
178
209
|
end
|
@@ -195,8 +226,9 @@ module Sentry
|
|
195
226
|
# The "transaction" here does not refer to `Transaction` objects.
|
196
227
|
# @param transaction_name [String]
|
197
228
|
# @return [void]
|
198
|
-
def set_transaction_name(transaction_name)
|
229
|
+
def set_transaction_name(transaction_name, source: :custom)
|
199
230
|
@transaction_names << transaction_name
|
231
|
+
@transaction_sources << source
|
200
232
|
end
|
201
233
|
|
202
234
|
# Sets the currently active session on the scope.
|
@@ -213,6 +245,13 @@ module Sentry
|
|
213
245
|
@transaction_names.last
|
214
246
|
end
|
215
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
|
+
|
216
255
|
# Returns the associated Transaction object.
|
217
256
|
# @return [Transaction, nil]
|
218
257
|
def get_transaction
|
@@ -241,6 +280,13 @@ module Sentry
|
|
241
280
|
@event_processors << block
|
242
281
|
end
|
243
282
|
|
283
|
+
# Generate a new propagation context either from the incoming env headers or from scratch.
|
284
|
+
# @param env [Hash, nil]
|
285
|
+
# @return [void]
|
286
|
+
def generate_propagation_context(env = nil)
|
287
|
+
@propagation_context = PropagationContext.new(self, env)
|
288
|
+
end
|
289
|
+
|
244
290
|
protected
|
245
291
|
|
246
292
|
# for duplicating scopes internally
|
@@ -256,10 +302,12 @@ module Sentry
|
|
256
302
|
@level = :error
|
257
303
|
@fingerprint = []
|
258
304
|
@transaction_names = []
|
305
|
+
@transaction_sources = []
|
259
306
|
@event_processors = []
|
260
307
|
@rack_env = {}
|
261
308
|
@span = nil
|
262
309
|
@session = nil
|
310
|
+
generate_propagation_context
|
263
311
|
set_new_breadcrumb_buffer
|
264
312
|
end
|
265
313
|
|
@@ -277,7 +325,8 @@ module Sentry
|
|
277
325
|
name: uname[:sysname] || RbConfig::CONFIG["host_os"],
|
278
326
|
version: uname[:version],
|
279
327
|
build: uname[:release],
|
280
|
-
kernel_version: uname[:version]
|
328
|
+
kernel_version: uname[:version],
|
329
|
+
machine: uname[:machine]
|
281
330
|
}
|
282
331
|
end
|
283
332
|
end
|
@@ -289,6 +338,22 @@ module Sentry
|
|
289
338
|
version: RUBY_DESCRIPTION || Sentry.sys_command("ruby -v")
|
290
339
|
}
|
291
340
|
end
|
341
|
+
|
342
|
+
# Returns the global event processors array.
|
343
|
+
# @return [Array<Proc>]
|
344
|
+
def global_event_processors
|
345
|
+
@global_event_processors ||= []
|
346
|
+
end
|
347
|
+
|
348
|
+
# Adds a new global event processor [Proc].
|
349
|
+
# Sometimes we need a global event processor without needing to configure scope.
|
350
|
+
# These run before scope event processors.
|
351
|
+
#
|
352
|
+
# @param block [Proc]
|
353
|
+
# @return [void]
|
354
|
+
def add_global_event_processor(&block)
|
355
|
+
global_event_processors << block
|
356
|
+
end
|
292
357
|
end
|
293
358
|
|
294
359
|
end
|
data/lib/sentry/session.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class Session
|
5
|
-
attr_reader :started, :status
|
5
|
+
attr_reader :started, :status, :aggregation_key
|
6
6
|
|
7
7
|
# TODO-neel add :crashed after adding handled mechanism
|
8
8
|
STATUSES = %i(ok errored exited)
|
@@ -11,6 +11,10 @@ module Sentry
|
|
11
11
|
def initialize
|
12
12
|
@started = Sentry.utc_now
|
13
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)
|
14
18
|
end
|
15
19
|
|
16
20
|
# TODO-neel add :crashed after adding handled mechanism
|
@@ -22,12 +26,6 @@ module Sentry
|
|
22
26
|
@status = :exited if @status == :ok
|
23
27
|
end
|
24
28
|
|
25
|
-
# truncate seconds from the timestamp since we only care about
|
26
|
-
# minute level granularity for aggregation
|
27
|
-
def aggregation_key
|
28
|
-
Time.utc(started.year, started.month, started.day, started.hour, started.min)
|
29
|
-
end
|
30
|
-
|
31
29
|
def deep_dup
|
32
30
|
dup
|
33
31
|
end
|