sentry-ruby 0.2.0 → 4.1.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.
@@ -0,0 +1,17 @@
1
+ require "rake"
2
+ require "rake/task"
3
+
4
+ module Rake
5
+ class Application
6
+ alias orig_display_error_messsage display_error_message
7
+ def display_error_message(ex)
8
+ Sentry.capture_exception(ex, hint: { background: false }) do |scope|
9
+ task_name = top_level_tasks.join(' ')
10
+ scope.set_transaction_name(task_name)
11
+ scope.set_tag("rake_task", task_name)
12
+ end if Sentry.initialized?
13
+
14
+ orig_display_error_messsage(ex)
15
+ end
16
+ end
17
+ end
@@ -15,7 +15,7 @@ module Sentry
15
15
  set_default_value
16
16
  end
17
17
 
18
- def apply_to_event(event)
18
+ def apply_to_event(event, hint = nil)
19
19
  event.tags = tags.merge(event.tags)
20
20
  event.user = user.merge(event.user)
21
21
  event.extra = extra.merge(event.extra)
@@ -26,14 +26,14 @@ module Sentry
26
26
  end
27
27
 
28
28
  event.fingerprint = fingerprint
29
- event.level ||= level
29
+ event.level = level
30
30
  event.transaction = transaction_names.last
31
31
  event.breadcrumbs = breadcrumbs
32
- event.rack_env = rack_env
32
+ event.rack_env = rack_env if rack_env
33
33
 
34
34
  unless @event_processors.empty?
35
35
  @event_processors.each do |processor_block|
36
- event = processor_block.call(event)
36
+ event = processor_block.call(event, hint)
37
37
  end
38
38
  end
39
39
 
@@ -57,7 +57,7 @@ module Sentry
57
57
  copy.user = user.deep_dup
58
58
  copy.transaction_names = transaction_names.deep_dup
59
59
  copy.fingerprint = fingerprint.deep_dup
60
- copy.span = span
60
+ copy.span = span.deep_dup
61
61
  copy
62
62
  end
63
63
 
@@ -35,16 +35,12 @@ module Sentry
35
35
  @tags = {}
36
36
  end
37
37
 
38
- def set_span_recorder
39
- @span_recorder = SpanRecorder.new(1000)
40
- @span_recorder.add(self)
41
- end
42
-
43
38
  def finish
44
39
  # already finished
45
40
  return if @timestamp
46
41
 
47
42
  @timestamp = Sentry.utc_now.to_f
43
+ self
48
44
  end
49
45
 
50
46
  def to_sentry_trace
@@ -81,14 +77,19 @@ module Sentry
81
77
 
82
78
  def start_child(**options)
83
79
  options = options.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
84
- child_span = Span.new(options)
85
- child_span.span_recorder = @span_recorder
80
+ Span.new(options)
81
+ end
86
82
 
87
- if @span_recorder && @sampled
88
- @span_recorder.add(child_span)
89
- end
83
+ def with_child_span(**options, &block)
84
+ child_span = start_child(**options)
85
+
86
+ yield(child_span)
87
+
88
+ child_span.finish
89
+ end
90
90
 
91
- child_span
91
+ def deep_dup
92
+ dup
92
93
  end
93
94
 
94
95
  def set_op(op)
@@ -127,20 +128,5 @@ module Sentry
127
128
  def set_tag(key, value)
128
129
  @tags[key] = value
129
130
  end
130
-
131
- class SpanRecorder
132
- attr_reader :max_length, :spans
133
-
134
- def initialize(max_length)
135
- @max_length = max_length
136
- @spans = []
137
- end
138
-
139
- def add(span)
140
- if @spans.count < @max_length
141
- @spans << span
142
- end
143
- end
144
- end
145
131
  end
146
132
  end
@@ -20,6 +20,11 @@ module Sentry
20
20
  set_span_recorder
21
21
  end
22
22
 
23
+ def set_span_recorder
24
+ @span_recorder = SpanRecorder.new(1000)
25
+ @span_recorder.add(self)
26
+ end
27
+
23
28
  def self.from_sentry_trace(sentry_trace, **options)
24
29
  return unless sentry_trace
25
30
 
@@ -37,6 +42,30 @@ module Sentry
37
42
  hash
38
43
  end
39
44
 
