sentry-raven 1.2.3 → 2.0.0

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