sentry-ruby-core 5.0.2 → 5.2.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.
- checksums.yaml +4 -4
 - data/Gemfile +1 -0
 - data/lib/sentry/configuration.rb +6 -0
 - data/lib/sentry/envelope.rb +29 -10
 - data/lib/sentry/event.rb +1 -0
 - data/lib/sentry/hub.rb +33 -2
 - data/lib/sentry/interfaces/exception.rb +1 -0
 - data/lib/sentry/interfaces/request.rb +3 -2
 - data/lib/sentry/net/http.rb +3 -2
 - data/lib/sentry/rack/capture_exceptions.rb +26 -24
 - data/lib/sentry/redis.rb +90 -0
 - data/lib/sentry/scope.rb +11 -2
 - data/lib/sentry/session.rb +35 -0
 - data/lib/sentry/session_flusher.rb +79 -0
 - data/lib/sentry/transaction.rb +4 -5
 - data/lib/sentry/transport/dummy_transport.rb +6 -1
 - data/lib/sentry/transport.rb +58 -14
 - data/lib/sentry/version.rb +1 -1
 - data/lib/sentry-ruby.rb +90 -12
 - metadata +5 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c6a629d8aa998cef5638cd40e3dc9e0ad24770d0c31540b327c669e9fb84aedd
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: e373b601b401fddca9307a32ea1dda36bc4994209c68b19748e89f128a598e80
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 2cfd2f1fe582578b74bc23610931d95bf7a86c35c696c658d55fb4f40ddfdd129c36bae415bc73efef20ecfb435f33ba72e3b46a96f536c0c61692d8c8cb34e2
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: f10f71edc8bef7a57426de73e0cf2a1aea855c89ec2900a065986d33f064216f7da74c0cf9f7dd41c08dcb18224a61c6c43bad67548a327ca593b73b526e3d8a
         
     | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/lib/sentry/configuration.rb
    CHANGED
    
    | 
         @@ -75,6 +75,7 @@ module Sentry 
     | 
|
| 
       75 
75 
     | 
    
         
             
                # An array of breadcrumbs loggers to be used. Available options are:
         
     | 
| 
       76 
76 
     | 
    
         
             
                # - :sentry_logger
         
     | 
| 
       77 
77 
     | 
    
         
             
                # - :http_logger
         
     | 
| 
      
 78 
     | 
    
         
            +
                # - :redis_logger
         
     | 
| 
       78 
79 
     | 
    
         
             
                #
         
     | 
| 
       79 
80 
     | 
    
         
             
                # And if you also use sentry-rails:
         
     | 
| 
       80 
81 
     | 
    
         
             
                # - :active_support_logger
         
     | 
| 
         @@ -206,6 +207,10 @@ module Sentry 
     | 
|
| 
       206 
207 
     | 
    
         
             
                # @return [Boolean]
         
     | 
| 
       207 
208 
     | 
    
         
             
                attr_accessor :send_client_reports
         
     | 
| 
       208 
209 
     | 
    
         | 
| 
      
 210 
     | 
    
         
            +
                # Track sessions in request/response cycles automatically
         
     | 
| 
      
 211 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 212 
     | 
    
         
            +
                attr_accessor :auto_session_tracking
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
       209 
214 
     | 
    
         
             
                # these are not config options
         
     | 
| 
       210 
215 
     | 
    
         
             
                # @!visibility private
         
     | 
| 
       211 
216 
     | 
    
         
             
                attr_reader :errors, :gem_specs
         
     | 
| 
         @@ -260,6 +265,7 @@ module Sentry 
     | 
|
| 
       260 
265 
     | 
    
         
             
                  self.send_default_pii = false
         
     | 
| 
       261 
266 
     | 
    
         
             
                  self.skip_rake_integration = false
         
     | 
| 
       262 
267 
     | 
    
         
             
                  self.send_client_reports = true
         
     | 
| 
      
 268 
     | 
    
         
            +
                  self.auto_session_tracking = true
         
     | 
| 
       263 
269 
     | 
    
         
             
                  self.trusted_proxies = []
         
     | 
| 
       264 
270 
     | 
    
         
             
                  self.dsn = ENV['SENTRY_DSN']
         
     | 
| 
       265 
271 
     | 
    
         
             
                  self.server_name = server_name_from_env
         
     | 
    
        data/lib/sentry/envelope.rb
    CHANGED
    
    | 
         @@ -3,24 +3,43 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Sentry
         
     | 
| 
       4 
4 
     | 
    
         
             
              # @api private
         
     | 
| 
       5 
5 
     | 
    
         
             
              class Envelope
         
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 6 
     | 
    
         
            +
                class Item
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_accessor :headers, :payload
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(headers, payload)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @headers = headers
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @payload = payload
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def type
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @headers[:type] || 'event'
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 19 
     | 
    
         
            +
                    <<~ITEM
         
     | 
| 
      
 20 
     | 
    
         
            +
                      #{JSON.generate(@headers)}
         
     | 
| 
      
 21 
     | 
    
         
            +
                      #{JSON.generate(@payload)}
         
     | 
| 
      
 22 
     | 
    
         
            +
                    ITEM
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                attr_accessor :headers, :items
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def initialize(headers = {})
         
     | 
| 
       7 
29 
     | 
    
         
             
                  @headers = headers
         
     | 
| 
       8 
30 
     | 
    
         
             
                  @items = []
         
     | 
| 
       9 
31 
     | 
    
         
             
                end
         
     | 
| 
       10 
32 
     | 
    
         | 
| 
       11 
33 
     | 
    
         
             
                def add_item(headers, payload)
         
     | 
| 
       12 
     | 
    
         
            -
                  @items <<  
     | 
| 
      
 34 
     | 
    
         
            +
                  @items << Item.new(headers, payload)
         
     | 
| 
       13 
35 
     | 
    
         
             
                end
         
     | 
| 
       14 
36 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                def  
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                      #{JSON.generate(item_headers)}
         
     | 
| 
       19 
     | 
    
         
            -
                      #{JSON.generate(item_payload)}
         
     | 
| 
       20 
     | 
    
         
            -
                    ENVELOPE
         
     | 
| 
       21 
     | 
    
         
            -
                  end.join("\n")
         
     | 
| 
      
 37 
     | 
    
         
            +
                def item_types
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @items.map(&:type)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
       22 
40 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 41 
     | 
    
         
            +
                def event_id
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @headers[:event_id]
         
     | 
| 
       24 
43 
     | 
    
         
             
                end
         
     | 
| 
       25 
44 
     | 
    
         
             
              end
         
     | 
| 
       26 
45 
     | 
    
         
             
            end
         
     | 
    
        data/lib/sentry/event.rb
    CHANGED
    
    | 
         @@ -23,6 +23,7 @@ module Sentry 
     | 
|
| 
       23 
23 
     | 
    
         
             
                WRITER_ATTRIBUTES = SERIALIZEABLE_ATTRIBUTES - %i(type timestamp level)
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8
         
     | 