45
+ def start_child(**options)
46
+ child_span = super
47
+ child_span.span_recorder = @span_recorder
48
+
49
+ if @sampled
50
+ @span_recorder.add(child_span)
51
+ end
52
+
53
+ child_span
54
+ end
55
+
56
+ def deep_dup
57
+ copy = super
58
+ copy.set_span_recorder
59
+
60
+ @span_recorder.spans.each do |span|
61
+ # span_recorder's first span is the current span, which should not be added to the copy's spans
62
+ next if span == self
63
+ copy.span_recorder.add(span.dup)
64
+ end
65
+
66
+ copy
67
+ end
68
+
40
69
  def set_initial_sample_desicion(sampling_context = {})
41
70
  unless Sentry.configuration.tracing_enabled?
42
71
  @sampled = false
@@ -109,5 +138,20 @@ module Sentry
109
138
  result += " <#{@name}>" if @name
110
139
  result
111
140
  end
141
+
142
+ class SpanRecorder
143
+ attr_reader :max_length, :spans
144
+
145
+ def initialize(max_length)
146
+ @max_length = max_length
147
+ @spans = []
148
+ end
149
+
150
+ def add(span)
151
+ if @spans.count < @max_length
152
+ @spans << span
153
+ end
154
+ end
155
+ end
112
156
  end
113
157
  end
@@ -1,20 +1,17 @@
1
1
  require "json"
2
2
  require "base64"
3
- require "sentry/transport/state"
4
3
 
5
4
  module Sentry
6
5
  class Transport
7
6
  PROTOCOL_VERSION = '5'
8
7
  USER_AGENT = "sentry-ruby/#{Sentry::VERSION}"
9
- CONTENT_TYPE = 'application/json'
10
8
 
11
- attr_accessor :configuration, :state
9
+ attr_accessor :configuration
12
10
 
13
11
  def initialize(configuration)
14
12
  @configuration = configuration
15
13
  @transport_configuration = configuration.transport
16
14
  @dsn = configuration.dsn
17
- @state = State.new
18
15
  end
19
16
 
20
17
  def send_data(data, options = {})
@@ -22,13 +19,17 @@ module Sentry
22
19
  end
23
20
 
24
21
  def send_event(event)
25
- content_type, encoded_data = prepare_encoded_event(event)
22
+ unless configuration.sending_allowed?
23
+ configuration.logger.debug(LOGGER_PROGNAME) { "Event not sent: #{configuration.error_messages}" }
24
+ return
25
+ end
26
+
27
+ encoded_data = prepare_encoded_event(event)
26
28
 
27
29
  return nil unless encoded_data
28
30
 
29
- send_data(encoded_data, content_type: content_type)
31
+ send_data(encoded_data)
30
32
 
31
- state.success
32
33
  event
33
34
  rescue => e
34
35
  failed_for_exception(e, event)
@@ -57,7 +58,7 @@ module Sentry
57
58
  #{JSON.generate(event_hash)}
58
59
  ENVELOPE
59
60
 
60
- [CONTENT_TYPE, envelope]
61
+ envelope
61
62
  end
62
63
 
63
64
  private
@@ -66,27 +67,16 @@ module Sentry
66
67
  # Convert to hash
67
68
  event_hash = event.to_hash
68
69
 
69
- unless @state.should_try?
70
- failed_for_previous_failure(event_hash)
71
- return
72
- end
73
-
74
70
  event_id = event_hash[:event_id] || event_hash['event_id']
75
71
  configuration.logger.info(LOGGER_PROGNAME) { "Sending event #{event_id} to Sentry" }
76
72
  encode(event_hash)
77
73
  end
78
74
 
79
75
  def failed_for_exception(e, event)
80
- @state.failure
81
76
  configuration.logger.warn(LOGGER_PROGNAME) { "Unable to record event with remote Sentry server (#{e.class} - #{e.message}):\n#{e.backtrace[0..10].join("\n")}" }
82
77
  log_not_sending(event)
83
78
  end
84
79
 
85
- def failed_for_previous_failure(event)
86
- configuration.logger.warn(LOGGER_PROGNAME) { "Not sending event due to previous failure(s)." }
87
- log_not_sending(event)
88
- end
89
-
90
80
  def log_not_sending(event)
91
81
  configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event. Unreported Event: #{Event.get_log_message(event.to_hash)}" }
92
82
  end
@@ -2,6 +2,7 @@ require 'faraday'
2
2
 
3
3
  module Sentry
