rollbar 2.18.2 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/.travis.yml +155 -93
  4. data/Gemfile +19 -13
  5. data/README.md +12 -0
  6. data/gemfiles/rails30.gemfile +17 -10
  7. data/gemfiles/rails31.gemfile +20 -12
  8. data/gemfiles/rails32.gemfile +16 -7
  9. data/gemfiles/rails40.gemfile +16 -5
  10. data/gemfiles/rails41.gemfile +15 -5
  11. data/gemfiles/rails42.gemfile +25 -14
  12. data/gemfiles/rails50.gemfile +15 -8
  13. data/gemfiles/rails51.gemfile +15 -8
  14. data/gemfiles/rails52.gemfile +62 -0
  15. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +2 -2
  16. data/lib/rails/rollbar_runner.rb +16 -1
  17. data/lib/rollbar/capistrano.rb +71 -39
  18. data/lib/rollbar/capistrano3.rb +53 -1
  19. data/lib/rollbar/capistrano_tasks.rb +131 -0
  20. data/lib/rollbar/configuration.rb +13 -4
  21. data/lib/rollbar/delay/active_job.rb +17 -0
  22. data/lib/rollbar/delay/sidekiq.rb +3 -1
  23. data/lib/rollbar/delay/thread.rb +1 -1
  24. data/lib/rollbar/deploy.rb +69 -0
  25. data/lib/rollbar/item.rb +17 -6
  26. data/lib/rollbar/middleware/js.rb +25 -3
  27. data/lib/rollbar/middleware/js/json_value.rb +26 -0
  28. data/lib/rollbar/notifier.rb +32 -13
  29. data/lib/rollbar/plugins/active_job.rb +3 -0
  30. data/lib/rollbar/plugins/rails/controller_methods.rb +2 -1
  31. data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -1
  32. data/lib/rollbar/rake_tasks.rb +126 -67
  33. data/lib/rollbar/scrubbers/params.rb +6 -0
  34. data/lib/rollbar/util.rb +75 -45
  35. data/lib/rollbar/util/hash.rb +15 -6
  36. data/lib/rollbar/version.rb +1 -1
  37. data/rollbar.gemspec +2 -3
  38. metadata +9 -261
  39. data/lib/rollbar/tasks/rollbar.cap +0 -47
  40. data/spec/cacert.pem +0 -3988
  41. data/spec/controllers/home_controller_spec.rb +0 -480
  42. data/spec/delay/sidekiq_spec.rb +0 -61
  43. data/spec/delay/sucker_punch_spec.rb +0 -25
  44. data/spec/delayed/backend/test.rb +0 -140
  45. data/spec/delayed/serialization/test.rb +0 -0
  46. data/spec/dummyapp/.gitignore +0 -73
  47. data/spec/dummyapp/Rakefile +0 -7
  48. data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
  49. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
  50. data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
  51. data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
  52. data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
  53. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  54. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  55. data/spec/dummyapp/app/models/.gitkeep +0 -0
  56. data/spec/dummyapp/app/models/book.rb +0 -5
  57. data/spec/dummyapp/app/models/post.rb +0 -9
  58. data/spec/dummyapp/app/models/user.rb +0 -9
  59. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
  60. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
  61. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
  62. data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
  63. data/spec/dummyapp/app/views/home/index.html.erb +0 -4
  64. data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
  65. data/spec/dummyapp/app/views/js/test.html.erb +0 -1
  66. data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
  67. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
  68. data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
  69. data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
  70. data/spec/dummyapp/app/views/users/index.html.erb +0 -8
  71. data/spec/dummyapp/app/views/users/show.html.erb +0 -3
  72. data/spec/dummyapp/config.ru +0 -4
  73. data/spec/dummyapp/config/application.rb +0 -59
  74. data/spec/dummyapp/config/boot.rb +0 -10
  75. data/spec/dummyapp/config/database.yml +0 -25
  76. data/spec/dummyapp/config/environment.rb +0 -5
  77. data/spec/dummyapp/config/environments/development.rb +0 -37
  78. data/spec/dummyapp/config/environments/production.rb +0 -67
  79. data/spec/dummyapp/config/environments/test.rb +0 -37
  80. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
  81. data/spec/dummyapp/config/initializers/inflections.rb +0 -15
  82. data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
  83. data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
  84. data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
  85. data/spec/dummyapp/config/initializers/session_store.rb +0 -8
  86. data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
  87. data/spec/dummyapp/config/locales/devise.en.yml +0 -58
  88. data/spec/dummyapp/config/locales/en.yml +0 -5
  89. data/spec/dummyapp/config/routes.rb +0 -17
  90. data/spec/dummyapp/config/secrets.yml +0 -2
  91. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
  92. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
  93. data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
  94. data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
  95. data/spec/dummyapp/db/schema.rb +0 -41
  96. data/spec/dummyapp/db/seeds.rb +0 -12
  97. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  98. data/spec/dummyapp/public/404.html +0 -26
  99. data/spec/dummyapp/public/422.html +0 -26
  100. data/spec/dummyapp/public/500.html +0 -25
  101. data/spec/dummyapp/public/favicon.ico +0 -0
  102. data/spec/dummyapp/script/rails +0 -6
  103. data/spec/fixtures/file1 +0 -1
  104. data/spec/fixtures/file2 +0 -1
  105. data/spec/fixtures/payloads/message.json +0 -25
  106. data/spec/fixtures/payloads/sample.trace.json +0 -275
  107. data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
  108. data/spec/fixtures/plugins/dummy1.rb +0 -5
  109. data/spec/fixtures/plugins/dummy2.rb +0 -5
  110. data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
  111. data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
  112. data/spec/requests/home_spec.rb +0 -49
  113. data/spec/rollbar/configuration_spec.rb +0 -74
  114. data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
  115. data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
  116. data/spec/rollbar/delay/resque_spec.rb +0 -37
  117. data/spec/rollbar/delay/shoryuken_spec.rb +0 -44
  118. data/spec/rollbar/delay/thread_spec.rb +0 -27
  119. data/spec/rollbar/encoding/encoder_spec.rb +0 -63
  120. data/spec/rollbar/item/backtrace_spec.rb +0 -26
  121. data/spec/rollbar/item/frame_spec.rb +0 -267
  122. data/spec/rollbar/item_spec.rb +0 -736
  123. data/spec/rollbar/json/oj_spec.rb +0 -18
  124. data/spec/rollbar/json_spec.rb +0 -110
  125. data/spec/rollbar/lazy_store_spec.rb +0 -99
  126. data/spec/rollbar/logger_proxy_spec.rb +0 -69
  127. data/spec/rollbar/logger_spec.rb +0 -124
  128. data/spec/rollbar/middleware/js_spec.rb +0 -428
  129. data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
  130. data/spec/rollbar/notifier_spec.rb +0 -67
  131. data/spec/rollbar/plugin_spec.rb +0 -209
  132. data/spec/rollbar/plugins/active_job_spec.rb +0 -45
  133. data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
  134. data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
  135. data/spec/rollbar/plugins/rack_spec.rb +0 -152
  136. data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
  137. data/spec/rollbar/plugins/rake_spec.rb +0 -34
  138. data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
  139. data/spec/rollbar/plugins/sidekiq_spec.rb +0 -169
  140. data/spec/rollbar/plugins/validations_spec.rb +0 -56
  141. data/spec/rollbar/plugins_spec.rb +0 -68
  142. data/spec/rollbar/request_data_extractor_spec.rb +0 -321
  143. data/spec/rollbar/scrubbers/params_spec.rb +0 -598
  144. data/spec/rollbar/scrubbers/url_spec.rb +0 -240
  145. data/spec/rollbar/scrubbers_spec.rb +0 -31
  146. data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
  147. data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
  148. data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
  149. data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
  150. data/spec/rollbar/truncation_spec.rb +0 -27
  151. data/spec/rollbar/util/hash_spec.rb +0 -22
  152. data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
  153. data/spec/rollbar/util_spec.rb +0 -80
  154. data/spec/rollbar_bc_spec.rb +0 -380
  155. data/spec/rollbar_spec.rb +0 -1737
  156. data/spec/spec_helper.rb +0 -84
  157. data/spec/support/cause_exception.rb +0 -1
  158. data/spec/support/encoding_helpers.rb +0 -8
  159. data/spec/support/encodings/iso_8859_9 +0 -1
  160. data/spec/support/fixture_helpers.rb +0 -10
  161. data/spec/support/get_ip_raising.rb +0 -7
  162. data/spec/support/helpers.rb +0 -5
  163. data/spec/support/matchers.rb +0 -23
  164. data/spec/support/notifier_helpers.rb +0 -57
  165. data/spec/support/rollbar_api.rb +0 -57
  166. data/spec/support/secure_headers_mocks.rb +0 -83
  167. data/spec/support/shared_contexts.rb +0 -12