| 
      
 26 
     | 
    
         
            +
                MAX_SERIALIZED_PAYLOAD_SIZE = 1024 * 200
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
                SKIP_INSPECTION_ATTRIBUTES = [:@modules, :@stacktrace_builder, :@send_default_pii, :@trusted_proxies, :@rack_env_whitelist]
         
     | 
| 
       28 
29 
     | 
    
         | 
    
        data/lib/sentry/hub.rb
    CHANGED
    
    | 
         @@ -2,6 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require "sentry/scope"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "sentry/client"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "sentry/session"
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Sentry
         
     | 
| 
       7 
8 
     | 
    
         
             
              class Hub
         
     | 
| 
         @@ -94,6 +95,8 @@ module Sentry 
     | 
|
| 
       94 
95 
     | 
    
         
             
                def capture_exception(exception, **options, &block)
         
     | 
| 
       95 
96 
     | 
    
         
             
                  check_argument_type!(exception, ::Exception)
         
     | 
| 
       96 
97 
     | 
    
         | 
| 
      
 98 
     | 
    
         
            +
                  return if Sentry.exception_captured?(exception)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
       97 
100 
     | 
    
         
             
                  return unless current_client
         
     | 
| 
       98 
101 
     | 
    
         | 
| 
       99 
102 
     | 
    
         
             
                  options[:hint] ||= {}
         
     | 
| 
         @@ -102,7 +105,12 @@ module Sentry 
     | 
|
| 
       102 
105 
     | 
    
         | 
| 
       103 
106 
     | 
    
         
             
                  return unless event
         
     | 
| 
       104 
107 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                   
     | 
| 
      
 108 
     | 
    
         
            +
                  current_scope.session&.update_from_exception(event.exception)
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                  capture_event(event, **options, &block).tap do
         
     | 
| 
      
 111 
     | 
    
         
            +
                    # mark the exception as captured so we can use this information to avoid duplicated capturing
         
     | 
| 
      
 112 
     | 
    
         
            +
                    exception.instance_variable_set(Sentry::CAPTURED_SIGNATURE, true)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
       106 
114 
     | 
    
         
             
                end
         
     | 
| 
       107 
115 
     | 
    
         | 
| 
       108 
116 
     | 
    
         
             
                def capture_message(message, **options, &block)
         
     | 
| 
         @@ -138,7 +146,6 @@ module Sentry 
     | 
|
| 
       138 
146 
     | 
    
         | 
| 
       139 
147 
     | 
    
         
             
                  event = current_client.capture_event(event, scope, hint)
         
     | 
| 
       140 
148 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
149 
     | 
    
         
             
                  if event && configuration.debug
         
     | 
| 
       143 
150 
     | 
    
         
             
                    configuration.log_debug(event.to_json_compatible)
         
     | 
| 
       144 
151 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -170,6 +177,30 @@ module Sentry 
     | 
|
| 
       170 
177 
     | 
    
         
             
                  configuration.background_worker_threads = original_background_worker_threads
         
     | 
| 
       171 
178 
     | 
    
         
             
                end
         
     | 
| 
       172 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                def start_session
         
     | 
| 
      
 181 
     | 
    
         
            +
                  return unless current_scope
         
     | 
| 
      
 182 
     | 
    
         
            +
                  current_scope.set_session(Session.new)
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                def end_session
         
     | 
| 
      
 186 
     | 
    
         
            +
                  return unless current_scope
         
     | 
| 
      
 187 
     | 
    
         
            +
                  session = current_scope.session
         
     | 
| 
      
 188 
     | 
    
         
            +
                  current_scope.set_session(nil)
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                  return unless session
         
     | 
| 
      
 191 
     | 
    
         
            +
                  session.close
         
     | 
| 
      
 192 
     | 
    
         
            +
                  Sentry.session_flusher.add_session(session)
         
     | 
| 
      
 193 
     | 
    
         
            +
                end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                def with_session_tracking(&block)
         
     | 
| 
      
 196 
     | 
    
         
            +
                  return yield unless configuration.auto_session_tracking
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                  start_session
         
     | 
| 
      
 199 
     | 
    
         
            +
                  yield
         
     | 
| 
      
 200 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 201 
     | 
    
         
            +
                  end_session
         
     | 
| 
      
 202 
     | 
    
         
            +
                end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
       173 
204 
     | 
    
         
             
                private
         
     | 
| 
       174 
205 
     | 
    
         | 
| 
       175 
206 
     | 
    
         
             
                def current_layer
         
     | 
| 
         @@ -62,7 +62,7 @@ module Sentry 
     | 
|
| 
       62 
62 
     | 
    
         
             
                  self.url = request.scheme && request.url.split('?').first
         
     | 
| 
       63 
63 
     | 
    
         
             
                  self.method = request.request_method
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
                  self.headers = filter_and_format_headers(env)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  self.headers = filter_and_format_headers(env, send_default_pii)
         
     | 
| 
       66 
66 
     | 
    
         
             
                  self.env     = filter_and_format_env(env, rack_env_whitelist)
         
     | 
| 
       67 
67 
     | 
    
         
             
                end
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
         @@ -81,13 +81,14 @@ module Sentry 
     | 
|
| 
       81 
81 
     | 
    
         
             
                  e.message
         
     | 
| 
       82 
82 
     | 
    
         
             
                end
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
                def filter_and_format_headers(env)
         
     | 
| 
      
 84 
     | 
    
         
            +
                def filter_and_format_headers(env, send_default_pii)
         
     | 
| 
       85 
85 
     | 
    
         
             
                  env.each_with_object({}) do |(key, value), memo|
         
     | 
| 
       86 
86 
     | 
    
         
             
                    begin
         
     | 
| 
       87 
87 
     | 
    
         
             
                      key = key.to_s # rack env can contain symbols
         
     | 
| 
       88 
88 
     | 
    
         
             
                      next memo['X-Request-Id'] ||= Utils::RequestId.read_from(env) if Utils::RequestId::REQUEST_ID_HEADERS.include?(key)
         
     | 
| 
       89 
89 
     | 
    
         
             
                      next if is_server_protocol?(key, value, env["SERVER_PROTOCOL"])
         
     | 
| 
       90 
90 
     | 
    
         
             
                      next if is_skippable_header?(key)
         
     | 
| 
      
 91 
     | 
    
         
            +
                      next if key == "HTTP_AUTHORIZATION" && !send_default_pii
         
     | 
| 
       91 
92 
     | 
    
         | 
| 
       92 
93 
     | 
    
         
             
                      # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
         
     | 
| 
       93 
94 
     | 
    
         
             
                      key = key.sub(/^HTTP_/, "")
         
     | 
    
        data/lib/sentry/net/http.rb
    CHANGED
    
    | 
         @@ -6,7 +6,8 @@ module Sentry 
     | 
|
| 
       6 
6 
     | 
    
         
             
              # @api private
         
     | 
| 
       7 
7 
     | 
    
         
             
              module Net
         
     | 
| 
       8 