4
4
  class HTTPTransport < Transport
5
+ CONTENT_TYPE = 'application/json'
5
6
  attr_reader :conn, :adapter
6
7
 
7
8
  def initialize(*args)
@@ -11,13 +12,9 @@ module Sentry
11
12
  @endpoint = @dsn.envelope_endpoint
12
13
  end
13
14
 
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
-
15
+ def send_data(data)
19
16
  conn.post @endpoint do |req|
20
- req.headers['Content-Type'] = options[:content_type]
17
+ req.headers['Content-Type'] = CONTENT_TYPE
21
18
  req.headers['X-Sentry-Auth'] = generate_auth_header
22
19
  req.body = data
23
20
  end
@@ -0,0 +1,16 @@
1
+ module Sentry
2
+ module Utils
3
+ module RequestId
4
+ REQUEST_ID_HEADERS = %w(action_dispatch.request_id HTTP_X_REQUEST_ID).freeze
5
+
6
+ # Request ID based on ActionDispatch::RequestId
7
+ def self.read_from(env_hash)
8
+ REQUEST_ID_HEADERS.each do |key|
9
+ request_id = env_hash[key]
10
+ return request_id if request_id
11
+ end
12
+ nil
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Sentry
2
- VERSION = "0.2.0"
2
+ VERSION = "4.1.1"
3
3
  end
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "faraday", ">= 1.0"
26
+ spec.add_dependency "concurrent-ruby", '~> 1.0', '>= 1.0.2'
26
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 4.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2020-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -24,6 +24,26 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.0.2
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.0.2
27
47
  description: A gem that provides a client interface for the Sentry error logger
28
48
  email: accounts@sentry.io
29
49
  executables: []
@@ -45,6 +65,7 @@ files:
45
65
  - bin/console
46
66
  - bin/setup
47
67
  - lib/sentry-ruby.rb
68
+ - lib/sentry/background_worker.rb
48
69
  - lib/sentry/backtrace.rb
49
70
  - lib/sentry/benchmarks/benchmark_transport.rb
50
71
  - lib/sentry/breadcrumb.rb
@@ -65,8 +86,10 @@ files:
65
86
  - lib/sentry/linecache.rb
66
87
  - lib/sentry/logger.rb
67
88
  - lib/sentry/rack.rb
68
- - lib/sentry/rack/capture_exception.rb
69
- - lib/sentry/rack/tracing.rb
89
+ - lib/sentry/rack/capture_exceptions.rb
90
+ - lib/sentry/rack/deprecations.rb
91
+ - lib/sentry/rack/interface.rb
92
+ - lib/sentry/rake.rb
70
93
  - lib/sentry/scope.rb
71
94
  - lib/sentry/span.rb
72
95
  - lib/sentry/transaction.rb
@@ -75,9 +98,9 @@ files:
75
98
  - lib/sentry/transport/configuration.rb
76
99
  - lib/sentry/transport/dummy_transport.rb
77
100
  - lib/sentry/transport/http_transport.rb
78
- - lib/sentry/transport/state.rb
79
101
  - lib/sentry/utils/exception_cause_chain.rb
80
102
  - lib/sentry/utils/real_ip.rb
103
+ - lib/sentry/utils/request_id.rb
81
104
  - lib/sentry/version.rb
82
105
  - sentry-ruby.gemspec
83
106
  homepage: https://github.com/getsentry/raven-ruby
@@ -1,39 +0,0 @@
1
- module Sentry
2
- module Rack
3
- class Tracing
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def call(env)
9
- Sentry.clone_hub_to_current_thread unless Sentry.get_current_hub
10
-
11
- if Sentry.configuration.traces_sample_rate.to_f == 0.0
12
- return @app.call(env)
13
- end
14
-
15
- Sentry.with_scope do |scope|
16
- scope.clear_breadcrumbs
17
- scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
18
- span = Sentry.start_transaction(name: scope.transaction_name, op: "rack.request")
19
- scope.set_span(span)
20
-
21
- begin
22
- response = @app.call(env)
23
- rescue
24
- finish_span(span, 500)
25
- raise
26
- end
27
-
28
- finish_span(span, response[0])
29
- response
30
- end
31
- end
32
-
33
- def finish_span(span, status_code)
34
- span.set_http_status(status_code)
35
- span.finish
36
- end
37
- end
38
- end
39
- 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