@@ -0,0 +1,17 @@
1
+ module Rollbar
2
+ module Delay
3
+ # This class provides the ActiveJob async handler. Users can
4
+ # use ActiveJob in order to send the reports to the Rollbar API
5
+ class ActiveJob < ::ActiveJob::Base
6
+ queue_as :default
7
+
8
+ def perform(payload)
9
+ Rollbar.process_from_async_handler(payload)
10
+ end
11
+
12
+ def self.call(payload)
13
+ perform_later payload
14
+ end
15
+ end
16
+ end
17
+ end
@@ -10,7 +10,9 @@ module Rollbar
10
10
  end
11
11
 
12
12
  def call(payload)
13
- ::Sidekiq::Client.push @options.merge('args' => [payload])
13
+ if ::Sidekiq::Client.push(@options.merge('args' => [payload])) == nil
14
+ raise StandardError.new "Unable to push the job to Sidekiq"
15
+ end
14
16
  end
15
17
 
16
18
  include ::Sidekiq::Worker
@@ -5,7 +5,7 @@ module Rollbar
5
5
  module Delay
6
6
  class Thread
7
7
  EXIT_SIGNAL = :exit
8
- EXIT_TIMEOUT = 3
8
+ EXIT_TIMEOUT = 6
9
9
 
10
10
  Error = Class.new(StandardError)
