sentry-raven 1.2.3 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 656c9303a15859cbba85c2e9d08003f57df11c7c
4
- data.tar.gz: e3c32559a3f11b62a4d49471d7bd7dab968fe5ab
3
+ metadata.gz: 44601f24d6796ddf4c83b31e84b4bce0bebda016
4
+ data.tar.gz: e06fca1cc97d57477771fabd6b8a05a0d8ac0192
5
5
  SHA512:
6
- metadata.gz: c3357a60cdd946579a473778671fffcb461ec7a3c572244a020f4b39a901b92091a744f055a455d1ef3ef004c45c989ffb7e0042e67a1e38cbacdb1e1dd0e859
7
- data.tar.gz: 7565bc3e31786e9eb670c22e0fd23946c8f1dffc39a743645a6710988b1966d936e95d11598c0901fde1edca1b2e07bb36b0b0810c319552722b6d5910e81fdc
6
+ metadata.gz: 007530478a48c41c6d61ce78cb776a73e78935c8cedeb8232a0acee4d9356a616ffaf71f679cadb79c141b1a27c9e99ec73449539c44b48b332f83f0cea0f9ac
7
+ data.tar.gz: e3c28440058749694dba1637d8da5d374e753b44189416a19411dda21b3ec082caca521e2643001ee4292954b4b15572621f2dbcc745da5cc687552a6ec4b121
@@ -1,16 +1,15 @@
1
1
  ## Inspired by Rails' and Airbrake's backtrace parsers.
2
2
 
3
3
  module Raven
4
-
5
4
  # Front end to parsing the backtrace for each notice
6
5
  class Backtrace
7
6
  # Handles backtrace parsing line by line
8
7
  class Line
9
8
  # regexp (optionnally allowing leading X: for windows support)
