sentry-ruby 0.1.2 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"