11
11
  TimeoutError = Class.new(Error)
@@ -0,0 +1,69 @@
1
+ require 'capistrano'
2
+
3
+ module Rollbar
4
+ # Deploy Tracking API wrapper module
5
+ module Deploy
6
+ ENDPOINT = 'https://api.rollbar.com/api/1/deploy/'.freeze
7
+
8
+ def self.report(opts = {}, access_token:, environment:, revision:)
9
+ opts[:status] ||= :started
10
+
11
+ uri = URI.parse(::Rollbar::Deploy::ENDPOINT)
12
+
13
+ request = Net::HTTP::Post.new(uri.request_uri)
14
+ request.body = ::JSON.dump({
15
+ :access_token => access_token,
16
+ :environment => environment,
17
+ :revision => revision
18
+ }.merge(opts))
19
+
20
+ send_request(opts, :uri => uri, :request => request)
21
+ end
22
+
23
+ def self.update(opts = {}, deploy_id:, access_token:, status:)
24
+ uri = URI.parse(
25
+ ::Rollbar::Deploy::ENDPOINT +
26
+ deploy_id.to_s +
27
+ '?access_token=' + access_token
28
+ )
29
+
30
+ request = Net::HTTP::Patch.new(uri.request_uri)
31
+ request.body = ::JSON.dump(:status => status.to_s, :comment => opts[:comment])
32
+
33
+ send_request(opts, :uri => uri, :request => request)
34
+ end
35
+
36
+ class << self
37
+ private
38
+
39
+ def send_request(opts = {}, uri:, request:)
40
+ Net::HTTP.start(uri.host, uri.port, opts[:proxy], :use_ssl => true) do |http|
41
+ build_result(
42
+ :uri => uri,
43
+ :request => request,
44
+ :response => opts[:dry_run] ? nil : http.request(request)
45
+ )
46
+ end
47
+ end
48
+
49
+ def build_result(uri:, request:, response: nil)
50
+ result = {
51
+ :request_info => uri.inspect + ': ' + request.body,
52
+ :request => request,
53
+ :response => response
54
+ }
55
+
56
+ unless result[:response].nil?
57
+ result.merge!(JSON.parse(result[:response].body, :symbolize_names => true))
58
+ result[:response_info] = build_response_info(result[:response])
59
+ end
60
+
61
+ result
62
+ end
63
+
64
+ def build_response_info(response)
65
+ response.code + '; ' + response.message + '; ' + response.body.delete!("\n")
66
+ end
67
+ end
68
+ end
69
+ end
@@ -26,12 +26,12 @@ module Rollbar
26
26
  attr_reader :message