10
- RUBY_INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+|<.*>):(\d+)(?::in `([^']+)')?$}
9
+ RUBY_INPUT_FORMAT = /^((?:[a-zA-Z]:)?[^:]+|<.*>):(\d+)(?::in `([^']+)')?$/
11
10
 
12
11
  # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
13
- JAVA_INPUT_FORMAT = %r{^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$}
12
+ JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
14
13
 
15
14
  # The file portion of the line (such as app/models/user.rb)
16
15
  attr_reader :file
@@ -47,7 +46,7 @@ module Raven
47
46
  end
48
47
 
49
48
  def in_app
50
- if self.file =~ self.class.in_app_pattern
49
+ if file =~ self.class.in_app_pattern
51
50
  true
52
51
  else
53
52
  false
@@ -7,7 +7,7 @@ require 'raven/processor/removecircularreferences'
7
7
  require 'raven/processor/utf8conversion'
8
8
  require 'raven/processor/cookies'
9
9
  require 'raven/processor/post_data'
10
- require 'raven/processor/truncator'
10
+ require 'raven/processor/http_headers'
11
11
  require 'raven/configuration'
12
12
  require 'raven/context'
13
13
  require 'raven/client'
@@ -19,13 +19,14 @@ require 'raven/interfaces/single_exception'
19
19
  require 'raven/interfaces/stack_trace'
20
20
  require 'raven/interfaces/http'
21
21
  require 'raven/utils/deep_merge'
22
+ require 'raven/utils/real_ip'
22
23
  require 'raven/instance'
23
24
 
24
25
  require 'forwardable'
25
26
  require 'English'
26
27
 
27
28
  module Raven
28
- AVAILABLE_INTEGRATIONS = %w[delayed_job railties sidekiq rack rake].freeze
29
+ AVAILABLE_INTEGRATIONS = %w(delayed_job railties sidekiq rack rack-timeout rake).freeze
29
30
 
30
31
  class << self
31
32
  extend Forwardable
@@ -63,7 +64,7 @@ module Raven
63
64
  integrations_to_load = Raven::AVAILABLE_INTEGRATIONS & only_integrations
64
65
  not_found_integrations = only_integrations - integrations_to_load
65
66
  if not_found_integrations.any?
66
- self.logger.warn "Integrations do not exist: #{not_found_integrations.join ', '}"
67
+ logger.warn "Integrations do not exist: #{not_found_integrations.join ', '}"
67
68
  end
68
69
  integrations_to_load &= Gem.loaded_specs.keys
69
70
  # TODO(dcramer): integrations should have some additional checks baked-in
@@ -78,7 +79,7 @@ module Raven
78
79
  def load_integration(integration)
79
80
  require "raven/integrations/#{integration}"
80
81
  rescue Exception => error
81
- self.logger.warn "Unable to load raven/integrations/#{integration}: #{error}"
82
+ logger.warn "Unable to load raven/integrations/#{integration}: #{error}"
82
83
  end
83
84
 
84
85
  def safely_prepend(module_name, opts = {})
@@ -1,6 +1,6 @@
1
1
  module Raven
2
2
  class CLI
3
- def self.test(dsn = nil, silent = false)
3
+ def self.test(dsn = nil, silent = false) # rubocop:disable all
4
4
  if silent
5
5
  Raven.configuration.logger = ::Logger.new(nil)
6
6
  else
@@ -17,7 +17,7 @@ module Raven
17
17
  Raven.configuration.dsn = dsn if dsn
18
18
 
19
19
  # wipe out env settings to ensure we send the event
20
- unless Raven.configuration.capture_in_current_environment?
20
+ unless Raven.configuration.capture_allowed?
21
21
  env_name = Raven.configuration.environments.pop || 'production'
22
22
  Raven.logger.debug "Setting environment to #{env_name}"
23
23
  Raven.configuration.current_environment = env_name
@@ -40,7 +40,7 @@ module Raven
40
40
  else
41
41
  Raven.logger.debug "-> event ID: #{evt.id}"
42
42
  end
43
- elsif evt #async configuration
43
+ elsif evt # async configuration
44
44
  if evt.value.is_a? Hash
45
45
  Raven.logger.debug "-> event ID: #{evt.value[:event_id]}"
46
46
  else
@@ -38,7 +38,7 @@ module Raven
38
38
 
39
39
  begin
40
40
  transport.send_event(generate_auth_header, encoded_data,
41
- :content_type => content_type)
41
+ :content_type => content_type)
42
42
  successful_send
43
43
  rescue => e
44
44
  failed_send(e, event)
@@ -63,7 +63,7 @@ module Raven
63
63
  private
64
64
 
65
65
  def encode(event)
66
- hash = @processors.reduce(event.to_hash) { |memo, p| p.process(memo) }
66
+ hash = @processors.reduce(event.to_hash) { |a, e| e.process(a) }
67
67
  encoded = JSON.generate(hash)
68
68
 
69
69
  case configuration.encoding
@@ -115,7 +115,7 @@ module Raven
115
115
  def should_try?
116
116
  return true if @status == :online
117
117
 
118
- interval = @retry_after || [@retry_number, 6].min ** 2
118
+ interval = @retry_after || [@retry_number, 6].min**2
119
119
  return true if Time.now - @last_check >= interval
120
120
 
121
121
  false
@@ -3,120 +3,140 @@ require 'uri'
3
3
 
4
4
  module Raven
5
5
  class Configuration
6
- # Simple server string (setter provided below)
7
- attr_reader :server
8
-
9
- # Public key for authentication with the Sentry server
10
- attr_accessor :public_key
11
-
12
- # Secret key for authentication with the Sentry server
13
- attr_accessor :secret_key
6
+ # Directories to be recognized as part of your app. e.g. if you
7
+ # have an `engines` dir at the root of your project, you may want
8
+ # to set this to something like /(app|config|engines|lib)/
9
+ attr_accessor :app_dirs_pattern
14
10
 
15
- # Accessors for the component parts of the DSN
16
- attr_accessor :scheme
17
- attr_accessor :host
18
- attr_accessor :port
19
- attr_accessor :path
11
+ # Provide an object that responds to `call` to send events asynchronously.
12
+ # E.g.: lambda { |event| Thread.new { Raven.send_event(event) } }
13
+ attr_reader :async
14
+ alias async? async
20
15
 
21
- # Project ID number to send to the Sentry server
22
- attr_accessor :project_id
16
+ # Number of lines of code context to capture, or nil for none
17
+ attr_accessor :context_lines
23
18
 
24
- # Project directory root
25
- attr_reader :project_root
19
+ # RACK_ENV by default.
20
+ attr_reader :current_environment
26
21
 
27
- # Encoding type for event bodies
22
+ # Encoding type for event bodies. Must be :json or :gzip.
28
23
  attr_reader :encoding
29
24
 
30
- # Logger to use internally
31
- attr_accessor :logger
32
-
33
- # Silence ready message
34
- attr_accessor :silence_ready
35
-
36
- # Number of lines of code context to capture, or nil for none
37
- attr_accessor :context_lines
38
-
39
- # Whitelist of environments that will send notifications to Sentry
25
+ # Whitelist of environments that will send notifications to Sentry. Array of Strings.
40
26
  attr_accessor :environments
41
27
 
42
- # Include module versions in reports?
43
- attr_accessor :send_modules
28
+ # Logger 'progname's to exclude from breadcrumbs
29
+ attr_accessor :exclude_loggers
44
30
 
45
- # Which exceptions should never be sent
31
+ # Array of exception classes that should never be sent. See IGNORE_DEFAULT.
32
+ # You should probably append to this rather than overwrite it.
46
33
  attr_accessor :excluded_exceptions
47
34
 
48
- # Processors to run on data before sending upstream
49
- attr_accessor :processors
35
+ # DSN component - set automatically if DSN provided
36
+ attr_accessor :host
50
37
 
51
- # Timeout when waiting for the server to return data in seconds
52
- attr_accessor :timeout
38
+ # The Faraday adapter to be used. Will default to Net::HTTP when not set.
39
+ attr_accessor :http_adapter
53
40
 
54
- # Timeout waiting for the connection to open in seconds
41
+ # Logger used by Raven. In Rails, this is the Rails logger, otherwise
42
+ # Raven provides its own Raven::Logger.
43
+ attr_accessor :logger
44
+
45
+ # Timeout waiting for the Sentry server connection to open in seconds
55
46
  attr_accessor :open_timeout
56
47
 
57
- # Should the SSL certificate of the server be verified?
58
- attr_accessor :ssl_verification
48
+ # DSN component - set automatically if DSN provided
49
+ attr_accessor :path
59
50
 
60
- # The path to the SSL certificate file
61
- attr_accessor :ssl_ca_file
51
+ # DSN component - set automatically if DSN provided
52
+ attr_accessor :port
62
53
 
63
- # SSl settings passed direactly to faraday's ssl option
64
- attr_accessor :ssl
54
+ # Processors to run on data before sending upstream. See DEFAULT_PROCESSORS.
55
+ # You should probably append to this rather than overwrite it.
56
+ attr_accessor :processors
65
57
 
66
- # Proxy information to pass to the HTTP adapter
58
+ # Project ID number to send to the Sentry server
59
+ # If you provide a DSN, this will be set automatically.
60
+ attr_accessor :project_id
61
+
62
+ # Project directory root for in_app detection. Could be Rails root, etc.
63
+ # Set automatically for Rails.
64
+ attr_reader :project_root
65
+
66
+ # Proxy information to pass to the HTTP adapter (via Faraday)
67
67
  attr_accessor :proxy
68
68
 
69
- attr_reader :current_environment
69
+ # Public key for authentication with the Sentry server
70
+ # If you provide a DSN, this will be set automatically.
71
+ attr_accessor :public_key
70
72
 
71
- # The Faraday adapter to be used. Will default to Net::HTTP when not set.
72
- attr_accessor :http_adapter
73
+ # Turns on ActiveSupport breadcrumbs integration
74
+ attr_accessor :rails_activesupport_breadcrumbs
73
75
 
74
- attr_accessor :server_name
76
+ # Rails catches exceptions in the ActionDispatch::ShowExceptions or
77
+ # ActionDispatch::DebugExceptions middlewares, depending on the environment.
78
+ # When `rails_report_rescued_exceptions` is true (it is by default), Raven
79
+ # will report exceptions even when they are rescued by these middlewares.
80
+ attr_accessor :rails_report_rescued_exceptions
75
81
 
82
+ # Release tag to be passed with every event sent to Sentry.
83
+ # We automatically try to set this to a git SHA or Capistrano release.
76
84
  attr_accessor :release
77
85
 
78
- # DEPRECATED: This option is now ignored as we use our own adapter.
79
- attr_accessor :json_adapter
86
+ # Boolean - sanitize values that look like credit card numbers
87
+ attr_accessor :sanitize_credit_cards
80
88
 
81
- # Default tags for events
82
- attr_accessor :tags
89
+ # By default, Sentry censors Hash values when their keys match things like
90
+ # "secret", "password", etc. Provide an array of Strings that, when matched in
91
+ # a hash key, will be censored and not sent to Sentry.
92
+ attr_accessor :sanitize_fields
83
93
 
84
- # Optional Proc to be used to send events asynchronously.
85
- attr_reader :async
94
+ # Sanitize additional HTTP headers - only Authorization is removed by default.
95
+ attr_accessor :sanitize_http_headers
86
96
 
87
- # Optional Proc, called when the Sentry server cannot be contacted for any reason
88
- attr_reader :transport_failure_callback
97
+ # DSN component - set automatically if DSN provided.
98
+ # Otherwise, can be one of "http", "https", or "dummy"
99
+ attr_accessor :scheme
89
100
 
90
- # Directories to be recognized as part of your app. e.g. if you
91
- # have an `engines` dir at the root of your project, you may want
92
- # to set this to something like /(app|config|engines|lib)/
93
- attr_accessor :app_dirs_pattern
101
+ # Secret key for authentication with the Sentry server
102
+ # If you provide a DSN, this will be set automatically.
103
+ attr_accessor :secret_key
94
104
 
95
- # Rails catches exceptions in the ActionDispatch::ShowExceptions or
96
- # ActionDispatch::DebugExceptions middlewares, depending on the environment.
97
- # When `rails_report_rescued_exceptions` is true (it is by default), Raven
98
- # will report exceptions even when they are rescued by these middlewares.
99
- attr_accessor :rails_report_rescued_exceptions
100
- # Deprecated accessor
101
- attr_reader :catch_debugged_exceptions
105
+ # Include module versions in reports - boolean.
106
+ attr_accessor :send_modules
102
107
 
103
- # Turns on ActiveSupport breadcrumbs integration
104
- attr_accessor :rails_activesupport_breadcrumbs
108
+ # Simple server string - set this to the DSN found on your Sentry settings.
109
+ attr_reader :server
105
110
 
106
- # Provide a configurable callback to determine event capture
111
+ attr_accessor :server_name
112
+
113
+ # Provide a configurable callback to determine event capture.
114
+ # Note that the object passed into the block will be a String (messages) or
115
+ # an exception.
116
+ # e.g. lambda { |exc_or_msg| exc_or_msg.some_attr == false }
107
117
  attr_accessor :should_capture
108
118
 
109
- # additional fields to sanitize
110
- attr_accessor :sanitize_fields
119
+ # Silences ready message when true.
120
+ attr_accessor :silence_ready
111
121
 
112
- # Sanitize values that look like credit card numbers
113
- attr_accessor :sanitize_credit_cards
122
+ # SSL settings passed directly to Faraday's ssl option
123
+ attr_accessor :ssl
114
124
 
115
- # Truncate any strings longer than this bytesize before sending
116
- attr_accessor :event_bytesize_limit
125
+ # The path to the SSL certificate file
126
+ attr_accessor :ssl_ca_file
117
127
 
118
- # Logger 'progname's to exclude from breadcrumbs
119
- attr_accessor :exclude_loggers
128
+ # Should the SSL certificate of the server be verified?
129
+ attr_accessor :ssl_verification
130
+
131
+ # Default tags for events. Hash.
132
+ attr_accessor :tags
133
+
134
+ # Timeout when waiting for the server to return data in seconds.
135
+ attr_accessor :timeout
136
+
137
+ # Optional Proc, called when the Sentry server cannot be contacted for any reason
138
+ # E.g. lambda { |event| Thread.new { MyJobProcessor.send_email(event) } }
139
+ attr_reader :transport_failure_callback
120
140
 
121
141
  IGNORE_DEFAULT = [
122
142
  'AbstractController::ActionNotFound',
@@ -126,46 +146,45 @@ module Raven
126
146
  'ActiveRecord::RecordNotFound',
127
147
  'CGI::Session::CookieStore::TamperedWithCookie',
128
148
  'Mongoid::Errors::DocumentNotFound',
129
- 'Sinatra::NotFound',
149
+ 'Sinatra::NotFound'
130
150
  ].freeze
131
151
 
152
+ # Note the order - we have to remove circular references and bad characters
153
+ # before passing to other processors.
132
154
  DEFAULT_PROCESSORS = [
133
- Raven::Processor::Truncator,
134
155
  Raven::Processor::RemoveCircularReferences,
135
156
  Raven::Processor::UTF8Conversion,
136
157
  Raven::Processor::SanitizeData,
137
158
  Raven::Processor::Cookies,
138
159
  Raven::Processor::PostData,
160
+ Raven::Processor::HTTPHeaders
139
161
  ].freeze
140
162
 
141
163
  def initialize
142
- self.server = ENV['SENTRY_DSN'] if ENV['SENTRY_DSN']
143
- @context_lines = 3
164
+ self.async = false
165
+ self.context_lines = 3
144
166
  self.current_environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'default'
145
- self.send_modules = true
146
- self.excluded_exceptions = IGNORE_DEFAULT.dup
147
- self.processors = DEFAULT_PROCESSORS.dup
148
- self.ssl_verification = true
149
167
  self.encoding = 'gzip'
150
- self.timeout = 2
168
+ self.environments = []
169
+ self.exclude_loggers = []
170
+ self.excluded_exceptions = IGNORE_DEFAULT.dup
151
171
  self.open_timeout = 1
172
+ self.processors = DEFAULT_PROCESSORS.dup
152
173
  self.proxy = nil
153
- self.tags = {}
154
- self.async = false
155
- self.rails_report_rescued_exceptions = true
156
174
  self.rails_activesupport_breadcrumbs = false
157
- self.transport_failure_callback = false
158
- self.sanitize_fields = []
159
- self.sanitize_credit_cards = true
160
- self.event_bytesize_limit = 8_000
161
- self.environments = []
162
- self.exclude_loggers = []
163
-
175
+ self.rails_report_rescued_exceptions = true
164
176
  self.release = detect_release
165
-
166
- # Try to resolve the hostname to an FQDN, but fall back to whatever the load name is
167
- self.server_name = Socket.gethostname
168
- self.server_name = Socket.gethostbyname(hostname).first rescue server_name
177
+ self.sanitize_credit_cards = true
178
+ self.sanitize_fields = []
179
+ self.sanitize_http_headers = []
180
+ self.send_modules = true
181
+ self.server = ENV['SENTRY_DSN'] if ENV['SENTRY_DSN']
182
+ self.server_name = resolve_hostname
183
+ self.should_capture = false
184
+ self.ssl_verification = true
185
+ self.tags = {}
186
+ self.timeout = 2
187
+ self.transport_failure_callback = false
169
188
  end
170
189
 
171
190
  def server=(value)
@@ -189,38 +208,46 @@ module Raven
189
208
  @server << ":#{port}" unless port == { 'http' => 80, 'https' => 443 }[scheme]
190
209
  @server << path
191
210
  end
211
+ alias dsn= server=
192
212
 
193
213
  def encoding=(encoding)
194
- raise Error.new('Unsupported encoding') unless %w(gzip json).include? encoding
214
+ raise(Error, 'Unsupported encoding') unless %w(gzip json).include? encoding
195
215
  @encoding = encoding
196
216
  end
197
217
 
198
- alias dsn= server=
199
-
200
218
  def async=(value)
201
- raise ArgumentError.new("async must be callable (or false to disable)") unless value == false || value.respond_to?(:call)
219
+ unless value == false || value.respond_to?(:call)
220
+ raise(ArgumentError, "async must be callable (or false to disable)")
221
+ end
202
222
  @async = value
203
223
  end
204
224
 
205
- alias async? async
206
-
207
225
  def transport_failure_callback=(value)
208
- raise ArgumentError.new("transport_failure_callback must be callable (or false to disable)") unless value == false || value.respond_to?(:call)
226
+ unless value == false || value.respond_to?(:call)
227
+ raise(ArgumentError, "transport_failure_callback must be callable (or false to disable)")
228
+ end
209
229
  @transport_failure_callback = value
210
230
  end
211
231
 
232
+ def should_capture=(value)
233
+ unless value == false || value.respond_to?(:call)
234
+ raise ArgumentError, "should_capture must be callable (or false to disable)"
235
+ end
236
+ @should_capture = value
237
+ end
238
+
212
239
  # Allows config options to be read like a hash
213
240
  #
214
241
  # @param [Symbol] option Key for a given attribute
215
242
  def [](option)
216
- send(option)
243
+ public_send(option)
217
244
  end
218
245
 
219
246
  def current_environment=(environment)
220
247
  @current_environment = environment.to_s
221
248
  end
222
249
 
223
- def capture_allowed?(message_or_exc)
250
+ def capture_allowed?(message_or_exc = nil)
224
251
  capture_in_current_environment? &&
225
252
  capture_allowed_by_callback?(message_or_exc)
226
253
  end
@@ -228,26 +255,10 @@ module Raven
228
255
  # If we cannot capture, we cannot send.
229
256
  alias sending_allowed? capture_allowed?
230
257
 
231
- def capture_in_current_environment?
232
- !!server && (environments.empty? || environments.include?(current_environment))
233
- end
234
-
235
- def capture_allowed_by_callback?(message_or_exc)
236
- return true unless should_capture
237
- should_capture.call(*[message_or_exc])
238
- end
239
-
240
258
  def verify!
241
- raise Error.new('No server specified') unless server
242
- raise Error.new('No public key specified') unless public_key
243
- raise Error.new('No secret key specified') unless secret_key
244
- raise Error.new('No project ID specified') unless project_id
245
- end
246
-
247
- def detect_release
248
- detect_release_from_heroku ||
249
- detect_release_from_capistrano ||
250
- detect_release_from_git
259
+ %w(server public_key secret_key project_id).each do |key|
260
+ raise(Error, "No #{key} specified") unless public_send key
261
+ end
251
262
  end
252
263
 
253
264
  def project_root=(root_dir)
@@ -255,11 +266,10 @@ module Raven
255
266
  Backtrace::Line.instance_variable_set(:@in_app_pattern, nil) # blow away cache
256
267
  end
257
268
 
258
- def catch_debugged_exceptions=(boolean)
259
- Raven.logger.warn "DEPRECATION WARNING: catch_debugged_exceptions has been \
260
- renamed to rails_report_rescued_exceptions. catch_debugged_exceptions will \
261
- be removed in raven-ruby 0.17.0"
262
- self.rails_report_rescued_exceptions = boolean
269
+ def detect_release
270
+ detect_release_from_heroku ||
271
+ detect_release_from_capistrano ||
272
+ detect_release_from_git
263
273
  end
264
274
 
265
275
  private
@@ -278,5 +288,21 @@ module Raven
278
288
  def detect_release_from_git
279
289
  `git rev-parse --short HEAD`.strip if File.directory?(".git") rescue nil
280
290
  end
291
+
292
+ def capture_in_current_environment?
293
+ !!server && (environments.empty? || environments.include?(current_environment))
294
+ end
295
+
296
+ def capture_allowed_by_callback?(message_or_exc)
297
+ return true if !should_capture || message_or_exc.nil?
298
+ should_capture.call(*[message_or_exc])
299
+ end
300
+
301
+ # Try to resolve the hostname to an FQDN, but fall back to whatever
302
+ # the load name is.
303
+ def resolve_hostname
304
+ Socket.gethostname ||
305
+ Socket.gethostbyname(hostname).first rescue server_name
306
+ end
281
307
  end
282
308
  end
@@ -8,7 +8,6 @@ require 'raven/error'
8
8
  require 'raven/linecache'
9
9
 
10
10
  module Raven
11
-
12
11
  class Event
13
12
  LOG_LEVELS = {
14
13
  "debug" => 10,
@@ -16,7 +15,7 @@ module Raven
16
15
  "warn" => 30,
17
16
  "warning" => 30,
18
17
  "error" => 40,
19
- "fatal" => 50,
18
+ "fatal" => 50
20
19
  }.freeze
21
20
 
22
21
  BACKTRACE_RE = /^(.+?):(\d+)(?::in `(.+?)')?$/
@@ -25,15 +24,15 @@ module Raven
25
24
 
26
25
  attr_reader :id
27
26
  attr_accessor :project, :message, :timestamp, :time_spent, :level, :logger,
28
- :culprit, :server_name, :release, :modules, :extra, :tags, :context, :configuration,
29
- :checksum, :fingerprint, :environment
27
+ :culprit, :server_name, :release, :modules, :extra, :tags, :context, :configuration,
28
+ :checksum, :fingerprint, :environment
30
29
 
31
30
  def initialize(init = {})
32
31
  @configuration = Raven.configuration
33
32
  @interfaces = {}
34
33
  @breadcrumbs = Raven.breadcrumbs
35
34
  @context = Raven.context
36
- @id = generate_event_id
35
+ @id = SecureRandom.uuid
37
36
  @project = nil
38
37
  @message = nil
39
38
  @timestamp = Time.now.utc
@@ -59,6 +58,10 @@ module Raven
59
58
  end
60
59
  end
61
60
 
61
+ if @context.rack_env
62
+ @context.user[:ip_address] = calculate_real_ip_from_rack
63
+ end
64
+
62
65
  init.each_pair { |key, val| instance_variable_set('@' + key.to_s, val) }
63
66
 
64
67
  @user = @context.user.merge(@user)
@@ -67,7 +70,7 @@ module Raven
67
70
 
68
71
  # Some type coercion
69
72
  @timestamp = @timestamp.strftime('%Y-%m-%dT%H:%M:%S') if @timestamp.is_a?(Time)
70
- @time_spent = (@time_spent*1000).to_i if @time_spent.is_a?(Float)
73
+ @time_spent = (@time_spent * 1000).to_i if @time_spent.is_a?(Float)
71
74
  @level = LOG_LEVELS[@level.to_s.downcase] if @level.is_a?(String) || @level.is_a?(Symbol)
72
75
  end
73
76
 
@@ -99,7 +102,9 @@ module Raven
99
102
  end
100
103
 
101
104
  def from_message(message, options = {})
105
+ message = message.byteslice(0...10_000) # Messages limited to 10kb
102
106
  configuration = options[:configuration] || Raven.configuration
107
+
103
108
  new(options) do |evt|
104
109
  evt.configuration = configuration
105
110
  evt.message = message
@@ -133,9 +138,7 @@ module Raven
133
138
 
134
139
  while exc.respond_to?(:cause) && exc.cause
135
140
  exc = exc.cause
136
- if context.include?(exc.object_id)
137
- break
138
- end
141
+ break if context.include?(exc.object_id)
139
142
  exceptions << exc
140
143
  context.add(exc.object_id)
141
144
  end
@@ -194,7 +197,7 @@ module Raven
194
197
 
195
198
  def interface(name, value = nil, &block)
196
199
  int = Raven.find_interface(name)
197
- raise Error.new("Unknown interface: #{name}") unless int
200
+ raise(Error, "Unknown interface: #{name}") unless int
198
201
  @interfaces[int.name] = int.new(value, &block) if value || block
199
202
  @interfaces[int.name]
200
203
  end
@@ -215,7 +218,7 @@ module Raven
215
218
  :time_spent => @time_spent,
216
219
  :level => @level,
217
220
  :project => @project,
218
- :platform => PLATFORM,
221
+ :platform => PLATFORM
219
222
  }
220
223
  data[:logger] = @logger if @logger
221
224
  data[:culprit] = @culprit if @culprit
@@ -236,7 +239,7 @@ module Raven
236
239
  end
237
240
 
238
241
  def get_file_context(filename, lineno, context)
239
- return nil, nil, nil unless Raven::LineCache.is_valid_file(filename)
242
+ return nil, nil, nil unless Raven::LineCache.valid_file?(filename)
240
243
  lines = Array.new(2 * context + 1) do |i|
241
244
  Raven::LineCache.getline(filename, lineno - context + i)
242
245
  end
@@ -248,24 +251,29 @@ module Raven
248
251
  "#{lastframe.filename} in #{lastframe.function} at line #{lastframe.lineno}" if lastframe
249
252
  end
250
253
 
254
+ def to_json_compatible
255
+ JSON.parse(JSON.generate(to_hash))
256
+ end
257
+
251
258
  # For cross-language compat
252
259
  class << self
253
- alias :captureException :from_exception
254
- alias :captureMessage :from_message
255
- alias :capture_exception :from_exception
256
- alias :capture_message :from_message
260
+ alias captureException from_exception
261
+ alias captureMessage from_message
262
+ alias capture_exception from_exception
263
+ alias capture_message from_message
257
264
  end
258
265
 
259
266
  private
260
267
 
261
- def generate_event_id
262
- # generate a uuid. copy-pasted from SecureRandom, this method is not
263
- # available in <1.9.
264
- ary = SecureRandom.random_bytes(16).unpack("NnnnnN")
265
- ary[2] = (ary[2] & 0x0fff) | 0x4000
266
- ary[3] = (ary[3] & 0x3fff) | 0x8000
267
- uuid = "%08x-%04x-%04x-%04x-%04x%08x" % ary
268
- ::Digest::MD5.hexdigest(uuid)
268
+ # When behind a proxy (or if the user is using a proxy), we can't use
269
+ # REMOTE_ADDR to determine the Event IP, and must use other headers instead.
270
+ def calculate_real_ip_from_rack
271
+ Utils::RealIp.new(
272
+ :remote_addr => context.rack_env["REMOTE_ADDR"],
273
+ :client_ip => context.rack_env["HTTP_CLIENT_IP"],
274
+ :real_ip => context.rack_env["HTTP_X_REAL_IP"],
275
+ :forwarded_for => context.rack_env["HTTP_X_FORWARDED_FOR"]
276
+ ).calculate_ip
269
277
  end
270
278
  end
271
279
  end
@@ -58,7 +58,7 @@ module Raven
58
58
  # Tell the log that the client is good to go
59
59
  def report_status
60
60
  return if configuration.silence_ready
61
- if configuration.capture_in_current_environment?
61
+ if configuration.capture_allowed?
62
62
  logger.info "Raven #{VERSION} ready to catch errors"
63
63
  else
64
64
  logger.info "Raven #{VERSION} configured not to capture errors."
@@ -119,7 +119,14 @@ module Raven
119
119
  if (evt = Event.send("from_" + message_or_exc, obj, options))
120
120
  yield evt if block_given?
121
121
  if configuration.async?
122
- configuration.async.call(evt)
122
+ begin
123
+ # We have to convert to a JSON-like hash, because background job
124
+ # processors (esp ActiveJob) may not like weird types in the event hash
125
+ configuration.async.call(evt.to_json_compatible)
126
+ rescue => ex
127
+ Raven.logger.error("async event sending failed: #{ex.message}")
128
+ send_event(evt)
129
+ end
123
130
  else
124
131
  send_event(evt)
125
132
  end
@@ -21,7 +21,7 @@ module Delayed
21
21
  :locked_by => job.locked_by,
22
22
  :queue => job.queue,
23
23
  :created_at => job.created_at
24
- }
24
+ }
25
25
  }
26
26
  # last_error can be nil
27
27
  extra[:last_error] = job.last_error[0...100] if job.last_error
@@ -33,12 +33,12 @@ module Delayed
33
33
  extra[:active_job] = job.payload_object.job_data
34
34
  end
35
35
  ::Raven.capture_exception(exception,
36
- :logger => 'delayed_job',
37
- :tags => {
38
- :delayed_job_queue => job.queue,
39
- :delayed_job_id => job.id
40
- },
41
- :extra => extra)
36
+ :logger => 'delayed_job',
37
+ :tags => {
38
+ :delayed_job_queue => job.queue,
39
+ :delayed_job_id => job.id
40
+ },
41
+ :extra => extra)
42
42
 
43
43
  # Make sure we propagate the failure!
44
44
  raise exception
@@ -49,7 +49,6 @@ module Delayed
49
49
  end
50
50
  end
51
51
  end
52
-
53
52
  end
54
53
  end
55
54
 
@@ -0,0 +1,16 @@
1
+ # rubocop:disable Style/FileName
2
+ # We need to do this because of the way integration loading works
3
+ require 'rack-timeout'
4
+
5
+ # This integration is a good example of how to change how exceptions
6
+ # get grouped by Sentry's UI. Simply override #raven_context in
7
+ # the exception class, and append something to the fingerprint
8
+ # that will distinguish exceptions in the way you desire.
9
+ module RackTimeoutExtensions
10
+ def raven_context
11
+ { :fingerprint => ["{{ default }}", env["REQUEST_URI"]] }
12
+ end
13
+ end
14
+
15
+ Rack::Timeout::Error.include RackTimeoutExtensions
16
+ Rack::Timeout::RequestTimeoutException.include RackTimeoutExtensions
@@ -51,7 +51,6 @@ module Raven
51
51
  rescue Error
52
52
  raise # Don't capture Raven errors
53
53
  rescue Exception => e
54
- Raven.logger.debug "Collecting %p: %s" % [ e.class, e.message ]
55
54
  Raven::Rack.capture_exception(e, env)
56
55
  raise
57
56
  end
@@ -84,8 +83,8 @@ module Raven
84
83
  def read_data_from(request)
85
84
  if request.form_data?
86
85
  request.POST
87
- elsif request.body
88
- data = request.body.read
86
+ elsif request.body # JSON requests, etc
87
+ data = request.body.read(2048) # Sentry server limit
89
88
  request.body.rewind
90
89
  data
91
90
  end
@@ -12,7 +12,7 @@ module Raven
12
12
  :arguments => arguments,
13
13
  :scheduled_at => scheduled_at,
14
14
  :job_id => job_id,
15
- :locale => locale,
15
+ :locale => locale
16
16
  }
17
17
 
18
18
  # Add provider_job_id details if Rails 5
@@ -4,7 +4,7 @@ require 'raven/integrations/tasks'
4
4
 
5
5
  module Rake
6
6
  class Application
7
- alias :orig_display_error_messsage :display_error_message
7
+ alias orig_display_error_messsage display_error_message
8
8
  def display_error_message(ex)
9
9
  Raven.capture_exception ex, :logger => 'rake', :tags => { 'rake_task' => @name }
10
10
  orig_display_error_messsage(ex)
@@ -8,7 +8,7 @@ module Raven
8
8
  yield
9
9
  rescue Exception => ex
10
10
  Raven.capture_exception(ex, :extra => { :sidekiq => msg },
11
- :time_spent => Time.now-started_at)
11
+ :time_spent => Time.now - started_at)
12
12
  raise
13
13
  ensure
14
14
  Context.clear!
@@ -26,10 +26,10 @@ if Sidekiq::VERSION < '3'
26
26
  end
27
27
  else
28
28
  Sidekiq.configure_server do |config|
29
- config.error_handlers << Proc.new do |ex, context|
29
+ config.error_handlers << proc do |ex, context|
30
30
  Raven.capture_exception(ex, :extra => {
31
- :sidekiq => filter_context(context)
32
- })
31
+ :sidekiq => filter_context(context)
32
+ })
33
33
  end
34
34
  end
35
35
  end
@@ -1,6 +1,4 @@
1
1
  module Raven
2
-
3
- # TODO: a constant isn't appropriate here, refactor
4
2
  INTERFACES = {} # rubocop:disable Style/MutableConstant
5
3
 
6
4
  class Interface
@@ -17,7 +15,7 @@ module Raven
17
15
  end
18
16
 
19
17
  def to_hash
20
- Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] } ]
18
+ Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
21
19
  end
22
20
  end
23
21
 
@@ -7,9 +7,7 @@ module Raven
7
7
 
8
8
  def to_hash(*args)
9
9
  data = super(*args)
10
- if data[:values]
11
- data[:values] = data[:values].map(&:to_hash)
12
- end
10
+ data[:values] = data[:values].map(&:to_hash) if data[:values]
13
11
  data
14
12
  end
15
13
  end
@@ -9,9 +9,7 @@ module Raven
9
9
 
10
10
  def to_hash(*args)
11
11
  data = super(*args)
12
- if data[:stacktrace]
13
- data[:stacktrace] = data[:stacktrace].to_hash
14
- end
12
+ data[:stacktrace] = data[:stacktrace].to_hash if data[:stacktrace]
15
13
  data
16
14
  end
17
15
  end
@@ -34,7 +34,7 @@ module Raven
34
34
  end
35
35
 
36
36
  def filename
37
- return nil if self.abs_path.nil?
37
+ return nil if abs_path.nil?
38
38
 
39
39
  prefix =
40
40
  if under_project_root? && in_app
@@ -45,7 +45,7 @@ module Raven
45
45
  longest_load_path
46
46
  end
47
47
 
48
- prefix ? self.abs_path[prefix.to_s.chomp(File::SEPARATOR).length+1..-1] : self.abs_path
48
+ prefix ? abs_path[prefix.to_s.chomp(File::SEPARATOR).length + 1..-1] : abs_path
49
49
  end
50
50
 
51
51
  def under_project_root?
@@ -57,16 +57,16 @@ module Raven
57
57
  end
58
58
 
59
59
  def longest_load_path
60
- $LOAD_PATH.select { |s| self.abs_path.start_with?(s.to_s) }.sort_by { |s| s.to_s.length }.last
60
+ $LOAD_PATH.select { |s| abs_path.start_with?(s.to_s) }.sort_by { |s| s.to_s.length }.last
61
61
  end
62
62
 
63
63
  def to_hash(*args)
64
64
  data = super(*args)
65
- data[:filename] = self.filename
66
- data.delete(:vars) unless self.vars && !self.vars.empty?
67
- data.delete(:pre_context) unless self.pre_context && !self.pre_context.empty?
68
- data.delete(:post_context) unless self.post_context && !self.post_context.empty?
69
- data.delete(:context_line) unless self.context_line && !self.context_line.empty?
65
+ data[:filename] = filename
66
+ data.delete(:vars) unless vars && !vars.empty?
67
+ data.delete(:pre_context) unless pre_context && !pre_context.empty?
68
+ data.delete(:post_context) unless post_context && !post_context.empty?
69
+ data.delete(:context_line) unless context_line && !context_line.empty?
70
70
  data
71
71
  end
72
72
  end
@@ -1,14 +1,9 @@
1
- # A much simpler source line cacher because linecache sucks at platform compat
2
-
3
1
  module Raven
4
2
  class LineCache
5
3
  class << self
6
- # TODO: a constant isn't appropriate here, refactor
7
- # also would there be threading bugs essentially using this as a class
8
- # variable?
9
4
  CACHE = {} # rubocop:disable Style/MutableConstant
10
5
 
11
- def is_valid_file(path)
6
+ def valid_file?(path)
12
7
  lines = getlines(path)
13
8
  !lines.nil?
14
9
  end
@@ -10,7 +10,7 @@ module Raven
10
10
  :error,
11
11
  :warn,
12
12
  :info,
13
- :debug,
13
+ :debug
14
14
  ].each do |level|
15
15
  define_method level do |*args, &block|
16
16
  logger = Raven.configuration[:logger]
@@ -1,5 +1,9 @@
1
1
  module Raven
2
2
  class Processor
3
+ STRING_MASK = '********'.freeze
4
+ INT_MASK = 0
5
+ REGEX_SPECIAL_CHARACTERS = %w(. $ ^ { [ ( | ) * + ?).freeze
6
+
3
7
  def initialize(client)
4
8
  @client = client
5
9
  end
@@ -3,10 +3,10 @@ module Raven
3
3
  def process(data)
4
4
  if data[:request]
5
5
  # Remove possibly sensitive cookies
6
- data[:request][:cookies] = nil if data[:request][:cookies]
6
+ data[:request][:cookies] = STRING_MASK if data[:request][:cookies]
7
7
 
8
8
  if data[:request][:headers] && data[:request][:headers]["Cookie"]
9
- data[:request][:headers]["Cookie"] = nil
9
+ data[:request][:headers]["Cookie"] = STRING_MASK
10
10
  end
11
11
  end
12
12
 
@@ -0,0 +1,42 @@
1
+ module Raven
2
+ class Processor::HTTPHeaders < Processor
3
+ DEFAULT_FIELDS = ["Authorization"].freeze
4
+
5
+ attr_accessor :sanitize_http_headers
6
+
7
+ def initialize(client)
8
+ super
9
+ self.sanitize_http_headers = client.configuration.sanitize_http_headers
10
+ end
11
+
12
+ def process(data)
13
+ if data[:request] && data[:request][:headers]
14
+ data[:request][:headers].keys.select { |k| fields_re.match(k.to_s) }.each do |k|
15
+ data[:request][:headers][k] = STRING_MASK
16
+ end
17
+ end
18
+
19
+ data
20
+ end
21
+
22
+ private
23
+
24
+ def matches_regexes?(k)
25
+ fields_re.match(k.to_s)
26
+ end
27
+
28
+ def fields_re
29
+ @fields_re ||= /#{(DEFAULT_FIELDS | sanitize_http_headers).map do |f|
30
+ use_boundary?(f) ? "\\b#{f}\\b" : f
31
+ end.join("|")}/i
32
+ end
33
+
34
+ def use_boundary?(string)
35
+ !DEFAULT_FIELDS.include?(string) && !special_characters?(string)
36
+ end
37
+
38
+ def special_characters?(string)
39
+ REGEX_SPECIAL_CHARACTERS.select { |r| string.include?(r) }.any?
40
+ end
41
+ end
42
+ end
@@ -2,7 +2,7 @@ module Raven
2
2
  class Processor::PostData < Processor
3
3
  def process(data)
4
4
  if data[:request] && data[:request][:method] == "POST"
5
- data[:request][:data] = nil # Remove possibly sensitive POST data
5
+ data[:request][:data] = STRING_MASK # Remove possibly sensitive POST data
6
6
  end
7
7
 
8
8
  data
@@ -3,11 +3,8 @@ require 'json'
3
3
 
4
4
  module Raven
5
5
  class Processor::SanitizeData < Processor
6
- STRING_MASK = '********'.freeze
7
- INT_MASK = 0
8
6
  DEFAULT_FIELDS = %w(authorization password passwd secret ssn social(.*)?sec).freeze
9
7
  CREDIT_CARD_RE = /^(?:\d[ -]*?){13,16}$/
10
- REGEX_SPECIAL_CHARACTERS = %w(. $ ^ { [ ( | ) * + ?).freeze
11
8
 
12
9
  attr_accessor :sanitize_fields, :sanitize_credit_cards
13
10
 
@@ -18,23 +15,23 @@ module Raven
18
15
  end
19
16
 
20
17
  def process(value)
21
- value.each_with_object(value) { |(k,v), memo| memo[k] = sanitize(k,v) }
18
+ value.each_with_object(value) { |(k, v), memo| memo[k] = sanitize(k, v) }
22
19
  end
23
20
 
24
- def sanitize(k,v)
21
+ def sanitize(k, v)
25
22
  if v.is_a?(Hash)
26
23
  process(v)
27
24
  elsif v.is_a?(Array)
28
- v.map{|a| sanitize(k, a)}
25
+ v.map { |a| sanitize(k, a) }
29
26
  elsif k.to_s == 'query_string'
30
27
  sanitize_query_string(v)
31
- elsif v.is_a?(Integer) && matches_regexes?(k,v)
28
+ elsif v.is_a?(Integer) && matches_regexes?(k, v)
32
29
  INT_MASK
33
30
  elsif v.is_a?(String)
34
31
  if fields_re.match(v.to_s) && (json = parse_json_or_nil(v))
35
- #if this string is actually a json obj, convert and sanitize
32
+ # if this string is actually a json obj, convert and sanitize
36
33
  json.is_a?(Hash) ? process(json).to_json : v
37
- elsif matches_regexes?(k,v)
34
+ elsif matches_regexes?(k, v)
38
35
  STRING_MASK
39
36
  else
40
37
  v
@@ -72,11 +69,9 @@ module Raven
72
69
  end
73
70
 
74
71
  def parse_json_or_nil(string)
75
- begin
76
- JSON.parse(string)
77
- rescue JSON::ParserError, NoMethodError
78
- nil
79
- end
72
+ JSON.parse(string)
73
+ rescue JSON::ParserError, NoMethodError
74
+ nil
80
75
  end
81
76
  end
82
77
  end
@@ -9,8 +9,8 @@ module Raven
9
9
  @configuration = configuration
10
10
  end
11
11
 
12
- def send_event #(auth_header, data, options = {})
13
- raise NotImplementedError.new('Abstract method not implemented')
12
+ def send_event # (auth_header, data, options = {})
13
+ raise NotImplementedError, 'Abstract method not implemented'
14
14
  end
15
15
 
16
16
  protected
@@ -0,0 +1,62 @@
1
+ require 'ipaddr'
2
+
3
+ # Based on ActionDispatch::RemoteIp. All security-related precautions from that
4
+ # middleware have been removed, because the Event IP just needs to be accurate,
5
+ # and spoofing an IP here only makes data inaccurate, not insecure. Don't re-use
6
+ # this module if you have to *trust* the IP address.
7
+ module Raven
8
+ module Utils
9
+ class RealIp
10
+ LOCAL_ADDRESSES = [
11
+ "127.0.0.1", # localhost IPv4
12
+ "::1", # localhost IPv6
13
+ "fc00::/7", # private IPv6 range fc00::/7
14
+ "10.0.0.0/8", # private IPv4 range 10.x.x.x
15
+ "172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255
16
+ "192.168.0.0/16", # private IPv4 range 192.168.x.x
17
+ ].map { |proxy| IPAddr.new(proxy) }
18
+
19
+ attr_accessor :ip, :ip_addresses
20
+
21
+ def initialize(ip_addresses)
22
+ self.ip_addresses = ip_addresses
23
+ end
24
+
25
+ def calculate_ip
26
+ # CGI environment variable set by Rack
27
+ remote_addr = ips_from(ip_addresses[:remote_addr]).last
28
+
29
+ # Could be a CSV list and/or repeated headers that were concatenated.
30
+ client_ips = ips_from(ip_addresses[:client_ip])
31
+ real_ips = ips_from(ip_addresses[:real_ip])
32
+ forwarded_ips = ips_from(ip_addresses[:forwarded_for])
33
+
34
+ ips = [client_ips, real_ips, forwarded_ips, remote_addr].flatten.compact
35
+
36
+ # If every single IP option is in the trusted list, just return REMOTE_ADDR
37
+ self.ip = filter_local_addresses(ips).first || remote_addr
38
+ end
39
+
40
+ protected
41
+
42
+ def ips_from(header)
43
+ # Split the comma-separated list into an array of strings
44
+ ips = header ? header.strip.split(/[,\s]+/) : []
45
+ ips.select do |ip|
46
+ begin
47
+ # Only return IPs that are valid according to the IPAddr#new method
48
+ range = IPAddr.new(ip).to_range
49
+ # we want to make sure nobody is sneaking a netmask in
50
+ range.begin == range.end
51
+ rescue ArgumentError
52
+ nil
53
+ end
54
+ end
55
+ end
56
+
57
+ def filter_local_addresses(ips)
58
+ ips.reject { |ip| LOCAL_ADDRESSES.any? { |proxy| proxy === ip } }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Raven
3
3
  # Freezing this constant breaks in 1.9.x
4
- VERSION = "1.2.3" # rubocop:disable Style/MutableConstant
4
+ VERSION = "2.0.0" # rubocop:disable Style/MutableConstant
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-raven
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-31 00:00:00.000000000 Z
11
+ date: 2016-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -138,6 +138,7 @@ files:
138
138
  - lib/raven/event.rb
139
139
  - lib/raven/instance.rb
140
140
  - lib/raven/integrations/delayed_job.rb
141
+ - lib/raven/integrations/rack-timeout.rb
141
142
  - lib/raven/integrations/rack.rb
142
143
  - lib/raven/integrations/rails.rb
143
144
  - lib/raven/integrations/rails/active_job.rb
@@ -158,16 +159,17 @@ files:
158
159
  - lib/raven/logger.rb
159
160
  - lib/raven/processor.rb
160
161
  - lib/raven/processor/cookies.rb
162
+ - lib/raven/processor/http_headers.rb
161
163
  - lib/raven/processor/post_data.rb
162
164
  - lib/raven/processor/removecircularreferences.rb
163
165
  - lib/raven/processor/removestacktrace.rb
164
166
  - lib/raven/processor/sanitizedata.rb
165
- - lib/raven/processor/truncator.rb
166
167
  - lib/raven/processor/utf8conversion.rb
167
168
  - lib/raven/transports.rb
168
169
  - lib/raven/transports/dummy.rb
169
170
  - lib/raven/transports/http.rb
170
171
  - lib/raven/utils/deep_merge.rb
172
+ - lib/raven/utils/real_ip.rb
171
173
  - lib/raven/version.rb
172
174
  - lib/sentry-raven-without-integrations.rb
173
175
  - lib/sentry-raven.rb
@@ -1,22 +0,0 @@
1
- module Raven
2
- class Processor::Truncator < Processor
3
- attr_accessor :event_bytesize_limit
4
-
5
- def initialize(client)
6
- super
7
- self.event_bytesize_limit = client.configuration.event_bytesize_limit
8
- end
9
-
10
- def process(value)
11
- value.each_with_object(value) { |(k, v), memo| memo[k] = truncate(v) }
12
- end
13
-
14
- def truncate(v)
15
- if v.respond_to?(:bytesize) && v.bytesize >= event_bytesize_limit
16
- v.byteslice(0...event_bytesize_limit)
17
- else
18
- v
19
- end
20
- end
21
- end
22
- end