rollbar 0.8.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.
Files changed (85) hide show
  1. data/.gitignore +20 -0
  2. data/.travis.yml +17 -0
  3. data/CHANGELOG.md +90 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +22 -0
  6. data/README.md +165 -0
  7. data/Rakefile +14 -0
  8. data/THANKS +10 -0
  9. data/lib/generators/rollbar/rollbar_generator.rb +53 -0
  10. data/lib/generators/rollbar/templates/initializer.rb +28 -0
  11. data/lib/rollbar.rb +358 -0
  12. data/lib/rollbar/configuration.rb +64 -0
  13. data/lib/rollbar/delayed_job.rb +25 -0
  14. data/lib/rollbar/exception_reporter.rb +24 -0
  15. data/lib/rollbar/goalie.rb +33 -0
  16. data/lib/rollbar/middleware/rack/builder.rb +21 -0
  17. data/lib/rollbar/middleware/rack/test_session.rb +31 -0
  18. data/lib/rollbar/middleware/rails/show_exceptions.rb +26 -0
  19. data/lib/rollbar/rack.rb +9 -0
  20. data/lib/rollbar/rails.rb +22 -0
  21. data/lib/rollbar/rails/controller_methods.rb +28 -0
  22. data/lib/rollbar/railtie.rb +37 -0
  23. data/lib/rollbar/rake.rb +9 -0
  24. data/lib/rollbar/rake_tasks.rb +60 -0
  25. data/lib/rollbar/request_data_extractor.rb +115 -0
  26. data/lib/rollbar/sidekiq.rb +25 -0
  27. data/lib/rollbar/version.rb +3 -0
  28. data/rollbar.gemspec +24 -0
  29. data/spec/controllers/home_controller_spec.rb +180 -0
  30. data/spec/dummyapp/.gitignore +73 -0
  31. data/spec/dummyapp/Rakefile +7 -0
  32. data/spec/dummyapp/app/assets/javascripts/application.js +3 -0
  33. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +37 -0
  34. data/spec/dummyapp/app/controllers/application_controller.rb +3 -0
  35. data/spec/dummyapp/app/controllers/home_controller.rb +25 -0
  36. data/spec/dummyapp/app/controllers/users_controller.rb +17 -0
  37. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  38. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  39. data/spec/dummyapp/app/models/.gitkeep +0 -0
  40. data/spec/dummyapp/app/models/user.rb +10 -0
  41. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +27 -0
  42. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +20 -0
  43. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +25 -0
  44. data/spec/dummyapp/app/views/home/cause_exception.html.erb +1 -0
  45. data/spec/dummyapp/app/views/home/index.html.erb +4 -0
  46. data/spec/dummyapp/app/views/home/report_exception.html.erb +1 -0
  47. data/spec/dummyapp/app/views/layouts/_messages.html.erb +5 -0
  48. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +21 -0
  49. data/spec/dummyapp/app/views/layouts/application.html.erb +25 -0
  50. data/spec/dummyapp/app/views/users/index.html.erb +8 -0
  51. data/spec/dummyapp/app/views/users/show.html.erb +3 -0
  52. data/spec/dummyapp/config.ru +4 -0
  53. data/spec/dummyapp/config/application.rb +60 -0
  54. data/spec/dummyapp/config/boot.rb +10 -0
  55. data/spec/dummyapp/config/database.yml +25 -0
  56. data/spec/dummyapp/config/environment.rb +5 -0
  57. data/spec/dummyapp/config/environments/development.rb +37 -0
  58. data/spec/dummyapp/config/environments/production.rb +67 -0
  59. data/spec/dummyapp/config/environments/test.rb +37 -0
  60. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +7 -0
  61. data/spec/dummyapp/config/initializers/devise.rb +233 -0
  62. data/spec/dummyapp/config/initializers/inflections.rb +15 -0
  63. data/spec/dummyapp/config/initializers/mime_types.rb +5 -0
  64. data/spec/dummyapp/config/initializers/rollbar.rb +20 -0
  65. data/spec/dummyapp/config/initializers/secret_token.rb +7 -0
  66. data/spec/dummyapp/config/initializers/session_store.rb +8 -0
  67. data/spec/dummyapp/config/initializers/wrap_parameters.rb +14 -0
  68. data/spec/dummyapp/config/locales/devise.en.yml +58 -0
  69. data/spec/dummyapp/config/locales/en.yml +5 -0
  70. data/spec/dummyapp/config/routes.rb +14 -0
  71. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +46 -0
  72. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +5 -0
  73. data/spec/dummyapp/db/schema.rb +35 -0
  74. data/spec/dummyapp/db/seeds.rb +12 -0
  75. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  76. data/spec/dummyapp/public/404.html +26 -0
  77. data/spec/dummyapp/public/422.html +26 -0
  78. data/spec/dummyapp/public/500.html +25 -0
  79. data/spec/dummyapp/public/favicon.ico +0 -0
  80. data/spec/dummyapp/script/rails +6 -0
  81. data/spec/requests/home_spec.rb +48 -0
  82. data/spec/rollbar_spec.rb +426 -0
  83. data/spec/spec_helper.rb +35 -0
  84. data/spec/support/devise.rb +3 -0
  85. metadata +282 -0
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Rollbar
4
+ class Sidekiq
5
+ def call(worker, msg, queue)
6
+ begin
7
+ yield
8
+ rescue => e
9
+ msg.delete('backtrace')
10
+ msg.delete('error_backtrace')
11
+ msg.delete('error_message')
12
+ msg.delete('error_class')
13
+
14
+ Rollbar.report_exception(e, :params => msg)
15
+ raise
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ Sidekiq.configure_server do |config|
22
+ config.server_middleware do |chain|
23
+ chain.add Rollbar::Sidekiq
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Rollbar
2
+ VERSION = "0.8.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rollbar/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Brian Rue"]
6
+ gem.email = ["brian@rollbar.com"]
7
+ gem.description = %q{Rails plugin to catch and send exceptions to Rollbar}
8
+ gem.summary = %q{Reports exceptions to Rollbar}
9
+ gem.homepage = "https://github.com/rollbar/rollbar-gem"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.test_files = gem.files.grep(%r{^(spec)/})
13
+ gem.name = "rollbar"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = Rollbar::VERSION
16
+
17
+ gem.add_runtime_dependency 'multi_json', '~> 1.6.0'
18
+
19
+ gem.add_development_dependency 'rails', '~> 3.2.12'
20
+ gem.add_development_dependency 'devise', '>= 2.1.2'
21
+ gem.add_development_dependency 'rspec-rails', '~> 2.12.0'
22
+ gem.add_development_dependency 'database_cleaner', '>= 0.9.1'
23
+ gem.add_development_dependency 'girl_friday', '>= 0.11.1'
24
+ end
@@ -0,0 +1,180 @@
1
+ require 'spec_helper'
2
+
3
+ describe HomeController do
4
+ let(:logger_mock) { double("Rails.logger").as_null_object }
5
+
6
+ before(:each) do
7
+ reset_configuration
8
+ Rollbar.configure do |config|
9
+ config.access_token = 'aaaabbbbccccddddeeeeffff00001111'
10
+ config.environment = ::Rails.env
11
+ config.root = ::Rails.root
12
+ config.framework = "Rails: #{::Rails::VERSION::STRING}"
13
+ config.logger = logger_mock
14
+ end
15
+ end
16
+
17
+ context "rollbar controller methods" do
18
+ # TODO run these for a a more-real request
19
+ it "should build valid request data" do
20
+ data = @controller.rollbar_request_data
21
+ data.should have_key(:params)
22
+ data.should have_key(:url)
23
+ data.should have_key(:user_ip)
24
+ data.should have_key(:headers)
25
+ data.should have_key(:GET)
26
+ data.should have_key(:session)
27
+ data.should have_key(:method)
28
+ end
29
+
30
+ it "should build empty person data when no one is logged-in" do
31
+ data = @controller.rollbar_person_data
32
+ data.should == {}
33
+ end
34
+
35
+ context "rollbar_filter_params" do
36
+ it "should filter files" do
37
+ name = "John Doe"
38
+ file_hash = {
39
+ :filename => "test.txt",
40
+ :type => "text/plain",
41
+ :head => {},
42
+ :tempfile => "dummy"
43
+ }
44
+ file = ActionDispatch::Http::UploadedFile.new(file_hash)
45
+
46
+ params = {
47
+ :name => name,
48
+ :a_file => file
49
+ }
50
+
51
+ filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
52
+
53
+ filtered[:name].should == name
54
+ filtered[:a_file].should be_a_kind_of(Hash)
55
+ filtered[:a_file][:content_type].should == file_hash[:type]
56
+ filtered[:a_file][:original_filename].should == file_hash[:filename]
57
+ filtered[:a_file][:size].should == file_hash[:tempfile].size
58
+ end
59
+
60
+ it "should filter files in nested params" do
61
+ name = "John Doe"
62
+ file_hash = {
63
+ :filename => "test.txt",
64
+ :type => "text/plain",
65
+ :head => {},
66
+ :tempfile => "dummy"
67
+ }
68
+ file = ActionDispatch::Http::UploadedFile.new(file_hash)
69
+
70
+ params = {
71
+ :name => name,
72
+ :wrapper => {
73
+ :wrapper2 => {
74
+ :a_file => file,
75
+ :foo => "bar"
76
+ }
77
+ }
78
+ }
79
+
80
+ filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
81
+
82
+ filtered[:name].should == name
83
+ filtered[:wrapper][:wrapper2][:foo].should == "bar"
84
+
85
+ filtered_file = filtered[:wrapper][:wrapper2][:a_file]
86
+ filtered_file.should be_a_kind_of(Hash)
87
+ filtered_file[:content_type].should == file_hash[:type]
88
+ filtered_file[:original_filename].should == file_hash[:filename]
89
+ filtered_file[:size].should == file_hash[:tempfile].size
90
+ end
91
+
92
+ it "should scrub the default scrub_fields" do
93
+ params = {
94
+ :passwd => "hidden",
95
+ :password => "hidden",
96
+ :secret => "hidden",
97
+ :notpass => "visible"
98
+ }
99
+
100
+ filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
101
+
102
+ filtered[:passwd].should == "******"
103
+ filtered[:password].should == "******"
104
+ filtered[:secret].should == "******"
105
+ filtered[:notpass].should == "visible"
106
+ end
107
+
108
+ it "should scrub custom scrub_fields" do
109
+ Rollbar.configure do |config|
110
+ config.scrub_fields = [:notpass, :secret]
111
+ end
112
+
113
+ params = {
114
+ :passwd => "visible",
115
+ :password => "visible",
116
+ :secret => "hidden",
117
+ :notpass => "hidden"
118
+ }
119
+
120
+ filtered = controller.send(:rollbar_filtered_params, Rollbar.configuration.scrub_fields, params)
121
+
122
+ filtered[:passwd].should == "visible"
123
+ filtered[:password].should == "visible"
124
+ filtered[:secret].should == "******"
125
+ filtered[:notpass].should == "******"
126
+ end
127
+ end
128
+
129
+ context "rollbar_request_url" do
130
+ it "should build simple http urls" do
131
+ req = controller.request
132
+ req.host = 'rollbar.com'
133
+
134
+ controller.send(:rollbar_request_data)[:url].should == 'http://rollbar.com'
135
+ end
136
+ end
137
+
138
+ context "rollbar_user_ip" do
139
+ it "should use X-Real-Ip when set" do
140
+ controller.request.env["HTTP_X_REAL_IP"] = '1.1.1.1'
141
+ controller.request.env["HTTP_X_FORWARDED_FOR"] = '1.2.3.4'
142
+ controller.send(:rollbar_request_data)[:user_ip].should == '1.1.1.1'
143
+ end
144
+
145
+ it "should use X-Forwarded-For when set" do
146
+ controller.request.env["HTTP_X_FORWARDED_FOR"] = '1.2.3.4'
147
+ controller.send(:rollbar_request_data)[:user_ip].should == '1.2.3.4'
148
+ end
149
+
150
+ it "should use the remote_addr when neither is set" do
151
+ controller.send(:rollbar_request_data)[:user_ip].should == '0.0.0.0'
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+ describe "GET 'index'" do
158
+ it "should be successful and report a message" do
159
+ logger_mock.should_receive(:info).with('[Rollbar] Success')
160
+ get 'index'
161
+ response.should be_success
162
+ end
163
+ end
164
+
165
+ describe "GET 'report_exception'" do
166
+ it "should raise a NameError and report an exception" do
167
+ logger_mock.should_receive(:info).with('[Rollbar] Success')
168
+
169
+ get 'report_exception'
170
+ response.should be_success
171
+ end
172
+ end
173
+
174
+ after(:each) do
175
+ Rollbar.configure do |config|
176
+ config.logger = ::Rails.logger
177
+ end
178
+ end
179
+
180
+ end
@@ -0,0 +1,73 @@
1
+ #----------------------------------------------------------------------------
2
+ # Ignore these files when commiting to a git repository.
3
+ #
4
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
5
+ #
6
+ # The original version of this file is found here:
7
+ # https://github.com/RailsApps/rails-composer/blob/master/files/gitignore.txt
8
+ #
9
+ # Corrections? Improvements? Create a GitHub issue:
10
+ # http://github.com/RailsApps/rails-composer/issues
11
+ #----------------------------------------------------------------------------
12
+
13
+ # bundler state
14
+ /.bundle
15
+ /vendor/bundle/
16
+ /vendor/ruby/
17
+
18
+ # minimal Rails specific artifacts
19
+ db/*.sqlite3
20
+ /log/*
21
+ /tmp/*
22
+
23
+ # various artifacts
24
+ **.war
25
+ *.rbc
26
+ *.sassc
27
+ .rspec
28
+ .redcar/
29
+ .sass-cache
30
+ /config/config.yml
31
+ /coverage.data
32
+ /coverage/
33
+ /db/*.javadb/
34
+ /db/*.sqlite3
35
+ /doc/api/
36
+ /doc/app/
37
+ /doc/features.html
38
+ /doc/specs.html
39
+ /public/cache
40
+ /public/stylesheets/compiled
41
+ /public/system/*
42
+ /spec/tmp/*
43
+ /cache
44
+ /capybara*
45
+ /capybara-*.html
46
+ /gems
47
+ /specifications
48
+ rerun.txt
49
+ pickle-email-*.html
50
+
51
+ # If you find yourself ignoring temporary files generated by your text editor
52
+ # or operating system, you probably want to add a global ignore instead:
53
+ # git config --global core.excludesfile ~/.gitignore_global
54
+ #
55
+ # Here are some files you may want to ignore globally:
56
+
57
+ # scm revert files
58
+ **.orig
59
+
60
+ # Mac finder artifacts
61
+ .DS_Store
62
+
63
+ # Netbeans project directory
64
+ /nbproject/
65
+
66
+ # RubyMine project files
67
+ .idea
68
+
69
+ # Textmate project files
70
+ /*.tmproj
71
+
72
+ # vim artifacts
73
+ **.swp
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require_tree .
@@ -0,0 +1,37 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
14
+ .brand {
15
+ float: left;
16
+ padding-right: 8px;
17
+ }
18
+ ul.nav {
19
+ list-style: none;
20
+ margin: 0 0 2em;
21
+ padding: 0;
22
+ }
23
+ ul.nav li {
24
+ display: inline;
25
+ }
26
+ #flash_notice, #flash_alert {
27
+ padding: 5px 8px;
28
+ margin: 10px 0;
29
+ }
30
+ #flash_notice {
31
+ background-color: #CFC;
32
+ border: solid 1px #6C6;
33
+ }
34
+ #flash_alert {
35
+ background-color: #FCC;
36
+ border: solid 1px #C66;
37
+ }
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,25 @@
1
+ class HomeController < ApplicationController
2
+ def index
3
+ @users = User.all
4
+
5
+ Rollbar.report_message("Test message from controller with no data", "debug")
6
+ Rollbar.report_message("Test message from controller with extra data", "debug",
7
+ :foo => "bar", :num_users => @users.length)
8
+ end
9
+
10
+ def report_exception
11
+ begin
12
+ foo = bar
13
+ rescue => e
14
+ Rollbar.report_exception(e, rollbar_request_data, rollbar_person_data)
15
+ end
16
+ end
17
+
18
+ def cause_exception
19
+ foo = bar
20
+ end
21
+
22
+ def current_user
23
+ User.find_by_encrypted_password(cookies[:session_id])
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ class UsersController < ApplicationController
2
+ before_filter :authenticate_user!
3
+
4
+ def index
5
+ @users = User.all
6
+ end
7
+
8
+ def show
9
+ @user = User.find(params[:id])
10
+ end
11
+
12
+ def start_session
13
+ @user = User.find(params[:id])
14
+ cookies[:session_id] = @user.encrypted_password
15
+ end
16
+
17
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,10 @@
1
+ class User < ActiveRecord::Base
2
+ # Include default devise modules. Others available are:
3
+ # :token_authenticatable, :confirmable,
4
+ # :lockable, :timeoutable and :omniauthable
5
+ devise :database_authenticatable, :registerable,
6
+ :recoverable, :rememberable, :trackable, :validatable
7
+
8
+ # Setup accessible (or protected) attributes for your model
9
+ attr_accessible :name, :email, :password, :password_confirmation, :remember_me
10
+ end
@@ -0,0 +1,27 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+ <p><%= f.label :name %><br />
6
+ <%= f.text_field :name %></p>
7
+
8
+ <div><%= f.label :email %><br />
9
+ <%= f.email_field :email %></div>
10
+
11
+ <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
12
+ <%= f.password_field :password, :autocomplete => "off" %></div>
13
+
14
+ <div><%= f.label :password_confirmation %><br />
15
+ <%= f.password_field :password_confirmation %></div>
16
+
17
+ <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
18
+ <%= f.password_field :current_password %></div>
19
+
20
+ <div><%= f.submit "Update" %></div>
21
+ <% end %>
22
+
23
+ <h3>Cancel my account</h3>
24
+
25
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
26
+
27
+ <%= link_to "Back", :back %>