27
27
  attr_reader :exception
28
28
  attr_reader :extra
29
-
29
+
30
30
  attr_reader :configuration
31
31
  attr_reader :scope
32
32
  attr_reader :logger
33
33
  attr_reader :notifier
34
-
34
+
35
35
  attr_reader :context
36
36
 
37
37
  def_delegators :payload, :[]
@@ -156,13 +156,24 @@ module Rollbar
156
156
  end
157
157
 
158
158
  def build_extra
159
- if custom_data_method?
160
- Util.deep_merge(custom_data, extra || {})
159
+ if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
160
+ Util.deep_merge(scrub(custom_data), scrub(extra) || {})
161
161
  else
162
- extra
162
+ scrub(extra)
163
163
  end
164
164
  end
165
165
 
166
+ def scrub(data)
167
+ return data unless data.is_a? Hash
168
+
169
+ options = {
170
+ :params => data,
171
+ :config => Rollbar.configuration.scrub_fields,
172
+ :whitelist => Rollbar.configuration.scrub_whitelist
173
+ }
174
+ Rollbar::Scrubbers::Params.call(options)
175
+ end
176
+
166
177
  def custom_data_method?
167
178
  !!configuration.custom_data_method
168
179
  end
@@ -173,7 +184,7 @@ module Rollbar
173
184
  else
174
185
  data = configuration.custom_data_method.call
175
186
  end
176
-
187
+
177
188
  Rollbar::Util.deep_copy(data)
178
189
  rescue => e
179
190
  return {} if configuration.safely?
@@ -120,7 +120,11 @@ module Rollbar
120
120
 
121
121
  add_person_data(js_config, env)
122
122
 
123
- script_tag("var _rollbarConfig = #{js_config.to_json};", env)
123
+ # MUST use the Ruby JSON encoder (JSON#generate).
124
+ # See lib/rollbar/middleware/js/json_value
125
+ json = ::JSON.generate(js_config)
126
+
127
+ script_tag("var _rollbarConfig = #{json};", env)
124
128
  end
125
129
 
126
130
  def add_person_data(js_config, env)
@@ -141,7 +145,9 @@ module Rollbar
141
145
  end
142
146
 
143
147
  def script_tag(content, env)
144
- if append_nonce?
148
+ if (nonce = rails5_nonce(env))
149
+ script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
150
+ elsif secure_headers_nonce?
145
151
  nonce = ::SecureHeaders.content_security_policy_script_nonce(::Rack::Request.new(env))
146
152
  script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
147
153
  else
@@ -156,7 +162,23 @@ module Rollbar
156
162
  string
157
163
  end
158
164
 
159
- def append_nonce?
165
+ # Rails 5.2 Secure Content Policy
166
+ def rails5_nonce(env)
167
+ # The nonce is the preferred method, however 'unsafe-inline' is also possible.
168
+ # The app gets to decide, so we handle both. If the script_src key is missing,
169
+ # Rails will not add the nonce to the headers, so we should not add it either.
170
+ # If the 'unsafe-inline' value is present, the app should not add a nonce and
171
+ # we should ignore it if they do.
172
+ req = ::ActionDispatch::Request.new env
173
+ req.respond_to?(:content_security_policy) &&
174
+ req.content_security_policy &&
175
+ req.content_security_policy.directives['script-src'] &&
176
+ !req.content_security_policy.directives['script-src'].include?("'unsafe-inline'") &&
177
+ req.content_security_policy_nonce
178
+ end
179
+
180
+ # Secure Headers gem
181
+ def secure_headers_nonce?
160
182
  secure_headers.append_nonce?
161
183
  end
162
184
 
@@ -0,0 +1,26 @@
1
+ # Allows a Ruby String to be used to create native Javascript objects
2
+ # when calling JSON#generate.
3
+ #
4
+ # Example:
5
+ # JSON.generate({ foo: Rollbar::JSON::Value.new('function(){ alert("bar") }') })
6
+ # => '{"foo":function(){ alert(\"bar\") }}'
7
+ #
8
+ # MUST use the Ruby JSON encoder, as in the example. The ActiveSupport encoder,
9
+ # which is installed with Rails, is invoked when calling Hash#to_json and #as_json,
10
+ # and will not work.
11
+ #
12
+ module Rollbar
13
+ module JSON
14
+ class Value # :nodoc:
15
+ attr_accessor :value
16
+
17
+ def initialize(value)
18
+ @value = value
19
+ end
20
+
21
+ def to_json(*_args)
22
+ value
23
+ end
24
+ end
25
+ end
26
+ end
@@ -134,10 +134,11 @@ module Rollbar
134
134
  return 'ignored' if ignored?(exception, use_exception_level_filters)