8 
     | 
    
         
             
                module HTTP
         
     | 
| 
       9 
     | 
    
         
            -
                  OP_NAME = " 
     | 
| 
      
 9 
     | 
    
         
            +
                  OP_NAME = "http.client"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  BREADCRUMB_CATEGORY = "net.http"
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
                  # To explain how the entire thing works, we need to know how the original Net::HTTP#request works
         
     | 
| 
       12 
13 
     | 
    
         
             
                  # Here's part of its definition. As you can see, it usually calls itself inside a #start block
         
     | 
| 
         @@ -53,7 +54,7 @@ module Sentry 
     | 
|
| 
       53 
54 
     | 
    
         | 
| 
       54 
55 
     | 
    
         
             
                    crumb = Sentry::Breadcrumb.new(
         
     | 
| 
       55 
56 
     | 
    
         
             
                      level: :info,
         
     | 
| 
       56 
     | 
    
         
            -
                      category:  
     | 
| 
      
 57 
     | 
    
         
            +
                      category: BREADCRUMB_CATEGORY,
         
     | 
| 
       57 
58 
     | 
    
         
             
                      type: :info,
         
     | 
| 
       58 
59 
     | 
    
         
             
                      data: {
         
     | 
| 
       59 
60 
     | 
    
         
             
                        status: res.code.to_i,
         
     | 
| 
         @@ -14,30 +14,32 @@ module Sentry 
     | 
|
| 
       14 
14 
     | 
    
         
             
                    Sentry.clone_hub_to_current_thread
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                    Sentry.with_scope do |scope|
         
     | 
| 
       17 
     | 
    
         
            -
                       
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
                      Sentry.with_session_tracking do
         
     | 
| 
      
 18 
     | 
    
         
            +
                        scope.clear_breadcrumbs
         
     | 
| 
      
 19 
     | 
    
         
            +
                        scope.set_transaction_name(env["PATH_INFO"]) if env["PATH_INFO"]
         
     | 
| 
      
 20 
     | 
    
         
            +
                        scope.set_rack_env(env)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                        transaction = start_transaction(env, scope)
         
     | 
| 
      
 23 
     | 
    
         
            +
                        scope.set_span(transaction) if transaction
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 26 
     | 
    
         
            +
                          response = @app.call(env)
         
     | 
| 
      
 27 
     | 
    
         
            +
                        rescue Sentry::Error
         
     | 
| 
      
 28 
     | 
    
         
            +
                          finish_transaction(transaction, 500)
         
     | 
| 
      
 29 
     | 
    
         
            +
                          raise # Don't capture Sentry errors
         
     | 
| 
      
 30 
     | 
    
         
            +
                        rescue Exception => e
         
     | 
| 
      
 31 
     | 
    
         
            +
                          capture_exception(e)
         
     | 
| 
      
 32 
     | 
    
         
            +
                          finish_transaction(transaction, 500)
         
     | 
| 
      
 33 
     | 
    
         
            +
                          raise
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                        exception = collect_exception(env)
         
     | 
| 
      
 37 
     | 
    
         
            +
                        capture_exception(exception) if exception
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                        finish_transaction(transaction, response[0])
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                        response
         
     | 
| 
       33 
42 
     | 
    
         
             
                      end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                      exception = collect_exception(env)
         
     | 
| 
       36 
     | 
    
         
            -
                      capture_exception(exception) if exception
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                      finish_transaction(transaction, response[0])
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                      response
         
     | 
| 
       41 
43 
     | 
    
         
             
                    end
         
     | 
| 
       42 
44 
     | 
    
         
             
                  end
         
     | 
| 
       43 
45 
     | 
    
         | 
| 
         @@ -59,7 +61,7 @@ module Sentry 
     | 
|
| 
       59 
61 
     | 
    
         
             
                    sentry_trace = env["HTTP_SENTRY_TRACE"]
         
     | 
| 
       60 
62 
     | 
    
         
             
                    options = { name: scope.transaction_name, op: transaction_op }
         
     | 
| 
       61 
63 
     | 
    
         
             
                    transaction = Sentry::Transaction.from_sentry_trace(sentry_trace, **options) if sentry_trace
         
     | 
| 
       62 
     | 
    
         
            -
                    Sentry.start_transaction(transaction: transaction, **options)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    Sentry.start_transaction(transaction: transaction, custom_sampling_context: { env: env }, **options)
         
     | 
| 
       63 
65 
     | 
    
         
             
                  end
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
       65 
67 
     | 
    
         | 
    
        data/lib/sentry/redis.rb
    ADDED
    
    | 
         @@ -0,0 +1,90 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sentry
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @api private
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Redis
         
     | 
| 
      
 6 
     | 
    
         
            +
                OP_NAME = "db.redis.command"
         
     | 
| 
      
 7 
     | 
    
         
            +
                LOGGER_NAME = :redis_logger
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(commands, host, port, db)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @commands, @host, @port, @db = commands, host, port, db
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def instrument
         
     | 
| 
      
 14 
     | 
    
         
            +
                  return yield unless Sentry.initialized?
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  record_span do
         
     | 
| 
      
 17 
     | 
    
         
            +
                    yield.tap do
         
     | 
| 
      
 18 
     | 
    
         
            +
                      record_breadcrumb
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                private
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                attr_reader :commands, :host, :port, :db
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 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 
     | 
    
         
            +
                def record_breadcrumb
         
     | 
| 
      
 40 
     | 
    
         
            +
                  return unless Sentry.configuration.breadcrumbs_logger.include?(LOGGER_NAME)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  Sentry.add_breadcrumb(
         
     | 
| 
      
 43 
     | 
    
         
            +
                    Sentry::Breadcrumb.new(
         
     | 
| 
      
 44 
     | 
    
         
            +
                      level: :info,
         
     | 
| 
      
 45 
     | 
    
         
            +
                      category: OP_NAME,
         
     | 
| 
      
 46 
     | 
    
         
            +
                      type: :info,
         
     | 
| 
      
 47 
     | 
    
         
            +
                      data: {
         
     | 
| 
      
 48 
     | 
    
         
            +
                        commands: parsed_commands,
         
     | 
| 
      
 49 
     | 
    
         
            +
                        server: server_description
         
     | 
| 
      
 50 
     | 
    
         
            +
                      }
         
     | 
| 
      
 51 
     | 
    
         
            +
                    )
         
     | 
| 
      
 52 
     | 
    
         
            +
                  )
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def commands_description
         
     | 
| 
      
 56 
     | 
    
         
            +
                  parsed_commands.map do |statement|
         
     | 
| 
      
 57 
     | 
    
         
            +
                    statement.values.join(" ").strip
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end.join(", ")
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def parsed_commands
         
     | 
| 
      
 62 
     | 
    
         
            +
                  commands.map do |statement|
         
     | 
| 
      
 63 
     | 
    
         
            +
                    command, key, *arguments = statement
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    { command: command.to_s.upcase, key: key }.tap do |command_set|
         
     | 
| 
      
 66 
     | 
    
         
            +
                      command_set[:arguments] = arguments.join(" ") if Sentry.configuration.send_default_pii
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                def server_description
         
     | 
| 
      
 72 
     | 
    
         
            +
                  "#{host}:#{port}/#{db}"
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                module Client
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def logging(commands, &block)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    Sentry::Redis.new(commands, host, port, db).instrument do
         
     | 
| 
      
 78 
     | 
    
         
            +
                      super
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
            end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            if defined?(::Redis::Client)
         
     | 
| 
      
 86 
     | 
    
         
            +
              Sentry.register_patch do
         
     | 
| 
      
 87 
     | 
    
         
            +
                patch = Sentry::Redis::Client
         
     | 
| 
      
 88 
     | 
    
         
            +
                Redis::Client.prepend(patch) unless Redis::Client.ancestors.include?(patch)
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/sentry/scope.rb
    CHANGED
    
    | 
         @@ -7,7 +7,7 @@ module Sentry 
     | 
|
| 
       7 
7 
     | 
    
         
             
              class Scope
         
     | 
| 
       8 
8 
     | 
    
         
             
                include ArgumentCheckingHelper
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                ATTRIBUTES = [:transaction_names, :contexts, :extra, :tags, :user, :level, :breadcrumbs, :fingerprint, :event_processors, :rack_env, :span]
         
     | 
| 
      
 10 
     | 
    
         
            +
                ATTRIBUTES = [:transaction_names, :contexts, :extra, :tags, :user, :level, :breadcrumbs, :fingerprint, :event_processors, :rack_env, :span, :session]
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                attr_reader(*ATTRIBUTES)
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
         @@ -76,6 +76,7 @@ module Sentry 
     | 
|
| 
       76 
76 
     | 
    
         
             
                  copy.transaction_names = transaction_names.deep_dup
         
     | 
| 
       77 
77 
     | 
    
         
             
                  copy.fingerprint = fingerprint.deep_dup
         
     | 
| 
       78 
78 
     | 
    
         
             
                  copy.span = span.deep_dup
         
     | 
| 
      
 79 
     | 
    
         
            +
                  copy.session = session.deep_dup
         
     | 
| 
       79 
80 
     | 
    
         
             
                  copy
         
     | 
| 
       80 
81 
     | 
    
         
             
                end
         
     | 
| 
       81 
82 
     | 
    
         | 
| 
         @@ -173,7 +174,7 @@ module Sentry 
     | 
|
| 
       173 
174 
     | 
    
         
             
                def set_contexts(contexts_hash)
         
     | 
| 
       174 
175 
     | 
    
         
             
                  check_argument_type!(contexts_hash, Hash)
         
     | 
| 
       175 
176 
     | 
    
         
             
                  @contexts.merge!(contexts_hash) do |key, old, new|
         
     | 
| 
       176 
     | 
    
         
            -
                     
     | 
| 
      
 177 
     | 
    
         
            +
                    old.merge(new)
         
     | 
| 
       177 
178 
     | 
    
         
             
                  end
         
     | 
| 
       178 
179 
     | 
    
         
             
                end
         
     | 
| 
       179 
180 
     | 
    
         | 
| 
         @@ -198,6 +199,13 @@ module Sentry 
     | 
|
| 
       198 
199 
     | 
    
         
             
                  @transaction_names << transaction_name
         
     | 
| 
       199 
200 
     | 
    
         
             
                end
         
     | 
| 
       200 
201 
     | 
    
         | 
| 
      
 202 
     | 
    
         
            +
                # Sets the currently active session on the scope.
         
     | 
| 
      
 203 
     | 
    
         
            +
                # @param session [Session, nil]
         
     | 
| 
      
 204 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 205 
     | 
    
         
            +
                def set_session(session)
         
     | 
| 
      
 206 
     | 
    
         
            +
                  @session = session
         
     | 
| 
      
 207 
     | 
    
         
            +
                end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
       201 
209 
     | 
    
         
             
                # Returns current transaction name.
         
     | 
| 
       202 
210 
     | 
    
         
             
                # The "transaction" here does not refer to `Transaction` objects.
         
     | 
| 
       203 
211 
     | 
    
         
             
                # @return [String, nil]
         
     | 
| 
         @@ -251,6 +259,7 @@ module Sentry 
     | 
|
| 
       251 
259 
     | 
    
         
             
                  @event_processors = []
         
     | 
| 
       252 
260 
     | 
    
         
             
                  @rack_env = {}
         
     | 
| 
       253 
261 
     | 
    
         
             
                  @span = nil
         
     | 
| 
      
 262 
     | 
    
         
            +
                  @session = nil
         
     | 
| 
       254 
263 
     | 
    
         
             
                  set_new_breadcrumb_buffer
         
     | 
| 
       255 
264 
     | 
    
         
             
                end
         
     | 
| 
       256 
265 
     | 
    
         | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sentry
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Session
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :started, :status
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # TODO-neel add :crashed after adding handled mechanism
         
     | 
| 
      
 8 
     | 
    
         
            +
                STATUSES = %i(ok errored exited)
         
     | 
| 
      
 9 
     | 
    
         
            +
                AGGREGATE_STATUSES = %i(errored exited)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @started = Sentry.utc_now
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @status = :ok
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # TODO-neel add :crashed after adding handled mechanism
         
     | 
| 
      
 17 
     | 
    
         
            +
                def update_from_exception(_exception = nil)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @status = :errored
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def close
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @status = :exited if @status == :ok
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 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 
     | 
    
         
            +
                def deep_dup
         
     | 
| 
      
 32 
     | 
    
         
            +
                  dup
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sentry
         
     | 
| 
      
 4 
     | 
    
         
            +
              class SessionFlusher
         
     | 
| 
      
 5 
     | 
    
         
            +
                include LoggingHelper
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                FLUSH_INTERVAL = 60
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(configuration, client)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @thread = nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @client = client
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @pending_aggregates = {}
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @release = configuration.release
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @environment = configuration.environment
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @logger = configuration.logger
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  log_debug("[Sessions] Sessions won't be captured without a valid release") unless @release
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def flush
         
     | 
| 
      
 21 
     | 
    
         
            +
                  return if @pending_aggregates.empty?
         
     | 
| 
      
 22 
     | 
    
         
            +
                  envelope = pending_envelope
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  Sentry.background_worker.perform do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @client.transport.send_envelope(envelope)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  @pending_aggregates = {}
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def add_session(session)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  return unless @release
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  ensure_thread
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  return unless Session::AGGREGATE_STATUSES.include?(session.status)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @pending_aggregates[session.aggregation_key] ||= init_aggregates(session.aggregation_key)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @pending_aggregates[session.aggregation_key][session.status] += 1
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def kill
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @thread&.kill
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                private
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def init_aggregates(aggregation_key)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  aggregates = { started: aggregation_key.iso8601 }
         
     | 
| 
      
 49 
     | 
    
         
            +
                  Session::AGGREGATE_STATUSES.each { |k| aggregates[k] = 0 }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  aggregates
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def pending_envelope
         
     | 
| 
      
 54 
     | 
    
         
            +
                  envelope = Envelope.new
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  header = { type: 'sessions' }
         
     | 
| 
      
 57 
     | 
    
         
            +
                  payload = { attrs: attrs, aggregates: @pending_aggregates.values }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  envelope.add_item(header, payload)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  envelope
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                def attrs
         
     | 
| 
      
 64 
     | 
    
         
            +
                  { release: @release, environment: @environment }
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def ensure_thread
         
     | 
| 
      
 68 
     | 
    
         
            +
                  return if @thread&.alive?
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  @thread = Thread.new do
         
     | 
| 
      
 71 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 72 
     | 
    
         
            +
                      sleep(FLUSH_INTERVAL)
         
     | 
| 
      
 73 
     | 
    
         
            +
                      flush
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/sentry/transaction.rb
    CHANGED
    
    | 
         @@ -164,13 +164,12 @@ module Sentry 
     | 
|
| 
       164 
164 
     | 
    
         
             
                    @name = UNLABELD_NAME
         
     | 
| 
       165 
165 
     | 
    
         
             
                  end
         
     | 
| 
       166 
166 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
                   
     | 
| 
      
 167 
     | 
    
         
            +
                  if @sampled
         
     | 
| 
      
 168 
     | 
    
         
            +
                    event = hub.current_client.event_from_transaction(self)
         
     | 
| 
      
 169 
     | 
    
         
            +
                    hub.capture_event(event)
         
     | 
| 
      
 170 
     | 
    
         
            +
                  else
         
     | 
| 
       168 
171 
     | 
    
         
             
                    hub.current_client.transport.record_lost_event(:sample_rate, 'transaction')
         
     | 
| 
       169 
     | 
    
         
            -
                    return
         
     | 
| 
       170 
172 
     | 
    
         
             
                  end
         
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
                  event = hub.current_client.event_from_transaction(self)
         
     | 
| 
       173 
     | 
    
         
            -
                  hub.capture_event(event)
         
     | 
| 
       174 
173 
     | 
    
         
             
                end
         
     | 
| 
       175 
174 
     | 
    
         | 
| 
       176 
175 
     | 
    
         
             
                protected
         
     | 
| 
         @@ -2,15 +2,20 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Sentry
         
     | 
| 
       4 
4 
     | 
    
         
             
              class DummyTransport < Transport
         
     | 
| 
       5 
     | 
    
         
            -
                attr_accessor :events
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_accessor :events, :envelopes
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                def initialize(*)
         
     | 
| 
       8 
8 
     | 
    
         
             
                  super
         
     | 
| 
       9 
9 
     | 
    
         
             
                  @events = []
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @envelopes = []
         
     | 
| 
       10 
11 
     | 
    
         
             
                end
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
                def send_event(event)
         
     | 
| 
       13 
14 
     | 
    
         
             
                  @events << event
         
     | 
| 
       14 
15 
     | 
    
         
             
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def send_envelope(envelope)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @envelopes << envelope
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
       15 
20 
     | 
    
         
             
              end
         
     | 
| 
       16 
21 
     | 
    
         
             
            end
         
     | 
    
        data/lib/sentry/transport.rb
    CHANGED
    
    | 
         @@ -46,23 +46,54 @@ module Sentry 
     | 
|
| 
       46 
46 
     | 
    
         
             
                end
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         
             
                def send_event(event)
         
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
       50 
     | 
    
         
            -
                   
     | 
| 
      
 49 
     | 
    
         
            +
                  envelope = envelope_from_event(event)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  send_envelope(envelope)
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                   
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 52 
     | 
    
         
            +
                  event
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def send_envelope(envelope)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  reject_rate_limited_items(envelope)
         
     | 
| 
       55 
57 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 58 
     | 
    
         
            +
                  return if envelope.items.empty?
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  data, serialized_items = serialize_envelope(envelope)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  if data
         
     | 
| 
      
 63 
     | 
    
         
            +
                    log_info("[Transport] Sending envelope with items [#{serialized_items.map(&:type).join(', ')}] #{envelope.event_id} to Sentry")
         
     | 
| 
      
 64 
     | 
    
         
            +
                    send_data(data)
         
     | 
| 
       57 
65 
     | 
    
         
             
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
       58 
67 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
      
 68 
     | 
    
         
            +
                def serialize_envelope(envelope)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  serialized_items = []
         
     | 
| 
      
 70 
     | 
    
         
            +
                  serialized_results = []
         
     | 
| 
       60 
71 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
      
 72 
     | 
    
         
            +
                  envelope.items.each do |item|
         
     | 
| 
      
 73 
     | 
    
         
            +
                    result = item.to_s
         
     | 
| 
       62 
74 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
      
 75 
     | 
    
         
            +
                    if result.bytesize > Event::MAX_SERIALIZED_PAYLOAD_SIZE
         
     | 
| 
      
 76 
     | 
    
         
            +
                      item.payload.delete(:breadcrumbs)
         
     | 
| 
      
 77 
     | 
    
         
            +
                      result = item.to_s
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
       64 
79 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
      
 80 
     | 
    
         
            +
                    if result.bytesize > Event::MAX_SERIALIZED_PAYLOAD_SIZE
         
     | 
| 
      
 81 
     | 
    
         
            +
                      size_breakdown = item.payload.map do |key, value|
         
     | 
| 
      
 82 
     | 
    
         
            +
                        "#{key}: #{JSON.generate(value).bytesize}"
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end.join(", ")
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                      log_debug("Envelope item [#{item.type}] is still oversized without breadcrumbs: {#{size_breakdown}}")
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                      next
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    serialized_results << result
         
     | 
| 
      
 91 
     | 
    
         
            +
                    serialized_items << item
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  data = [JSON.generate(envelope.headers), *serialized_results].join("\n") unless serialized_results.empty?
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  [data, serialized_items]
         
     | 
| 
       66 
97 
     | 
    
         
             
                end
         
     | 
| 
       67 
98 
     | 
    
         | 
| 
       68 
99 
     | 
    
         
             
                def is_rate_limited?(item_type)
         
     | 
| 
         @@ -71,6 +102,8 @@ module Sentry 
     | 
|
| 
       71 
102 
     | 
    
         
             
                    case item_type
         
     | 
| 
       72 
103 
     | 
    
         
             
                    when "transaction"
         
     | 
| 
       73 
104 
     | 
    
         
             
                      @rate_limits["transaction"]
         
     | 
| 
      
 105 
     | 
    
         
            +
                    when "sessions"
         
     | 
| 
      
 106 
     | 
    
         
            +
                      @rate_limits["session"]
         
     | 
| 
       74 
107 
     | 
    
         
             
                    else
         
     | 
| 
       75 
108 
     | 
    
         
             
                      @rate_limits["error"]
         
     | 
| 
       76 
109 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -106,7 +139,7 @@ module Sentry 
     | 
|
| 
       106 
139 
     | 
    
         
             
                  'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
         
     | 
| 
       107 
140 
     | 
    
         
             
                end
         
     | 
| 
       108 
141 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                def  
     | 
| 
      
 142 
     | 
    
         
            +
                def envelope_from_event(event)
         
     | 
| 
       110 
143 
     | 
    
         
             
                  # Convert to hash
         
     | 
| 
       111 
144 
     | 
    
         
             
                  event_payload = event.to_hash
         
     | 
| 
       112 
145 
     | 
    
         
             
                  event_id = event_payload[:event_id] || event_payload["event_id"]
         
     | 
| 
         @@ -129,9 +162,7 @@ module Sentry 
     | 
|
| 
       129 
162 
     | 
    
         
             
                  client_report_headers, client_report_payload = fetch_pending_client_report
         
     | 
| 
       130 
163 
     | 
    
         
             
                  envelope.add_item(client_report_headers, client_report_payload) if client_report_headers
         
     | 
| 
       131 
164 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
                   
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
                  envelope.to_s
         
     | 
| 
      
 165 
     | 
    
         
            +
                  envelope
         
     | 
| 
       135 
166 
     | 
    
         
             
                end
         
     | 
| 
       136 
167 
     | 
    
         | 
| 
       137 
168 
     | 
    
         
             
                def record_lost_event(reason, item_type)
         
     | 
| 
         @@ -173,6 +204,19 @@ module Sentry 
     | 
|
| 
       173 
204 
     | 
    
         | 
| 
       174 
205 
     | 
    
         
             
                  [item_header, item_payload]
         
     | 
| 
       175 
206 
     | 
    
         
             
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                def reject_rate_limited_items(envelope)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  envelope.items.reject! do |item|
         
     | 
| 
      
 210 
     | 
    
         
            +
                    if is_rate_limited?(item.type)
         
     | 
| 
      
 211 
     | 
    
         
            +
                      log_info("[Transport] Envelope item [#{item.type}] not sent: rate limiting")
         
     | 
| 
      
 212 
     | 
    
         
            +
                      record_lost_event(:ratelimit_backoff, item.type)
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                      true
         
     | 
| 
      
 215 
     | 
    
         
            +
                    else
         
     | 
| 
      
 216 
     | 
    
         
            +
                      false
         
     | 
| 
      
 217 
     | 
    
         
            +
                    end
         
     | 
| 
      
 218 
     | 
    
         
            +
                  end
         
     | 
| 
      
 219 
     | 
    
         
            +
                end
         
     | 
| 
       176 
220 
     | 
    
         
             
              end
         
     | 
| 
       177 
221 
     | 
    
         
             
            end
         
     | 
| 
       178 
222 
     | 
    
         | 
    
        data/lib/sentry/version.rb
    CHANGED
    
    
    
        data/lib/sentry-ruby.rb
    CHANGED
    
    | 
         @@ -17,6 +17,7 @@ require "sentry/span" 
     | 
|
| 
       17 
17 
     | 
    
         
             
            require "sentry/transaction"
         
     | 
| 
       18 
18 
     | 
    
         
             
            require "sentry/hub"
         
     | 
| 
       19 
19 
     | 
    
         
             
            require "sentry/background_worker"
         
     | 
| 
      
 20 
     | 
    
         
            +
            require "sentry/session_flusher"
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
            [
         
     | 
| 
       22 
23 
     | 
    
         
             
              "sentry/rake",
         
     | 
| 
         @@ -31,6 +32,8 @@ end 
     | 
|
| 
       31 
32 
     | 
    
         
             
            module Sentry
         
     | 
| 
       32 
33 
     | 
    
         
             
              META = { "name" => "sentry.ruby", "version" => Sentry::VERSION }.freeze
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
      
 35 
     | 
    
         
            +
              CAPTURED_SIGNATURE = :@__sentry_captured
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       34 
37 
     | 
    
         
             
              LOGGER_PROGNAME = "sentry".freeze
         
     | 
| 
       35 
38 
     | 
    
         | 
| 
       36 
39 
     | 
    
         
             
              SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze
         
     | 
| 
         @@ -59,6 +62,10 @@ module Sentry 
     | 
|
| 
       59 
62 
     | 
    
         
             
                #   @return [BackgroundWorker]
         
     | 
| 
       60 
63 
     | 
    
         
             
                attr_accessor :background_worker
         
     | 
| 
       61 
64 
     | 
    
         | 
| 
      
 65 
     | 
    
         
            +
                # @!attribute [r] session_flusher
         
     | 
| 
      
 66 
     | 
    
         
            +
                #   @return [SessionFlusher]
         
     | 
| 
      
 67 
     | 
    
         
            +
                attr_reader :session_flusher
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
       62 
69 
     | 
    
         
             
                ##### Patch Registration #####
         
     | 
| 
       63 
70 
     | 
    
         | 
| 
       64 
71 
     | 
    
         
             
                # @!visibility private
         
     | 
| 
         @@ -111,9 +118,17 @@ module Sentry 
     | 
|
| 
       111 
118 
     | 
    
         | 
| 
       112 
119 
     | 
    
         
             
                # @!method configuration
         
     | 
| 
       113 
120 
     | 
    
         
             
                #   @!macro configuration
         
     | 
| 
      
 121 
     | 
    
         
            +
                def configuration
         
     | 
| 
      
 122 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 123 
     | 
    
         
            +
                  get_current_client.configuration
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
       114 
126 
     | 
    
         
             
                # @!method send_event
         
     | 
| 
       115 
127 
     | 
    
         
             
                #   @!macro send_event
         
     | 
| 
       116 
     | 
    
         
            -
                 
     | 
| 
      
 128 
     | 
    
         
            +
                def send_event(*args)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 130 
     | 
    
         
            +
                  get_current_client.send_event(*args)
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
       117 
132 
     | 
    
         | 
| 
       118 
133 
     | 
    
         
             
                # @!macro [new] set_extras
         
     | 
| 
       119 
134 
     | 
    
         
             
                #   Updates the scope's extras attribute by merging with the old value.
         
     | 
| 
         @@ -135,13 +150,31 @@ module Sentry 
     | 
|
| 
       135 
150 
     | 
    
         | 
| 
       136 
151 
     | 
    
         
             
                # @!method set_tags
         
     | 
| 
       137 
152 
     | 
    
         
             
                #   @!macro set_tags
         
     | 
| 
      
 153 
     | 
    
         
            +
                def set_tags(*args)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 155 
     | 
    
         
            +
                  get_current_scope.set_tags(*args)
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
       138 
158 
     | 
    
         
             
                # @!method set_extras
         
     | 
| 
       139 
159 
     | 
    
         
             
                #   @!macro set_extras
         
     | 
| 
      
 160 
     | 
    
         
            +
                def set_extras(*args)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 162 
     | 
    
         
            +
                  get_current_scope.set_extras(*args)
         
     | 
| 
      
 163 
     | 
    
         
            +
                end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
       140 
165 
     | 
    
         
             
                # @!method set_user
         
     | 
| 
       141 
166 
     | 
    
         
             
                #   @!macro set_user
         
     | 
| 
      
 167 
     | 
    
         
            +
                def set_user(*args)
         
     | 
| 
      
 168 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 169 
     | 
    
         
            +
                  get_current_scope.set_user(*args)
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
       142 
172 
     | 
    
         
             
                # @!method set_context
         
     | 
| 
       143 
173 
     | 
    
         
             
                #   @!macro set_context
         
     | 
| 
       144 
     | 
    
         
            -
                 
     | 
| 
      
 174 
     | 
    
         
            +
                def set_context(*args)
         
     | 
| 
      
 175 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 176 
     | 
    
         
            +
                  get_current_scope.set_context(*args)
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
       145 
178 
     | 
    
         | 
| 
       146 
179 
     | 
    
         
             
                ##### Main APIs #####
         
     | 
| 
       147 
180 
     | 
    
         | 
| 
         @@ -161,11 +194,18 @@ module Sentry 
     | 
|
| 
       161 
194 
     | 
    
         
             
                  @main_hub = hub
         
     | 
| 
       162 
195 
     | 
    
         
             
                  @background_worker = Sentry::BackgroundWorker.new(config)
         
     | 
| 
       163 
196 
     | 
    
         | 
| 
      
 197 
     | 
    
         
            +
                  @session_flusher = if config.auto_session_tracking
         
     | 
| 
      
 198 
     | 
    
         
            +
                                       Sentry::SessionFlusher.new(config, client)
         
     | 
| 
      
 199 
     | 
    
         
            +
                                     else
         
     | 
| 
      
 200 
     | 
    
         
            +
                                       nil
         
     | 
| 
      
 201 
     | 
    
         
            +
                                     end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
       164 
203 
     | 
    
         
             
                  if config.capture_exception_frame_locals
         
     | 
| 
       165 
204 
     | 
    
         
             
                    exception_locals_tp.enable
         
     | 
| 
       166 
205 
     | 
    
         
             
                  end
         
     | 
| 
       167 
206 
     | 
    
         | 
| 
       168 
207 
     | 
    
         
             
                  at_exit do
         
     | 
| 
      
 208 
     | 
    
         
            +
                    @session_flusher&.kill
         
     | 
| 
       169 
209 
     | 
    
         
             
                    @background_worker.shutdown
         
     | 
| 
       170 
210 
     | 
    
         
             
                  end
         
     | 
| 
       171 
211 
     | 
    
         
             
                end
         
     | 
| 
         @@ -201,7 +241,8 @@ module Sentry 
     | 
|
| 
       201 
241 
     | 
    
         
             
                #
         
     | 
| 
       202 
242 
     | 
    
         
             
                # @return [Breadcrumb, nil]
         
     | 
| 
       203 
243 
     | 
    
         
             
                def add_breadcrumb(breadcrumb, **options)
         
     | 
| 
       204 
     | 
    
         
            -
                   
     | 
| 
      
 244 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 245 
     | 
    
         
            +
                  get_current_hub.add_breadcrumb(breadcrumb, **options)
         
     | 
| 
       205 
246 
     | 
    
         
             
                end
         
     | 
| 
       206 
247 
     | 
    
         | 
| 
       207 
248 
     | 
    
         
             
                # Returns the current active hub.
         
     | 
| 
         @@ -221,14 +262,16 @@ module Sentry 
     | 
|
| 
       221 
262 
     | 
    
         
             
                # Returns the current active client.
         
     | 
| 
       222 
263 
     | 
    
         
             
                # @return [Client, nil]
         
     | 
| 
       223 
264 
     | 
    
         
             
                def get_current_client
         
     | 
| 
       224 
     | 
    
         
            -
                   
     | 
| 
      
 265 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 266 
     | 
    
         
            +
                  get_current_hub.current_client
         
     | 
| 
       225 
267 
     | 
    
         
             
                end
         
     | 
| 
       226 
268 
     | 
    
         | 
| 
       227 
269 
     | 
    
         
             
                # Returns the current active scope.
         
     | 
| 
       228 
270 
     | 
    
         
             
                #
         
     | 
| 
       229 
271 
     | 
    
         
             
                # @return [Scope, nil]
         
     | 
| 
       230 
272 
     | 
    
         
             
                def get_current_scope
         
     | 
| 
       231 
     | 
    
         
            -
                   
     | 
| 
      
 273 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 274 
     | 
    
         
            +
                  get_current_hub.current_scope
         
     | 
| 
       232 
275 
     | 
    
         
             
                end
         
     | 
| 
       233 
276 
     | 
    
         | 
| 
       234 
277 
     | 
    
         
             
                # Clones the main thread's active hub and stores it to the current thread.
         
     | 
| 
         @@ -250,7 +293,8 @@ module Sentry 
     | 
|
| 
       250 
293 
     | 
    
         
             
                # @yieldparam scope [Scope]
         
     | 
| 
       251 
294 
     | 
    
         
             
                # @return [void]
         
     | 
| 
       252 
295 
     | 
    
         
             
                def configure_scope(&block)
         
     | 
| 
       253 
     | 
    
         
            -
                   
     | 
| 
      
 296 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 297 
     | 
    
         
            +
                  get_current_hub.configure_scope(&block)
         
     | 
| 
       254 
298 
     | 
    
         
             
                end
         
     | 
| 
       255 
299 
     | 
    
         | 
| 
       256 
300 
     | 
    
         
             
                # Takes a block and yields a temporary scope.
         
     | 
| 
         @@ -274,7 +318,28 @@ module Sentry 
     | 
|
| 
       274 
318 
     | 
    
         
             
                # @yieldparam scope [Scope]
         
     | 
| 
       275 
319 
     | 
    
         
             
                # @return [void]
         
     | 
| 
       276 
320 
     | 
    
         
             
                def with_scope(&block)
         
     | 
| 
       277 
     | 
    
         
            -
                   
     | 
| 
      
 321 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 322 
     | 
    
         
            +
                  get_current_hub.with_scope(&block)
         
     | 
| 
      
 323 
     | 
    
         
            +
                end
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                # Wrap a given block with session tracking.
         
     | 
| 
      
 326 
     | 
    
         
            +
                # Aggregate sessions in minutely buckets will be recorded
         
     | 
| 
      
 327 
     | 
    
         
            +
                # around this block and flushed every minute.
         
     | 
| 
      
 328 
     | 
    
         
            +
                #
         
     | 
| 
      
 329 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 330 
     | 
    
         
            +
                #   Sentry.with_session_tracking do
         
     | 
| 
      
 331 
     | 
    
         
            +
                #     a = 1 + 1 # new session recorded with :exited status
         
     | 
| 
      
 332 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 333 
     | 
    
         
            +
                #
         
     | 
| 
      
 334 
     | 
    
         
            +
                #   Sentry.with_session_tracking do
         
     | 
| 
      
 335 
     | 
    
         
            +
                #     1 / 0
         
     | 
| 
      
 336 
     | 
    
         
            +
                #   rescue => e
         
     | 
| 
      
 337 
     | 
    
         
            +
                #     Sentry.capture_exception(e) # new session recorded with :errored status
         
     | 
| 
      
 338 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 339 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 340 
     | 
    
         
            +
                def with_session_tracking(&block)
         
     | 
| 
      
 341 
     | 
    
         
            +
                  return yield unless initialized?
         
     | 
| 
      
 342 
     | 
    
         
            +
                  get_current_hub.with_session_tracking(&block)
         
     | 
| 
       278 
343 
     | 
    
         
             
                end
         
     | 
| 
       279 
344 
     | 
    
         | 
| 
       280 
345 
     | 
    
         
             
                # Takes an exception and reports it to Sentry via the currently active hub.
         
     | 
| 
         @@ -282,7 +347,8 @@ module Sentry 
     | 
|
| 
       282 
347 
     | 
    
         
             
                # @yieldparam scope [Scope]
         
     | 
| 
       283 
348 
     | 
    
         
             
                # @return [Event, nil]
         
     | 
| 
       284 
349 
     | 
    
         
             
                def capture_exception(exception, **options, &block)
         
     | 
| 
       285 
     | 
    
         
            -
                   
     | 
| 
      
 350 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 351 
     | 
    
         
            +
                  get_current_hub.capture_exception(exception, **options, &block)
         
     | 
| 
       286 
352 
     | 
    
         
             
                end
         
     | 
| 
       287 
353 
     | 
    
         | 
| 
       288 
354 
     | 
    
         
             
                # Takes a message string and reports it to Sentry via the currently active hub.
         
     | 
| 
         @@ -290,30 +356,41 @@ module Sentry 
     | 
|
| 
       290 
356 
     | 
    
         
             
                # @yieldparam scope [Scope]
         
     | 
| 
       291 
357 
     | 
    
         
             
                # @return [Event, nil]
         
     | 
| 
       292 
358 
     | 
    
         
             
                def capture_message(message, **options, &block)
         
     | 
| 
       293 
     | 
    
         
            -
                   
     | 
| 
      
 359 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 360 
     | 
    
         
            +
                  get_current_hub.capture_message(message, **options, &block)
         
     | 
| 
       294 
361 
     | 
    
         
             
                end
         
     | 
| 
       295 
362 
     | 
    
         | 
| 
       296 
363 
     | 
    
         
             
                # Takes an instance of Sentry::Event and dispatches it to the currently active hub.
         
     | 
| 
       297 
364 
     | 
    
         
             
                #
         
     | 
| 
       298 
365 
     | 
    
         
             
                # @return [Event, nil]
         
     | 
| 
       299 
366 
     | 
    
         
             
                def capture_event(event)
         
     | 
| 
       300 
     | 
    
         
            -
                   
     | 
| 
      
 367 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 368 
     | 
    
         
            +
                  get_current_hub.capture_event(event)
         
     | 
| 
       301 
369 
     | 
    
         
             
                end
         
     | 
| 
       302 
370 
     | 
    
         | 
| 
       303 
371 
     | 
    
         
             
                # Takes or initializes a new Sentry::Transaction and makes a sampling decision for it.
         
     | 
| 
       304 
372 
     | 
    
         
             
                #
         
     | 
| 
       305 
373 
     | 
    
         
             
                # @return [Transaction, nil]
         
     | 
| 
       306 
374 
     | 
    
         
             
                def start_transaction(**options)
         
     | 
| 
       307 
     | 
    
         
            -
                   
     | 
| 
      
 375 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 376 
     | 
    
         
            +
                  get_current_hub.start_transaction(**options)
         
     | 
| 
       308 
377 
     | 
    
         
             
                end
         
     | 
| 
       309 
378 
     | 
    
         | 
| 
       310 
379 
     | 
    
         
             
                # Returns the id of the lastly reported Sentry::Event.
         
     | 
| 
       311 
380 
     | 
    
         
             
                #
         
     | 
| 
       312 
381 
     | 
    
         
             
                # @return [String, nil]
         
     | 
| 
       313 
382 
     | 
    
         
             
                def last_event_id
         
     | 
| 
       314 
     | 
    
         
            -
                   
     | 
| 
      
 383 
     | 
    
         
            +
                  return unless initialized?
         
     | 
| 
      
 384 
     | 
    
         
            +
                  get_current_hub.last_event_id
         
     | 
| 
       315 
385 
     | 
    
         
             
                end
         
     | 
| 
       316 
386 
     | 
    
         | 
| 
      
 387 
     | 
    
         
            +
                # Checks if the exception object has been captured by the SDK.
         
     | 
| 
      
 388 
     | 
    
         
            +
                #
         
     | 
| 
      
 389 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 390 
     | 
    
         
            +
                def exception_captured?(exc)
         
     | 
| 
      
 391 
     | 
    
         
            +
                  return false unless initialized?
         
     | 
| 
      
 392 
     | 
    
         
            +
                  !!exc.instance_variable_get(CAPTURED_SIGNATURE)
         
     | 
| 
      
 393 
     | 
    
         
            +
                end
         
     | 
| 
       317 
394 
     | 
    
         | 
| 
       318 
395 
     | 
    
         
             
                ##### Helpers #####
         
     | 
| 
       319 
396 
     | 
    
         | 
| 
         @@ -344,3 +421,4 @@ end 
     | 
|
| 
       344 
421 
     | 
    
         | 
| 
       345 
422 
     | 
    
         
             
            # patches
         
     | 
| 
       346 
423 
     | 
    
         
             
            require "sentry/net/http"
         
     | 
| 
      
 424 
     | 
    
         
            +
            require "sentry/redis"
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sentry-ruby-core
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 5.0 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Sentry Team
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2022- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2022-03-08 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: concurrent-ruby
         
     | 
| 
         @@ -73,8 +73,11 @@ files: 
     | 
|
| 
       73 
73 
     | 
    
         
             
            - lib/sentry/rack.rb
         
     | 
| 
       74 
74 
     | 
    
         
             
            - lib/sentry/rack/capture_exceptions.rb
         
     | 
| 
       75 
75 
     | 
    
         
             
            - lib/sentry/rake.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - lib/sentry/redis.rb
         
     | 
| 
       76 
77 
     | 
    
         
             
            - lib/sentry/release_detector.rb
         
     | 
| 
       77 
78 
     | 
    
         
             
            - lib/sentry/scope.rb
         
     | 
| 
      
 79 
     | 
    
         
            +
            - lib/sentry/session.rb
         
     | 
| 
      
 80 
     | 
    
         
            +
            - lib/sentry/session_flusher.rb
         
     | 
| 
       78 
81 
     | 
    
         
             
            - lib/sentry/span.rb
         
     | 
| 
       79 
82 
     | 
    
         
             
            - lib/sentry/transaction.rb
         
     | 
| 
       80 
83 
     | 
    
         
             
            - lib/sentry/transaction_event.rb
         
     |