sentry-ruby 0.1.2 → 4.0.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,113 @@
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
@@ -0,0 +1,29 @@
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
@@ -32,10 +32,11 @@ module Sentry
32
32
  event
33
33
  rescue => e
34
34
  failed_for_exception(e, event)
35
+ nil
35
36
  end
36
37
 
37
38
  def generate_auth_header
38
- now = Time.now.to_i.to_s
39
+ now = Sentry.utc_now.to_i
39
40
  fields = {
40
41
  'sentry_version' => PROTOCOL_VERSION,
41
42
  'sentry_client' => USER_AGENT,
@@ -48,11 +49,12 @@ module Sentry
48
49
 
49
50
  def encode(event_hash)
50
51
  event_id = event_hash[:event_id] || event_hash['event_id']
52
+ event_type = event_hash[:type] || event_hash['type']
51
53
 
52
54
  envelope = <<~ENVELOPE
53
- {"event_id":"#{event_id}","dsn":"#{configuration.dsn.to_s}","sdk":#{Sentry.sdk_meta.to_json},"sent_at":"#{DateTime.now.rfc3339}"}
54
- {"type":"event","content_type":"application/json"}
55
- #{event_hash.to_json}
55
+ {"event_id":"#{event_id}","dsn":"#{configuration.dsn.to_s}","sdk":#{Sentry.sdk_meta.to_json},"sent_at":"#{Sentry.utc_now.iso8601}"}
56
+ {"type":"#{event_type}","content_type":"application/json"}
57
+ #{JSON.generate(event_hash)}
56
58
  ENVELOPE
57
59
 
58
60
  [CONTENT_TYPE, envelope]
@@ -86,7 +88,7 @@ module Sentry
86
88
  end
87
89
 
88
90
  def log_not_sending(event)
89
- configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event: #{Event.get_log_message(event.to_hash)}" }
91
+ configuration.logger.warn(LOGGER_PROGNAME) { "Failed to submit event. Unreported Event: #{Event.get_log_message(event.to_hash)}" }
90
92
  end
91
93
  end
92
94
  end
@@ -1,19 +1,12 @@
1
1
  module Sentry
2
2
  class Transport
3
3
  class Configuration
4
- attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :encoding, :http_adapter, :faraday_builder, :transport_class
4
+ attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :http_adapter, :faraday_builder, :transport_class
5
5
 
6
6
  def initialize
7
7
  @ssl_verification = true
8
8
  @open_timeout = 1
9
9
  @timeout = 2
10
- @encoding = 'gzip'
11
- end
12
-
13
- def encoding=(encoding)
14
- raise(Error, 'Unsupported encoding') unless %w(gzip json).include? encoding
15
-
16
- @encoding = encoding
17
10
  end
18
11
 
19
12
  def transport_class=(klass)
@@ -23,9 +23,12 @@ module Sentry
23
23
  end
24
24
  rescue Faraday::Error => e
25
25
  error_info = e.message
26
- if e.response && e.response[:headers]['x-sentry-error']
27
- error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}"
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']
28
30
  end
31
+
29
32
  raise Sentry::Error, error_info
30
33
  end
31
34
 
@@ -9,7 +9,7 @@ module Sentry
9
9
  return true if @status == :online
10
10
 
11
11
  interval = @retry_after || [@retry_number, 6].min**2
12
- return true if Time.now - @last_check >= interval
12
+ return true if Sentry.utc_now - @last_check >= interval
13
13
 
14
14
  false
15
15
  end
@@ -17,7 +17,7 @@ module Sentry
17
17
  def failure(retry_after = nil)
18
18
  @status = :error
19
19
  @retry_number += 1
20
- @last_check = Time.now
20
+ @last_check = Sentry.utc_now
21
21
  @retry_after = retry_after
22
22
  end
23
23
 
@@ -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.1.2"
2
+ VERSION = "4.0.1"
3
3
  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.1.2
4
+ version: 4.0.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-12 00:00:00.000000000 Z
11
+ date: 2020-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -44,8 +44,9 @@ files:
44
44
  - Rakefile
45
45
  - bin/console
46
46
  - bin/setup
47
- - lib/sentry.rb
47
+ - lib/sentry-ruby.rb
48
48
  - lib/sentry/backtrace.rb
49
+ - lib/sentry/benchmarks/benchmark_transport.rb
49
50
  - lib/sentry/breadcrumb.rb
50
51
  - lib/sentry/breadcrumb/sentry_logger.rb
51
52
  - lib/sentry/breadcrumb_buffer.rb
@@ -65,8 +66,12 @@ files:
65
66
  - lib/sentry/logger.rb
66
67
  - lib/sentry/rack.rb
67
68
  - lib/sentry/rack/capture_exception.rb
68
- - lib/sentry/ruby.rb
69
+ - lib/sentry/rack/tracing.rb
70
+ - lib/sentry/rake.rb
69
71
  - lib/sentry/scope.rb
72
+ - lib/sentry/span.rb
73
+ - lib/sentry/transaction.rb
74
+ - lib/sentry/transaction_event.rb
70
75
  - lib/sentry/transport.rb
71
76
  - lib/sentry/transport/configuration.rb
72
77
  - lib/sentry/transport/dummy_transport.rb
@@ -74,6 +79,7 @@ files:
74
79
  - lib/sentry/transport/state.rb
75
80
  - lib/sentry/utils/exception_cause_chain.rb
76
81
  - lib/sentry/utils/real_ip.rb
82
+ - lib/sentry/utils/request_id.rb
77
83
  - lib/sentry/version.rb
78
84
  - sentry-ruby.gemspec
79
85
  homepage: https://github.com/getsentry/raven-ruby
@@ -1 +0,0 @@
1
- require "sentry"