135
135
 
136
136
  begin
137
- call_before_process(:level => level,
138
- :exception => exception,
139
- :message => message,
140
- :extra => extra)
137
+ status = call_before_process(:level => level,
138
+ :exception => exception,
139
+ :message => message,
140
+ :extra => extra)
141
+ return 'ignored' if status == 'ignored'
141
142
  rescue Rollbar::Ignore
142
143
  return 'ignored'
143
144
  end
@@ -295,6 +296,10 @@ module Rollbar
295
296
  end
296
297
  end
297
298
 
299
+ def logger
300
+ @logger ||= LoggerProxy.new(configuration.logger)
301
+ end
302
+
298
303
  private
299
304
 
300
305
  def use_exception_level_filters?(options)
@@ -317,7 +322,8 @@ module Rollbar
317
322
 
318
323
  handlers.each do |handler|
319
324
  begin
320
- handler.call(options)
325
+ status = handler.call(options)
326
+ return 'ignored' if status == 'ignored'
321
327
  rescue Rollbar::Ignore
322
328
  raise
323
329
  rescue => e
@@ -343,10 +349,10 @@ module Rollbar
343
349
  exception = arg
344
350
  elsif arg.is_a?(Hash)
345
351
  extra = arg
346
-
352
+
347
353
  context = extra[:custom_data_method_context]
348
354
  extra.delete :custom_data_method_context
349
-
355
+
350
356
  extra = nil if extra.empty?
351
357
  end
352
358
  end
@@ -407,7 +413,7 @@ module Rollbar
407
413
  # If that fails, we'll fall back to a more static failsafe response.
408
414
  def report_internal_error(exception)
409
415
  log_error '[Rollbar] Reporting internal error encountered while sending data to Rollbar.'
410
-
416
+
411
417
  configuration.execute_hook(:on_report_internal_error, exception)
412
418
 
413
419
  begin
@@ -513,12 +519,29 @@ module Rollbar
513
519
 
514
520
  request = Net::HTTP::Post.new(uri.request_uri)
515
521
 
516
- request.body = body
522
+ request.body = pack_ruby260_bytes(body)
517
523
  request.add_field('X-Rollbar-Access-Token', access_token)
518
524
 
519
525
  handle_net_retries { http.request(request) }
520
526
  end
521
527
 
528
+ def pack_ruby260_bytes(body)
529
+ # Ruby 2.6.0 shipped with a bug affecting multi-byte body for Net::HTTP.
530
+ # Fix (committed one day after 2.6.0p0 shipped) is here:
531
+ # https://github.com/ruby/ruby/commit/1680a13a926b17661329beec1ded6b32aad16c1b#diff-00a99d8c71daaf5fc60a050da41f7261
532
+ #
533
+ # We work around this by repacking the body as single byte chars if needed.
534
+ if RUBY_VERSION == '2.6.0' && multibyte?(body)
535
+ body.unpack('C*').pack('C*')
536
+ else
537
+ body
538
+ end
539
+ end
540
+
541
+ def multibyte?(str)
542
+ str.chars.length != str.bytes.length
543
+ end
544
+
522
545
  def http_proxy_for_em(uri)
523
546
  proxy = http_proxy(uri)
