sentry-ruby 0.3.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +102 -24
  3. metadata +41 -54
  4. data/.craft.yml +0 -19
  5. data/.gitignore +0 -11
  6. data/.rspec +0 -3
  7. data/.travis.yml +0 -6
  8. data/CHANGELOG.md +0 -31
  9. data/CODE_OF_CONDUCT.md +0 -74
  10. data/Gemfile +0 -16
  11. data/Rakefile +0 -8
  12. data/bin/console +0 -14
  13. data/bin/setup +0 -8
  14. data/lib/sentry/backtrace.rb +0 -128
  15. data/lib/sentry/benchmarks/benchmark_transport.rb +0 -14
  16. data/lib/sentry/breadcrumb/sentry_logger.rb +0 -87
  17. data/lib/sentry/breadcrumb.rb +0 -25
  18. data/lib/sentry/breadcrumb_buffer.rb +0 -47
  19. data/lib/sentry/client.rb +0 -80
  20. data/lib/sentry/configuration.rb +0 -387
  21. data/lib/sentry/core_ext/object/deep_dup.rb +0 -57
  22. data/lib/sentry/core_ext/object/duplicable.rb +0 -153
  23. data/lib/sentry/dsn.rb +0 -48
  24. data/lib/sentry/event.rb +0 -177
  25. data/lib/sentry/hub.rb +0 -137
  26. data/lib/sentry/interface.rb +0 -22
  27. data/lib/sentry/interfaces/exception.rb +0 -11
  28. data/lib/sentry/interfaces/request.rb +0 -95
  29. data/lib/sentry/interfaces/single_exception.rb +0 -14
  30. data/lib/sentry/interfaces/stacktrace.rb +0 -57
  31. data/lib/sentry/linecache.rb +0 -44
  32. data/lib/sentry/logger.rb +0 -20
  33. data/lib/sentry/rack/capture_exception.rb +0 -45
  34. data/lib/sentry/rack/tracing.rb +0 -39
  35. data/lib/sentry/rack.rb +0 -5
  36. data/lib/sentry/scope.rb +0 -214
  37. data/lib/sentry/span.rb +0 -155
  38. data/lib/sentry/transaction.rb +0 -113
  39. data/lib/sentry/transaction_event.rb +0 -29
  40. data/lib/sentry/transport/configuration.rb +0 -21
  41. data/lib/sentry/transport/dummy_transport.rb +0 -14
  42. data/lib/sentry/transport/http_transport.rb +0 -65
  43. data/lib/sentry/transport/state.rb +0 -40
  44. data/lib/sentry/transport.rb +0 -97
  45. data/lib/sentry/utils/exception_cause_chain.rb +0 -20
  46. data/lib/sentry/utils/real_ip.rb +0 -70
  47. data/lib/sentry/utils/request_id.rb +0 -16
  48. data/lib/sentry/version.rb +0 -3
  49. data/lib/sentry-ruby.rb +0 -123
  50. data/sentry-ruby.gemspec +0 -26