524
547
  {
@@ -706,9 +729,5 @@ module Rollbar
706
729
  uuid_url = Util.uuid_rollbar_url(data, configuration)
707
730
  log_info "[Rollbar] Details: #{uuid_url} (only available if report was successful)"
708
731
  end
709
-
710
- def logger
711
- @logger ||= LoggerProxy.new(configuration.logger)
712
- end
713
732
  end
714
733
  end
@@ -13,3 +13,6 @@ module Rollbar
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ # Automatically add to ActionMailer::DeliveryJob
18
+ ActionMailer::DeliveryJob.send(:include, Rollbar::ActiveJob) if defined?(ActionMailer::DeliveryJob)
@@ -1,4 +1,5 @@
1
1
  require 'rollbar/request_data_extractor'
2
+ require 'rollbar/util'
2
3
 
3
4
  module Rollbar
4
5
  module Rails
@@ -6,7 +7,7 @@ module Rollbar
6
7
  include RequestDataExtractor
7
8
 
8
9
  def rollbar_person_data
9
- user = send(Rollbar.configuration.person_method)
10
+ (user = send(Rollbar.configuration.person_method)) unless Rollbar::Util.method_in_stack_twice(:rollbar_person_data, __FILE__)
10
11
  # include id, username, email if non-empty
11
12
  if user
12
13
  {
@@ -14,7 +14,13 @@ module Rollbar
14
14
  config.environment ||= ::Rails.env
15
15
  config.root ||= ::Rails.root
16
16
  config.framework = "Rails: #{::Rails::VERSION::STRING}"
17
- config.filepath ||= ::Rails.application.class.parent_name + '.rollbar'
17
+ config.filepath ||= begin
18
+ if ::Rails.application.class.respond_to?(:module_parent_name)
19
+ ::Rails.application.class.module_parent_name + '.rollbar'
20
+ else
21
+ ::Rails.application.class.parent_name + '.rollbar'
22
+ end
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -2,92 +2,151 @@ require 'rollbar'
2
2
  begin
3
3
  require 'rack/mock'
4
4
  rescue LoadError
5
+ puts 'Cannot load rack/mock'
5
6
  end
6
7
  require 'logger'
7
8
 
8
9
  namespace :rollbar do
9
10
  desc 'Verify your gem installation by sending a test exception to Rollbar'
10
11
  task :test => [:environment] do
11
- if defined?(Rails)
12
- Rails.logger = if defined?(ActiveSupport::TaggedLogging)
13
- ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
14
- else
15
- Logger.new(STDOUT)
16
- end
17
-
18
- Rails.logger.level = Logger::DEBUG
19
- Rollbar.preconfigure do |config|
20
- config.logger = Rails.logger
21
- end
22
- end
12
+ RollbarTest.run
13
+ end
14
+ end
23
15
 
24
- class RollbarTestingException < RuntimeError; end
16
+ # Module to inject into the Rails controllers or rack apps
17
+ module RollbarTest # :nodoc:
18
+ def test_rollbar
19
+ puts 'Raising RollbarTestingException to simulate app failure.'
25
20
 
26
- unless Rollbar.configuration.access_token
27
- puts 'Rollbar needs an access token configured. Check the README for instructions.'
21
+ raise RollbarTestingException.new, ::RollbarTest.success_message
22
+ end
28
23
 
29
- exit
30
- end
24
+ def self.run
25
+ return unless confirmed_token?
26
+
27
+ configure_rails if defined?(Rails)
31
28
 
32
29
  puts 'Testing manual report...'
33
30
  Rollbar.error('Test error from rollbar:test')
34
31
 
35
- # Module to inject into the Rails controllers or
36
- # rack apps
37
- module RollbarTest
38
- def test_rollbar
39
- puts 'Raising RollbarTestingException to simulate app failure.'
32
+ return unless defined?(Rack::MockRequest)
40
33
 
41
- raise RollbarTestingException.new, 'Testing rollbar with "rake rollbar:test". If you can see this, it works.'
42
- end
34
+ protocol, app = setup_app
35
+
36
+ puts 'Processing...'
37
+ env = Rack::MockRequest.env_for("#{protocol}://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
38
+ status, = app.call(env)
39
+
40
+ puts error_message unless status.to_i == 500
41
+ end
42
+
43
+ def self.configure_rails
44
+ Rails.logger = if defined?(ActiveSupport::TaggedLogging)
45
+ ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
46
+ else
47
+ Logger.new(STDOUT)
48
+ end
49
+
50
+ Rails.logger.level = Logger::DEBUG
51
+ Rollbar.preconfigure do |config|
52
+ config.logger = Rails.logger
43
53
  end
54
+ end
44
55
 
45
- if defined?(Rack::MockRequest)
46
- if defined?(Rails)
47
- puts 'Setting up the controller.'
48
-
49
- class RollbarTestController < ActionController::Base
50
- include RollbarTest
51
-
52
- def verify
53
- test_rollbar
54
- end
55
-
56
- def logger
57
- nil
58
- end
59
- end
60
-
61
- Rails.application.routes_reloader.execute_if_updated
62
- Rails.application.routes.draw do
63
- get 'verify' => 'rollbar_test#verify', :as => 'verify'
64
- end
65
-
66
- # from http://stackoverflow.com/questions/5270835/authlogic-activation-problems
67
- if defined? Authlogic
68
- Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)
69
- end
70
-
71
- protocol = (defined? Rails.application.config.force_ssl && Rails.application.config.force_ssl) ? 'https' : 'http'
72
- app = Rails.application
73
- else
74
- protocol = 'http'
75
- app = Class.new do
76
- include RollbarTest
77
-
78
- def self.call(_env)
79
- new.test_rollbar
80
- end
81
- end
82
- end
56
+ def self.confirmed_token?
57
+ return true if Rollbar.configuration.access_token
58
+
59
+ puts token_error_message
60
+
61
+ false
62
+ end
63
+
64
+ def self.authlogic_config
65
+ # from http://stackoverflow.com/questions/5270835/authlogic-activation-problems
66
+ return unless defined?(Authlogic)
67
+
68
+ Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)
69
+ end
70
+
71
+ def self.setup_app
72
+ puts 'Setting up the test app.'
73
+
74
+ if defined?(Rails)
75
+ app = rails_app
83
76
 
84
- puts 'Processing...'
85
- env = Rack::MockRequest.env_for("#{protocol}://www.example.com/verify")
86
- status, = app.call(env)
77
+ draw_rails_route(app)
87
78
 
88
- unless status.to_i == 500
89
- puts 'Test failed! You may have a configuration issue, or you could be using a gem that\'s blocking the test. Contact support@rollbar.com if you need help troubleshooting.'
79
+ authlogic_config
80
+
81
+ [rails_protocol(app), app]
82
+ else
83
+ ['http', rack_app]
84
+ end
85
+ end
86
+
87
+ def self.rails_app
88
+ # The setup below is needed for Rails 5.x, but not for Rails 4.x and below.
89
+ # (And fails on Rails 4.x in various ways depending on the exact version.)
90
+ return Rails.application if Rails.version < '5.0.0'
91
+
92
+ # Spring now runs by default in development on all new Rails installs. This causes
93
+ # the new `/verify` route to not get picked up if `config.cache_classes == false`
94
+ # which is also a default in development env.
95
+ #
96
+ # `config.cache_classes` needs to be set, but the only possible time is at app load,
97
+ # so here we clone the default app with an updated config.
98
+ #
99
+ config = Rails.application.config
100
+ config.cache_classes = true
101
+
102
+ # Make a copy of the app, so the config can be updated.
103
+ Rails.application.class.name.constantize.new(:config => config)
104
+ end
105
+
106
+ def self.draw_rails_route(app)
107
+ app.routes_reloader.execute_if_updated
108
+ app.routes.draw do
109
+ get 'verify' => 'rollbar_test#verify', :as => 'verify'
110
+ end
111
+ end
112
+
113
+ def self.rails_protocol(app)
114
+ defined?(app.config.force_ssl && app.config.force_ssl) ? 'https' : 'http'
115
+ end
116
+
117
+ def self.rack_app
118
+ Class.new do
119
+ include RollbarTest
120
+
121
+ def self.call(_env)
122
+ new.test_rollbar
90
123
  end
91
124
  end
92
125
  end
126
+
127
+ def self.token_error_message
128
+ 'Rollbar needs an access token configured. Check the README for instructions.'
129
+ end
130
+
131
+ def self.error_message
132
+ 'Test failed! You may have a configuration issue, or you could be using a gem that\'s blocking the test. Contact support@rollbar.com if you need help troubleshooting.'
133
+ end
134
+
135
+ def self.success_message
136
+ 'Testing rollbar with "rake rollbar:test". If you can see this, it works.'
137
+ end
138
+ end
139
+
140
+ class RollbarTestingException < RuntimeError; end
141
+
142
+ class RollbarTestController < ActionController::Base # :nodoc:
143
+ include RollbarTest
144
+
145
+ def verify
146
+ test_rollbar
147
+ end
148
+
149
+ def logger
150
+ nil
151
+ end
93
152
  end