data/lib/sentry/scope.rb DELETED
@@ -1,214 +0,0 @@
1
- require "sentry/breadcrumb_buffer"
2
- require "etc"
3
-
4
- module Sentry
5
- class Scope
6
- ATTRIBUTES = [:transaction_names, :contexts, :extra, :tags, :user, :level, :breadcrumbs, :fingerprint, :event_processors, :rack_env, :span]
7
-
8
- attr_reader(*ATTRIBUTES)
9
-
10
- def initialize
11
- set_default_value
12
- end
13
-
14
- def clear
15
- set_default_value
16
- end
17
-
18
- def apply_to_event(event, hint = nil)
19
- event.tags = tags.merge(event.tags)
20
- event.user = user.merge(event.user)
21
- event.extra = extra.merge(event.extra)
22
- event.contexts = contexts.merge(event.contexts)
23
-
24
- if span
25
- event.contexts[:trace] = span.get_trace_context
26
- end
27
-
28
- event.fingerprint = fingerprint
29
- event.level = level
30
- event.transaction = transaction_names.last
31
- event.breadcrumbs = breadcrumbs
32
- event.rack_env = rack_env
33
-
34
- unless @event_processors.empty?
35
- @event_processors.each do |processor_block|
36
- event = processor_block.call(event, hint)
37
- end
38
- end
39
-
40
- event
41
- end
42
-
43
- def add_breadcrumb(breadcrumb)
44
- breadcrumbs.record(breadcrumb)
45
- end
46
-
47
- def clear_breadcrumbs
48
- @breadcrumbs = BreadcrumbBuffer.new
49
- end
50
-
51
- def dup
52
- copy = super
53
- copy.breadcrumbs = breadcrumbs.dup
54
- copy.contexts = contexts.deep_dup
55
- copy.extra = extra.deep_dup
56
- copy.tags = tags.deep_dup
57
- copy.user = user.deep_dup
58
- copy.transaction_names = transaction_names.deep_dup
59
- copy.fingerprint = fingerprint.deep_dup
60
- copy.span = span
61
- copy
62
- end
63
-
64
- def update_from_scope(scope)
65
- self.breadcrumbs = scope.breadcrumbs
66
- self.contexts = scope.contexts
67
- self.extra = scope.extra
68
- self.tags = scope.tags
69
- self.user = scope.user
70
- self.transaction_names = scope.transaction_names
71
- self.fingerprint = scope.fingerprint
72
- self.span = scope.span
73
- end
74
-
75
- def update_from_options(
76
- contexts: nil,
77
- extra: nil,
78
- tags: nil,
79
- user: nil,
80
- level: nil,
81
- fingerprint: nil
82
- )
83
- self.contexts.merge!(contexts) if contexts
84
- self.extra.merge!(extra) if extra
85
- self.tags.merge!(tags) if tags
86
- self.user = user if user
87
- self.level = level if level
88
- self.fingerprint = fingerprint if fingerprint
89
- end
90
-
91
- def set_rack_env(env)
92
- env = env || {}
93
- @rack_env = env
94
- end
95
-
96
- def set_span(span)
97
- check_argument_type!(span, Span)
98
- @span = span
99
- end
100
-
101
- def set_user(user_hash)
102
- check_argument_type!(user_hash, Hash)
103
- @user = user_hash
104
- end
105
-
106
- def set_extras(extras_hash)
107
- check_argument_type!(extras_hash, Hash)
108
- @extra.merge!(extras_hash)
109
- end
110
-
111
- def set_extra(key, value)
112
- @extra.merge!(key => value)
113
- end
114
-
115
- def set_tags(tags_hash)
116
- check_argument_type!(tags_hash, Hash)
117
- @tags.merge!(tags_hash)
118
- end
119
-
120
- def set_tag(key, value)
121
- @tags.merge!(key => value)
122
- end
123
-
124
- def set_contexts(contexts_hash)
125
- check_argument_type!(contexts_hash, Hash)
126
- @contexts = contexts_hash
127
- end
128
-
129
- def set_context(key, value)
130
- @contexts.merge!(key => value)
131
- end
132
-
133
- def set_level(level)
134
- @level = level
135
- end
136
-
137
- def set_transaction_name(transaction_name)
138
- @transaction_names << transaction_name
139
- end
140
-
141
- def transaction_name
142
- @transaction_names.last
143
- end
144
-
145
- def get_transaction
146
- # transaction will always be the first in the span_recorder
147
- span.span_recorder.spans.first if span
148
- end
149
-
150
- def get_span
151
- span
152
- end
153
-
154
- def set_fingerprint(fingerprint)
155
- check_argument_type!(fingerprint, Array)
156
-
157
- @fingerprint = fingerprint
158
- end
159
-
160
- def add_event_processor(&block)
161
- @event_processors << block
162
- end
163
-
164
- protected
165
-
166
- # for duplicating scopes internally
167
- attr_writer(*ATTRIBUTES)
168
-
169
- private
170
-
171
- def check_argument_type!(argument, expected_type)
172
- unless argument.is_a?(expected_type)
173
- raise ArgumentError, "expect the argument to be a #{expected_type}, got #{argument.class} (#{argument})"
174
- end
175
- end
176
-
177
- def set_default_value
178
- @breadcrumbs = BreadcrumbBuffer.new
179
- @contexts = { :os => self.class.os_context, :runtime => self.class.runtime_context }
180
- @extra = {}
181
- @tags = {}
182
- @user = {}
183
- @level = :error
184
- @fingerprint = []
185
- @transaction_names = []
186
- @event_processors = []
187
- @rack_env = {}
188
- @span = nil
189
- end
190
-
191
- class << self
192
- def os_context
193
- @os_context ||=
194
- begin
195
- uname = Etc.uname
196
- {
197
- name: uname[:sysname] || RbConfig::CONFIG["host_os"],
198
- version: uname[:version],
199
- build: uname[:release],
200
- kernel_version: uname[:version]
201
- }
202
- end
203
- end
204
-
205
- def runtime_context
206
- @runtime_context ||= {
207
- name: RbConfig::CONFIG["ruby_install_name"],
208
- version: RUBY_DESCRIPTION || Sentry.sys_command("ruby -v")
209
- }
210
- end
211
- end
212
-
213
- end
214
- end
data/lib/sentry/span.rb DELETED
@@ -1,155 +0,0 @@
1
- # frozen_string_literal: true
2
- require "securerandom"
3
-
4
- module Sentry
5
- class Span
6
- STATUS_MAP = {
7
- 400 => "invalid_argument",
8
- 401 => "unauthenticated",
9
- 403 => "permission_denied",
10
- 404 => "not_found",
11
- 409 => "already_exists",
12
- 429 => "resource_exhausted",
13
- 499 => "cancelled",
14
- 500 => "internal_error",
15
- 501 => "unimplemented",
16
- 503 => "unavailable",
17
- 504 => "deadline_exceeded"
18
- }
19
-
20
-
21
- attr_reader :trace_id, :span_id, :parent_span_id, :sampled, :start_timestamp, :timestamp, :description, :op, :status, :tags, :data
22
- attr_accessor :span_recorder
23
-
24
- def initialize(description: nil, op: nil, status: nil, trace_id: nil, parent_span_id: nil, sampled: nil, start_timestamp: nil, timestamp: nil)
25
- @trace_id = trace_id || SecureRandom.uuid.delete("-")
26
- @span_id = SecureRandom.hex(8)
27
- @parent_span_id = parent_span_id
28
- @sampled = sampled
29
- @start_timestamp = start_timestamp || Sentry.utc_now.to_f
30
- @timestamp = timestamp
31
- @description = description
32
- @op = op
33
- @status = status
34
- @data = {}
35
- @tags = {}
36
- end
37
-
38
- def set_span_recorder
39
- @span_recorder = SpanRecorder.new(1000)
40
- @span_recorder.add(self)
41
- end
42
-
43
- def finish
44
- # already finished
45
- return if @timestamp
46
-
47
- @timestamp = Sentry.utc_now.to_f
48
- self
49
- end
50
-
51
- def to_sentry_trace
52
- sampled_flag = ""
53
- sampled_flag = @sampled ? 1 : 0 unless @sampled.nil?
54
-
55
- "#{@trace_id}-#{@span_id}-#{sampled_flag}"
56
- end
57
-
58
- def to_hash
59
- {
60
- trace_id: @trace_id,
61
- span_id: @span_id,
62
- parent_span_id: @parent_span_id,
63
- start_timestamp: @start_timestamp,
64
- timestamp: @timestamp,
65
- description: @description,
66
- op: @op,
67
- status: @status,
68
- tags: @tags,
69
- data: @data
70
- }
71
- end
72
-
73
- def get_trace_context
74
- {
75
- trace_id: @trace_id,
76
- span_id: @span_id,
77
- description: @description,
78
- op: @op,
79
- status: @status
80
- }
81
- end
82
-
83
- def start_child(**options)
84
- options = options.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
85
- child_span = Span.new(options)
86
- child_span.span_recorder = @span_recorder
87
-
88
- if @span_recorder && @sampled
89
- @span_recorder.add(child_span)
90
- end
91
-
92
- child_span
93
- end
94
-
95
- def with_child_span(**options, &block)
96
- child_span = start_child(**options)
97
-
98
- yield(child_span)
99
-
100
- child_span.finish
101
- end
102
-
103
- def set_op(op)
104
- @op = op
105
- end
106
-
107
- def set_description(description)
108
- @description = description
109
- end
110
-
111
- def set_status(status)
112
- @status = status
113
- end
114
-
115
- def set_timestamp(timestamp)
116
- @timestamp = timestamp
117
- end
118
-
119
- def set_http_status(status_code)
120
- status_code = status_code.to_i
121
- set_data("status_code", status_code)
122
-
123
- status =
124
- if status_code >= 200 && status_code < 299
125
- "ok"
126
- else
127
- STATUS_MAP[status_code]
128
- end
129
- set_status(status)
130
- end
131
-
132
- def set_data(key, value)
133
- @data[key] = value
134
- end
135
-
136
- def set_tag(key, value)
137
- @tags[key] = value
138
- end
139
-
140
- class SpanRecorder
141
- attr_reader :max_length, :spans
142
-
143
- def initialize(max_length)
144
- @max_length = max_length
145
- @spans = []
146
- end
147
-
148
- def add(span)
149
- if @spans.count < @max_length
150
- @spans << span
151
- end
152
- end
153
- end
154
- end
155
- end
@@ -1,113 +0,0 @@
1
- module Sentry
2
- class Transaction < Span
3
- SENTRY_TRACE_REGEXP = Regexp.new(
4
- "^[ \t]*" + # whitespace
5
- "([0-9a-f]{32})?" + # trace_id
6
- "-?([0-9a-f]{16})?" + # span_id
7
- "-?([01])?" + # sampled
8
- "[ \t]*$" # whitespace
9
- )
10
- UNLABELD_NAME = "<unlabeled transaction>".freeze
11
- MESSAGE_PREFIX = "[Tracing]"
12
-
13
- attr_reader :name, :parent_sampled
14
-
15
- def initialize(name: nil, parent_sampled: nil, **options)
16
- super(**options)
17
-
18
- @name = name
19
- @parent_sampled = parent_sampled
20
- set_span_recorder
21
- end
22
-
23
- def self.from_sentry_trace(sentry_trace, **options)
24
- return unless sentry_trace
25
-
26
- match = SENTRY_TRACE_REGEXP.match(sentry_trace)
27
- trace_id, parent_span_id, sampled_flag = match[1..3]
28
-
29
- sampled = sampled_flag != "0"
30
-
31
- new(trace_id: trace_id, parent_span_id: parent_span_id, parent_sampled: sampled, **options)
32
- end
33
-
34
- def to_hash
35
- hash = super
36
- hash.merge!(name: @name, sampled: @sampled, parent_sampled: @parent_sampled)
37
- hash
38
- end
39
-
40
- def set_initial_sample_desicion(sampling_context = {})
41
- unless Sentry.configuration.tracing_enabled?
42
- @sampled = false
43
- return
44
- end
45
-
46
- return unless @sampled.nil?
47
-
48
- transaction_description = generate_transaction_description
49
-
50
- logger = Sentry.configuration.logger
51
- sample_rate = Sentry.configuration.traces_sample_rate
52
- traces_sampler = Sentry.configuration.traces_sampler
53
-
54
- if traces_sampler.is_a?(Proc)
55
- sampling_context = sampling_context.merge(
56
- parent_sampled: @parent_sampled,
57
- transaction_context: self.to_hash
58
- )
59
-
60
- sample_rate = traces_sampler.call(sampling_context)
61
- end
62
-
63
- unless [true, false].include?(sample_rate) || (sample_rate.is_a?(Float) && sample_rate >= 0.0 && sample_rate <= 1.0)
64
- @sampled = false
65
- logger.warn("#{MESSAGE_PREFIX} Discarding #{transaction_description} because of invalid sample_rate: #{sample_rate}")
66
- return
67
- end
68
-
69
- if sample_rate == 0.0 || sample_rate == false
70
- @sampled = false
71
- logger.debug("#{MESSAGE_PREFIX} Discarding #{transaction_description} because traces_sampler returned 0 or false")
72
- return
73
- end
74
-
75
- if sample_rate == true
76
- @sampled = true
77
- else
78
- @sampled = Random.rand < sample_rate
79
- end
80
-
81
- if @sampled
82
- logger.debug("#{MESSAGE_PREFIX} Starting #{transaction_description}")
83
- else
84
- logger.debug(
85
- "#{MESSAGE_PREFIX} Discarding #{transaction_description} because it's not included in the random sample (sampling rate = #{sample_rate})"
86
- )
87
- end
88
- end
89
-
90
- def finish(hub: nil)
91
- super() # Span#finish doesn't take arguments
92
-
93
- if @name.nil?
94
- @name = UNLABELD_NAME
95
- end
96
-
97
- return unless @sampled
98
-
99
- hub ||= Sentry.get_current_hub
100
- event = hub.current_client.event_from_transaction(self)
101
- hub.capture_event(event)
102
- end
103
-
104
- private
105
-
106
- def generate_transaction_description
107
- result = op.nil? ? "" : "<#{@op}> "
108
- result += "transaction"
109
- result += " <#{@name}>" if @name
110
- result
111
- end
112
- end
113
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sentry
4
- class TransactionEvent < Event
5
- ATTRIBUTES = %i(
6
- event_id level timestamp start_timestamp
7
- release environment server_name modules
8
- user tags contexts extra
9
- transaction platform sdk type
10
- )
11
-
12
- attr_accessor(*ATTRIBUTES)
13
- attr_accessor :spans
14
-
15
- def start_timestamp=(time)
16
- @start_timestamp = time.is_a?(Time) ? time.to_f : time
17
- end
18
-
19
- def type
20
- "transaction"
21
- end
22
-
23
- def to_hash
24
- data = super
25
- data[:spans] = @spans.map(&:to_hash) if @spans
26
- data
27
- end
28
- end
29
- end
@@ -1,21 +0,0 @@
1
- module Sentry
2
- class Transport
3
- class Configuration
4
- attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :http_adapter, :faraday_builder, :transport_class
5
-
6
- def initialize
7
- @ssl_verification = true
8
- @open_timeout = 1
9
- @timeout = 2
10
- end
11
-
12
- def transport_class=(klass)
13
- unless klass.is_a?(Class)
14
- raise Sentry::Error.new("config.transport.transport_class must a class. got: #{klass.class}")
15
- end
16
-
17
- @transport_class = klass
18
- end
19
- end
20
- end
21
- end
@@ -1,14 +0,0 @@
1
- module Sentry
2
- class DummyTransport < Transport
3
- attr_accessor :events
4
-
5
- def initialize(*)
6
- super
7
- @events = []
8
- end
9
-
10
- def send_event(event)
11
- @events << event
12
- end
13
- end
14
- end
@@ -1,65 +0,0 @@
1
- require 'faraday'
2
-
3
- module Sentry
4
- class HTTPTransport < Transport
5
- attr_reader :conn, :adapter
6
-
7
- def initialize(*args)
8
- super
9
- @adapter = @transport_configuration.http_adapter || Faraday.default_adapter
10
- @conn = set_conn
11
- @endpoint = @dsn.envelope_endpoint
12
- end
13
-
14
- def send_data(data, options = {})
15
- unless configuration.sending_allowed?
16
- logger.debug(LOGGER_PROGNAME) { "Event not sent: #{configuration.error_messages}" }
17
- end
18
-
19
- conn.post @endpoint do |req|
20
- req.headers['Content-Type'] = options[:content_type]
21
- req.headers['X-Sentry-Auth'] = generate_auth_header
22
- req.body = data
23
- end
24
- rescue Faraday::Error => e
25
- error_info = e.message
26
-
27
- if e.response
28
- error_info += "\nbody: #{e.response[:body]}"
29
- error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}" if e.response[:headers]['x-sentry-error']
30
- end
31
-
32
- raise Sentry::Error, error_info
33
- end
34
-
35
- private
36
-
37
- def set_conn
38
- server = @dsn.server
39
-
40
- configuration.logger.debug(LOGGER_PROGNAME) { "Sentry HTTP Transport connecting to #{server}" }
41
-
42
- Faraday.new(server, :ssl => ssl_configuration, :proxy => @transport_configuration.proxy) do |builder|
43
- @transport_configuration.faraday_builder&.call(builder)
44
- builder.response :raise_error
45
- builder.options.merge! faraday_opts
46
- builder.headers[:user_agent] = "sentry-ruby/#{Sentry::VERSION}"
47
- builder.adapter(*adapter)
48
- end
49
- end
50
-
51
- # TODO: deprecate and replace where possible w/Faraday Builder
52
- def faraday_opts
53
- [:timeout, :open_timeout].each_with_object({}) do |opt, memo|
54
- memo[opt] = @transport_configuration.public_send(opt) if @transport_configuration.public_send(opt)
55
- end
56
- end
57
-
58
- def ssl_configuration
59
- (@transport_configuration.ssl || {}).merge(
60
- :verify => @transport_configuration.ssl_verification,
61
- :ca_file => @transport_configuration.ssl_ca_file
62
- )
63
- end
64
- end
65
- end
@@ -1,40 +0,0 @@
1
- module Sentry
2
- class Transport
3
- class State
4
- def initialize
5
- reset
6
- end
7
-
8
- def should_try?
9
- return true if @status == :online
10
-
11
- interval = @retry_after || [@retry_number, 6].min**2
12
- return true if Sentry.utc_now - @last_check >= interval
13
-
14
- false
15
- end
16
-
17
- def failure(retry_after = nil)
18
- @status = :error
19
- @retry_number += 1
20
- @last_check = Sentry.utc_now
21
- @retry_after = retry_after
22
- end
23
-
24
- def success
25
- reset
26
- end
27
-
28
- def reset
29
- @status = :online
30
- @retry_number = 0
31
- @last_check = nil
32
- @retry_after = nil
33
- end
34
-
35
- def failed?
36
- @status == :error
37
- end
38
- end
39
- end
40
- end