rollbar 2.22.0 → 2.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +136 -0
- data/.travis.yml +33 -30
- data/Gemfile +2 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +1 -0
- data/gemfiles/rails42.gemfile +4 -0
- data/gemfiles/rails60.gemfile +1 -1
- data/lib/rails/rollbar_runner.rb +3 -1
- data/lib/rollbar/configuration.rb +26 -6
- data/lib/rollbar/delay/girl_friday.rb +3 -7
- data/lib/rollbar/delay/resque.rb +2 -3
- data/lib/rollbar/delay/sidekiq.rb +2 -4
- data/lib/rollbar/delay/sucker_punch.rb +3 -4
- data/lib/rollbar/delay/thread.rb +14 -0
- data/lib/rollbar/encoding/encoder.rb +7 -3
- data/lib/rollbar/item.rb +13 -2
- data/lib/rollbar/item/backtrace.rb +13 -3
- data/lib/rollbar/item/frame.rb +2 -0
- data/lib/rollbar/item/locals.rb +45 -1
- data/lib/rollbar/middleware/js.rb +6 -1
- data/lib/rollbar/notifier.rb +67 -33
- data/lib/rollbar/plugins/active_job.rb +6 -2
- data/lib/rollbar/plugins/delayed_job/plugin.rb +7 -1
- data/lib/rollbar/plugins/error_context.rb +11 -0
- data/lib/rollbar/request_data_extractor.rb +6 -1
- data/lib/rollbar/scrubbers.rb +1 -5
- data/lib/rollbar/truncation/frames_strategy.rb +1 -1
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/truncation/strings_strategy.rb +4 -2
- data/lib/rollbar/util.rb +4 -0
- data/lib/rollbar/version.rb +1 -1
- data/rollbar.gemspec +1 -0
- data/spec/support/rollbar_api.rb +67 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1848033c2fc853846ba902fbe4dc6095ad17a6e27595a3937484a6036154b76
|
|
4
|
+
data.tar.gz: a42d4a1274624ea5991b66b0df1ce7031d699390c5dcf574b98d8fe03ea5519d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5d71b0e452e917b566e48a292368a242404c2d26e91c011f641f1fb7bde2b05ee8bd88a9af6d595bf6581cea17d5d4a996af63104c4ea55a19de564760b4f7f3
|
|
7
|
+
data.tar.gz: b7ec97dfa2625823709eba27b5252706fce661877b9e4338595228c901e5766ab9752a5103a87f929d7af8ae9c687a978f7630d93d0aee5611ab58e5771ccd2c
|
data/.rubocop.yml
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require: rubocop-performance
|
|
2
|
+
|
|
1
3
|
AllCops:
|
|
2
4
|
Exclude:
|
|
3
5
|
- 'vendor/**/*'
|
|
@@ -66,3 +68,137 @@ Style/FrozenStringLiteralComment:
|
|
|
66
68
|
# If we do this, it will be in its own PR. It requires adding these magic comments
|
|
67
69
|
# throughout the project, in order to prepare for a future Ruby 3.x.
|
|
68
70
|
Enabled: false
|
|
71
|
+
|
|
72
|
+
Style/SafeNavigation:
|
|
73
|
+
# Not available in Ruby < 2.3.
|
|
74
|
+
Enabled: false
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Performance cops are opt in, and `Enabled: true` is always required.
|
|
78
|
+
# Full list is here: https://github.com/rubocop-hq/rubocop-performance/tree/master/lib/rubocop/cop/performance
|
|
79
|
+
# For travis builds, Codacy will see and use these directives.
|
|
80
|
+
#
|
|
81
|
+
Performance/Caller:
|
|
82
|
+
Enabled: true
|
|
83
|
+
Exclude:
|
|
84
|
+
- spec/**/*
|
|
85
|
+
|
|
86
|
+
Performance/CaseWhenSplat:
|
|
87
|
+
Enabled: true
|
|
88
|
+
Exclude:
|
|
89
|
+
- spec/**/*
|
|
90
|
+
|
|
91
|
+
Performance/Casecmp:
|
|
92
|
+
Enabled: true
|
|
93
|
+
Exclude:
|
|
94
|
+
- spec/**/*
|
|
95
|
+
|
|
96
|
+
Performance/ChainArrayAllocation:
|
|
97
|
+
Enabled: true
|
|
98
|
+
Exclude:
|
|
99
|
+
- spec/**/*
|
|
100
|
+
|
|
101
|
+
Performance/CompareWithBlock:
|
|
102
|
+
Enabled: true
|
|
103
|
+
Exclude:
|
|
104
|
+
- spec/**/*
|
|
105
|
+
|
|
106
|
+
Performance/Count:
|
|
107
|
+
Enabled: true
|
|
108
|
+
Exclude:
|
|
109
|
+
- spec/**/*
|
|
110
|
+
|
|
111
|
+
Performance/Detect:
|
|
112
|
+
Enabled: true
|
|
113
|
+
Exclude:
|
|
114
|
+
- spec/**/*
|
|
115
|
+
|
|
116
|
+
Performance/DoubleStartEndWith:
|
|
117
|
+
Enabled: true
|
|
118
|
+
Exclude:
|
|
119
|
+
- spec/**/*
|
|
120
|
+
|
|
121
|
+
Performance/EndWith:
|
|
122
|
+
Enabled: true
|
|
123
|
+
Exclude:
|
|
124
|
+
- spec/**/*
|
|
125
|
+
|
|
126
|
+
Performance/FixedSize:
|
|
127
|
+
Enabled: true
|
|
128
|
+
Exclude:
|
|
129
|
+
- spec/**/*
|
|
130
|
+
|
|
131
|
+
Performance/FlatMap:
|
|
132
|
+
Enabled: true
|
|
133
|
+
Exclude:
|
|
134
|
+
- spec/**/*
|
|
135
|
+
|
|
136
|
+
Performance/InefficientHashSearch:
|
|
137
|
+
Enabled: true
|
|
138
|
+
Exclude:
|
|
139
|
+
- spec/**/*
|
|
140
|
+
|
|
141
|
+
Performance/OpenStruct:
|
|
142
|
+
Enabled: true
|
|
143
|
+
Exclude:
|
|
144
|
+
- spec/**/*
|
|
145
|
+
|
|
146
|
+
Performance/RangeInclude:
|
|
147
|
+
Enabled: true
|
|
148
|
+
Exclude:
|
|
149
|
+
- spec/**/*
|
|
150
|
+
|
|
151
|
+
Performance/RedundantBlockCall:
|
|
152
|
+
Enabled: true
|
|
153
|
+
Exclude:
|
|
154
|
+
- spec/**/*
|
|
155
|
+
|
|
156
|
+
Performance/RedundantMatch:
|
|
157
|
+
Enabled: true
|
|
158
|
+
Exclude:
|
|
159
|
+
- spec/**/*
|
|
160
|
+
|
|
161
|
+
Performance/RedundantMerge:
|
|
162
|
+
Enabled: true
|
|
163
|
+
Exclude:
|
|
164
|
+
- spec/**/*
|
|
165
|
+
|
|
166
|
+
Performance/RegexpMatch:
|
|
167
|
+
Enabled: true
|
|
168
|
+
Exclude:
|
|
169
|
+
- spec/**/*
|
|
170
|
+
|
|
171
|
+
Performance/ReverseEach:
|
|
172
|
+
Enabled: true
|
|
173
|
+
Exclude:
|
|
174
|
+
- spec/**/*
|
|
175
|
+
|
|
176
|
+
Performance/Size:
|
|
177
|
+
Enabled: true
|
|
178
|
+
Exclude:
|
|
179
|
+
- spec/**/*
|
|
180
|
+
|
|
181
|
+
Performance/StartWith:
|
|
182
|
+
Enabled: true
|
|
183
|
+
Exclude:
|
|
184
|
+
- spec/**/*
|
|
185
|
+
|
|
186
|
+
Performance/StringReplacement:
|
|
187
|
+
Enabled: true
|
|
188
|
+
Exclude:
|
|
189
|
+
- spec/**/*
|
|
190
|
+
|
|
191
|
+
Performance/TimesMap:
|
|
192
|
+
Enabled: true
|
|
193
|
+
Exclude:
|
|
194
|
+
- spec/**/*
|
|
195
|
+
|
|
196
|
+
Performance/UnfreezeString:
|
|
197
|
+
Enabled: true
|
|
198
|
+
Exclude:
|
|
199
|
+
- spec/**/*
|
|
200
|
+
|
|
201
|
+
Performance/UriDefaultParser:
|
|
202
|
+
Enabled: true
|
|
203
|
+
Exclude:
|
|
204
|
+
- spec/**/*
|
data/.travis.yml
CHANGED
|
@@ -3,12 +3,6 @@ dist: trusty
|
|
|
3
3
|
services:
|
|
4
4
|
- redis-server
|
|
5
5
|
language: ruby
|
|
6
|
-
# Broken bundler on travis CI - https://github.com/bundler/bundler/issues/2784
|
|
7
|
-
before_install:
|
|
8
|
-
- gem update --system 2.7.7
|
|
9
|
-
- gem --version
|
|
10
|
-
- gem install bundler -v 1.6.1
|
|
11
|
-
- bundle --version
|
|
12
6
|
|
|
13
7
|
rvm:
|
|
14
8
|
- 1.9.3
|
|
@@ -18,8 +12,8 @@ rvm:
|
|
|
18
12
|
- 2.3.8
|
|
19
13
|
- 2.4.5
|
|
20
14
|
- 2.5.3
|
|
21
|
-
- 2.6.
|
|
22
|
-
- 2.
|
|
15
|
+
- 2.6.5
|
|
16
|
+
- 2.7.0
|
|
23
17
|
- rbx
|
|
24
18
|
# Travis's own rvm installer is failing on JRuby builds, TODO: reenable when fixed.
|
|
25
19
|
# - jruby-9.1.9.0
|
|
@@ -73,9 +67,6 @@ matrix:
|
|
|
73
67
|
allow_failures:
|
|
74
68
|
- rvm: ruby-head
|
|
75
69
|
- rvm: jruby-head
|
|
76
|
-
# Ruby 2.6.x is still being eveluated and may have test failures
|
|
77
|
-
- rvm: 2.6.0
|
|
78
|
-
- rvm: 2.6.3
|
|
79
70
|
# oraclejdk9 has a dependency issue that needs to be investigated
|
|
80
71
|
- jdk: oraclejdk9
|
|
81
72
|
|
|
@@ -124,17 +115,17 @@ matrix:
|
|
|
124
115
|
jdk: oraclejdk8
|
|
125
116
|
- rvm: 2.5.3
|
|
126
117
|
jdk: oraclejdk9
|
|
127
|
-
- rvm: 2.6.
|
|
118
|
+
- rvm: 2.6.5
|
|
128
119
|
jdk: openjdk8
|
|
129
|
-
- rvm: 2.6.
|
|
120
|
+
- rvm: 2.6.5
|
|
130
121
|
jdk: oraclejdk8
|
|
131
|
-
- rvm: 2.6.
|
|
122
|
+
- rvm: 2.6.5
|
|
132
123
|
jdk: oraclejdk9
|
|
133
|
-
- rvm: 2.
|
|
124
|
+
- rvm: 2.7.0
|
|
134
125
|
jdk: openjdk8
|
|
135
|
-
- rvm: 2.
|
|
126
|
+
- rvm: 2.7.0
|
|
136
127
|
jdk: oraclejdk8
|
|
137
|
-
- rvm: 2.
|
|
128
|
+
- rvm: 2.7.0
|
|
138
129
|
jdk: oraclejdk9
|
|
139
130
|
|
|
140
131
|
- rvm: ruby-head
|
|
@@ -184,11 +175,14 @@ matrix:
|
|
|
184
175
|
gemfile: gemfiles/rails52.gemfile
|
|
185
176
|
- rvm: 2.1.0
|
|
186
177
|
gemfile: gemfiles/rails60.gemfile
|
|
187
|
-
# MRI 2.2.2 supports Rails 3.2.x and higher
|
|
178
|
+
# MRI 2.2.2 supports Rails 3.2.x and higher, except Rails 5.2.4 and higher*
|
|
179
|
+
# * ActionDispatch 5.2.4 uses Ruby 3.x safe navigation operator.
|
|
188
180
|
- rvm: 2.2.2
|
|
189
181
|
gemfile: gemfiles/rails30.gemfile
|
|
190
182
|
- rvm: 2.2.2
|
|
191
183
|
gemfile: gemfiles/rails31.gemfile
|
|
184
|
+
- rvm: 2.2.2
|
|
185
|
+
gemfile: gemfiles/rails52.gemfile
|
|
192
186
|
# MRI 2.3.x supports Rails 4.0.x and higher
|
|
193
187
|
- rvm: 2.3.8
|
|
194
188
|
gemfile: gemfiles/rails30.gemfile
|
|
@@ -222,30 +216,39 @@ matrix:
|
|
|
222
216
|
gemfile: gemfiles/rails40.gemfile
|
|
223
217
|
- rvm: 2.5.3
|
|
224
218
|
gemfile: gemfiles/rails41.gemfile
|
|
225
|
-
- rvm: 2.6.
|
|
219
|
+
- rvm: 2.6.5
|
|
226
220
|
gemfile: gemfiles/rails30.gemfile
|
|
227
|
-
- rvm: 2.6.
|
|
221
|
+
- rvm: 2.6.5
|
|
228
222
|
gemfile: gemfiles/rails31.gemfile
|
|
229
|
-
- rvm: 2.6.
|
|
223
|
+
- rvm: 2.6.5
|
|
230
224
|
gemfile: gemfiles/rails32.gemfile
|
|
231
|
-
- rvm: 2.6.
|
|
225
|
+
- rvm: 2.6.5
|
|
232
226
|
gemfile: gemfiles/rails40.gemfile
|
|
233
|
-
- rvm: 2.6.
|
|
227
|
+
- rvm: 2.6.5
|
|
234
228
|
gemfile: gemfiles/rails41.gemfile
|
|
235
|
-
- rvm: 2.6.
|
|
229
|
+
- rvm: 2.6.5
|
|
236
230
|
gemfile: gemfiles/rails42.gemfile
|
|
237
|
-
|
|
231
|
+
# Rails 6.x tries to be compatible with Ruby 2.7, though
|
|
232
|
+
# it still throws a lot of warnings. No point testing earlier
|
|
233
|
+
# Rails with Ruby 2.7.
|
|
234
|
+
- rvm: 2.7.0
|
|
238
235
|
gemfile: gemfiles/rails30.gemfile
|
|
239
|
-
- rvm: 2.
|
|
236
|
+
- rvm: 2.7.0
|
|
240
237
|
gemfile: gemfiles/rails31.gemfile
|
|
241
|
-
- rvm: 2.
|
|
238
|
+
- rvm: 2.7.0
|
|
242
239
|
gemfile: gemfiles/rails32.gemfile
|
|
243
|
-
- rvm: 2.
|
|
240
|
+
- rvm: 2.7.0
|
|
244
241
|
gemfile: gemfiles/rails40.gemfile
|
|
245
|
-
- rvm: 2.
|
|
242
|
+
- rvm: 2.7.0
|
|
246
243
|
gemfile: gemfiles/rails41.gemfile
|
|
247
|
-
- rvm: 2.
|
|
244
|
+
- rvm: 2.7.0
|
|
248
245
|
gemfile: gemfiles/rails42.gemfile
|
|
246
|
+
- rvm: 2.7.0
|
|
247
|
+
gemfile: gemfiles/rails50.gemfile
|
|
248
|
+
- rvm: 2.7.0
|
|
249
|
+
gemfile: gemfiles/rails51.gemfile
|
|
250
|
+
- rvm: 2.7.0
|
|
251
|
+
gemfile: gemfiles/rails52.gemfile
|
|
249
252
|
# JRuby JDBC Adapter is only compatible with Rails >= 5.x
|
|
250
253
|
- rvm: jruby-9.1.9.0
|
|
251
254
|
gemfile: gemfiles/rails30.gemfile
|
data/Gemfile
CHANGED
|
@@ -46,6 +46,7 @@ end
|
|
|
46
46
|
|
|
47
47
|
if RUBY_VERSION.start_with?('1.9')
|
|
48
48
|
gem 'capistrano', '<= 3.4.1', :require => false
|
|
49
|
+
gem 'json', '1.8.6'
|
|
49
50
|
gem 'shoryuken', '>= 4.0.0', '<= 4.0.2'
|
|
50
51
|
gem 'sucker_punch', '~> 1.0'
|
|
51
52
|
elsif RUBY_VERSION.start_with?('2')
|
|
@@ -73,6 +74,7 @@ gem 'girl_friday', '>= 0.11.1'
|
|
|
73
74
|
gem 'redis'
|
|
74
75
|
gem 'resque', '< 2.0.0'
|
|
75
76
|
gem 'rubocop', :require => false
|
|
77
|
+
gem 'rubocop-performance', :require => false
|
|
76
78
|
gem 'sinatra'
|
|
77
79
|
gem 'webmock', :require => false
|
|
78
80
|
gemspec
|
data/data/rollbar.snippet.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(r){var e={};function o(n){if(e[n])return e[n].exports;var t=e[n]={i:n,l:!1,exports:{}};return r[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=e,o.d=function(r,e,n){o.o(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:n})},o.r=function(r){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},o.t=function(r,e){if(1&e&&(r=o(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var t in r)o.d(n,t,function(e){return r[e]}.bind(null,t));return n},o.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return o.d(e,"a",e),e},o.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},o.p="",o(o.s=0)}([function(r,e,o){var n=o(1),t=o(4);_rollbarConfig=_rollbarConfig||{},_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||"https://cdnjs.cloudflare.com/ajax/libs/rollbar.js/2.12.
|
|
1
|
+
!function(r){var e={};function o(n){if(e[n])return e[n].exports;var t=e[n]={i:n,l:!1,exports:{}};return r[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=e,o.d=function(r,e,n){o.o(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:n})},o.r=function(r){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},o.t=function(r,e){if(1&e&&(r=o(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var t in r)o.d(n,t,function(e){return r[e]}.bind(null,t));return n},o.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return o.d(e,"a",e),e},o.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},o.p="",o(o.s=0)}([function(r,e,o){var n=o(1),t=o(4);_rollbarConfig=_rollbarConfig||{},_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||"https://cdnjs.cloudflare.com/ajax/libs/rollbar.js/2.12.3/rollbar.min.js",_rollbarConfig.async=void 0===_rollbarConfig.async||_rollbarConfig.async;var a=n.setupShim(window,_rollbarConfig),l=t(_rollbarConfig);window.rollbar=n.Rollbar,a.loadFull(window,document,!_rollbarConfig.async,_rollbarConfig,l)},function(r,e,o){var n=o(2);function t(r){return function(){try{return r.apply(this,arguments)}catch(r){try{console.error("[Rollbar]: Internal error",r)}catch(r){}}}}var a=0;function l(r,e){this.options=r,this._rollbarOldOnError=null;var o=a++;this.shimId=function(){return o},"undefined"!=typeof window&&window._rollbarShims&&(window._rollbarShims[o]={handler:e,messages:[]})}var i=o(3),s=function(r,e){return new l(r,e)},d=function(r){return new i(s,r)};function c(r){return t(function(){var e=Array.prototype.slice.call(arguments,0),o={shim:this,method:r,args:e,ts:new Date};window._rollbarShims[this.shimId()].messages.push(o)})}l.prototype.loadFull=function(r,e,o,n,a){var l=!1,i=e.createElement("script"),s=e.getElementsByTagName("script")[0],d=s.parentNode;i.crossOrigin="",i.src=n.rollbarJsUrl,o||(i.async=!0),i.onload=i.onreadystatechange=t(function(){if(!(l||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){i.onload=i.onreadystatechange=null;try{d.removeChild(i)}catch(r){}l=!0,function(){var e;if(void 0===r._rollbarDidLoad){e=new Error("rollbar.js did not load");for(var o,n,t,l,i=0;o=r._rollbarShims[i++];)for(o=o.messages||[];n=o.shift();)for(t=n.args||[],i=0;i<t.length;++i)if("function"==typeof(l=t[i])){l(e);break}}"function"==typeof a&&a(e)}()}}),d.insertBefore(i,s)},l.prototype.wrap=function(r,e,o){try{var n;if(n="function"==typeof e?e:function(){return e||{}},"function"!=typeof r)return r;if(r._isWrap)return r;if(!r._rollbar_wrapped&&(r._rollbar_wrapped=function(){o&&"function"==typeof o&&o.apply(this,arguments);try{return r.apply(this,arguments)}catch(o){var e=o;throw e&&("string"==typeof e&&(e=new String(e)),e._rollbarContext=n()||{},e._rollbarContext._wrappedSource=r.toString(),window._rollbarWrappedError=e),e}},r._rollbar_wrapped._isWrap=!0,r.hasOwnProperty))for(var t in r)r.hasOwnProperty(t)&&(r._rollbar_wrapped[t]=r[t]);return r._rollbar_wrapped}catch(e){return r}};for(var p="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleAnonymousErrors,handleUnhandledRejection,captureEvent,captureDomContentLoaded,captureLoad".split(","),u=0;u<p.length;++u)l.prototype[p[u]]=c(p[u]);r.exports={setupShim:function(r,e){if(r){var o=e.globalAlias||"Rollbar";if("object"==typeof r[o])return r[o];r._rollbarShims={},r._rollbarWrappedError=null;var a=new d(e);return t(function(){e.captureUncaught&&(a._rollbarOldOnError=r.onerror,n.captureUncaughtExceptions(r,a,!0),e.wrapGlobalEventHandlers&&n.wrapGlobals(r,a,!0)),e.captureUnhandledRejections&&n.captureUnhandledRejections(r,a,!0);var t=e.autoInstrument;return!1!==e.enabled&&(void 0===t||!0===t||"object"==typeof t&&t.network)&&r.addEventListener&&(r.addEventListener("load",a.captureLoad.bind(a)),r.addEventListener("DOMContentLoaded",a.captureDomContentLoaded.bind(a))),r[o]=a,a})()}},Rollbar:d}},function(r,e){function o(r,e,o){if(e.hasOwnProperty&&e.hasOwnProperty("addEventListener")){for(var n=e.addEventListener;n._rollbarOldAdd&&n.belongsToShim;)n=n._rollbarOldAdd;var t=function(e,o,t){n.call(this,e,r.wrap(o),t)};t._rollbarOldAdd=n,t.belongsToShim=o,e.addEventListener=t;for(var a=e.removeEventListener;a._rollbarOldRemove&&a.belongsToShim;)a=a._rollbarOldRemove;var l=function(r,e,o){a.call(this,r,e&&e._rollbar_wrapped||e,o)};l._rollbarOldRemove=a,l.belongsToShim=o,e.removeEventListener=l}}r.exports={captureUncaughtExceptions:function(r,e,o){if(r){var n;if("function"==typeof e._rollbarOldOnError)n=e._rollbarOldOnError;else if(r.onerror){for(n=r.onerror;n._rollbarOldOnError;)n=n._rollbarOldOnError;e._rollbarOldOnError=n}e.handleAnonymousErrors();var t=function(){var o=Array.prototype.slice.call(arguments,0);!function(r,e,o,n){r._rollbarWrappedError&&(n[4]||(n[4]=r._rollbarWrappedError),n[5]||(n[5]=r._rollbarWrappedError._rollbarContext),r._rollbarWrappedError=null);var t=e.handleUncaughtException.apply(e,n);o&&o.apply(r,n),"anonymous"===t&&(e.anonymousErrorsPending+=1)}(r,e,n,o)};o&&(t._rollbarOldOnError=n),r.onerror=t}},captureUnhandledRejections:function(r,e,o){if(r){"function"==typeof r._rollbarURH&&r._rollbarURH.belongsToShim&&r.removeEventListener("unhandledrejection",r._rollbarURH);var n=function(r){var o,n,t;try{o=r.reason}catch(r){o=void 0}try{n=r.promise}catch(r){n="[unhandledrejection] error getting `promise` from event"}try{t=r.detail,!o&&t&&(o=t.reason,n=t.promise)}catch(r){}o||(o="[unhandledrejection] error getting `reason` from event"),e&&e.handleUnhandledRejection&&e.handleUnhandledRejection(o,n)};n.belongsToShim=o,r._rollbarURH=n,r.addEventListener("unhandledrejection",n)}},wrapGlobals:function(r,e,n){if(r){var t,a,l="EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload".split(",");for(t=0;t<l.length;++t)r[a=l[t]]&&r[a].prototype&&o(e,r[a].prototype,n)}}}},function(r,e){function o(r,e){this.impl=r(e,this),this.options=e,function(r){for(var e=function(r){return function(){var e=Array.prototype.slice.call(arguments,0);if(this.impl[r])return this.impl[r].apply(this.impl,e)}},o="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleAnonymousErrors,handleUnhandledRejection,_createItem,wrap,loadFull,shimId,captureEvent,captureDomContentLoaded,captureLoad".split(","),n=0;n<o.length;n++)r[o[n]]=e(o[n])}(o.prototype)}o.prototype._swapAndProcessMessages=function(r,e){var o,n,t;for(this.impl=r(this.options);o=e.shift();)n=o.method,t=o.args,this[n]&&"function"==typeof this[n]&&("captureDomContentLoaded"===n||"captureLoad"===n?this[n].apply(this,[t[0],o.ts]):this[n].apply(this,t));return this},r.exports=o},function(r,e){r.exports=function(r){return function(e){if(!e&&!window._rollbarInitialized){for(var o,n,t=(r=r||{}).globalAlias||"Rollbar",a=window.rollbar,l=function(r){return new a(r)},i=0;o=window._rollbarShims[i++];)n||(n=o.handler),o.handler._swapAndProcessMessages(l,o.messages);window[t]=n,window._rollbarInitialized=!0}}}}]);
|
data/docs/configuration.md
CHANGED
|
@@ -129,6 +129,7 @@ An array of backup handlers if the async handlers fails. Each should respond to
|
|
|
129
129
|
|
|
130
130
|
For use with `write_to_file`. Indicates location of the rollbar log file being
|
|
131
131
|
tracked by [rollbar-agent](https://github.com/rollbar/rollbar-agent).
|
|
132
|
+
Enable `files_with_pid_name_enabled` if you want to have different files for each process(only works if extension `rollbar`)
|
|
132
133
|
|
|
133
134
|
### framework
|
|
134
135
|
|
data/gemfiles/rails42.gemfile
CHANGED
data/gemfiles/rails60.gemfile
CHANGED
|
@@ -15,7 +15,7 @@ is_jruby = defined?(JRUBY_VERSION) || (defined?(RUBY_ENGINE) && 'jruby' == RUBY_
|
|
|
15
15
|
gem 'appraisal'
|
|
16
16
|
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
|
|
17
17
|
gem 'jruby-openssl', :platform => :jruby
|
|
18
|
-
gem 'rails', '6.0.
|
|
18
|
+
gem 'rails', '6.0.2.1'
|
|
19
19
|
gem 'sqlite3', '~> 1.4', :platform => [:ruby, :mswin, :mingw]
|
|
20
20
|
|
|
21
21
|
gem 'rspec-core', '~> 3.8.0'
|
data/lib/rails/rollbar_runner.rb
CHANGED
|
@@ -39,7 +39,7 @@ module Rails
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def eval_runner
|
|
42
|
-
if Rails.version >= '5.1.0'
|
|
42
|
+
if Gem::Version.new(Rails.version) >= Gem::Version.new('5.1.0')
|
|
43
43
|
rails5_runner
|
|
44
44
|
else
|
|
45
45
|
legacy_runner
|
|
@@ -55,6 +55,8 @@ module Rails
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def rails5_runner
|
|
58
|
+
require 'rails/command'
|
|
59
|
+
|
|
58
60
|
Rails::Command.invoke 'runner', ARGV
|
|
59
61
|
end
|
|
60
62
|
|
|
@@ -17,13 +17,13 @@ module Rollbar
|
|
|
17
17
|
attr_accessor :disable_monkey_patch
|
|
18
18
|
attr_accessor :disable_rack_monkey_patch
|
|
19
19
|
attr_accessor :disable_core_monkey_patch
|
|
20
|
+
attr_accessor :enable_error_context
|
|
20
21
|
attr_accessor :dj_threshold
|
|
21
22
|
attr_accessor :enabled
|
|
22
23
|
attr_accessor :endpoint
|
|
23
24
|
attr_accessor :environment
|
|
24
25
|
attr_accessor :exception_level_filters
|
|
25
26
|
attr_accessor :failover_handlers
|
|
26
|
-
attr_accessor :filepath
|
|
27
27
|
attr_accessor :framework
|
|
28
28
|
attr_accessor :ignored_person_ids
|
|
29
29
|
attr_accessor :host
|
|
@@ -57,15 +57,23 @@ module Rollbar
|
|
|
57
57
|
attr_reader :transform
|
|
58
58
|
attr_accessor :verify_ssl_peer
|
|
59
59
|
attr_accessor :use_async
|
|
60
|
+
attr_accessor :async_json_payload
|
|
60
61
|
attr_reader :use_eventmachine
|
|
61
62
|
attr_accessor :web_base
|
|
62
|
-
attr_accessor :write_to_file
|
|
63
63
|
attr_reader :send_extra_frame_data
|
|
64
64
|
attr_accessor :use_exception_level_filters_default
|
|
65
65
|
attr_accessor :proxy
|
|
66
66
|
attr_accessor :raise_on_error
|
|
67
67
|
attr_accessor :transmit
|
|
68
68
|
attr_accessor :log_payload
|
|
69
|
+
attr_accessor :backtrace_cleaner
|
|
70
|
+
|
|
71
|
+
attr_accessor :write_to_file
|
|
72
|
+
attr_accessor :filepath
|
|
73
|
+
attr_accessor :files_with_pid_name_enabled
|
|
74
|
+
attr_accessor :files_processed_enabled
|
|
75
|
+
attr_accessor :files_processed_duration # seconds
|
|
76
|
+
attr_accessor :files_processed_size # bytes
|
|
69
77
|
|
|
70
78
|
attr_reader :project_gem_paths
|
|
71
79
|
attr_accessor :configured_options
|
|
@@ -87,6 +95,7 @@ module Rollbar
|
|
|
87
95
|
@disable_monkey_patch = false
|
|
88
96
|
@disable_core_monkey_patch = false
|
|
89
97
|
@disable_rack_monkey_patch = false
|
|
98
|
+
@enable_error_context = true
|
|
90
99
|
@dj_threshold = 0
|
|
91
100
|
@enabled = nil # set to true when configure is called
|
|
92
101
|
@endpoint = DEFAULT_ENDPOINT
|
|
@@ -118,7 +127,7 @@ module Rollbar
|
|
|
118
127
|
:api_key, :access_token, :accessToken, :session_id]
|
|
119
128
|
@scrub_user = true
|
|
120
129
|
@scrub_password = true
|
|
121
|
-
@randomize_scrub_length =
|
|
130
|
+
@randomize_scrub_length = false
|
|
122
131
|
@scrub_whitelist = []
|
|
123
132
|
@uncaught_exception_level = 'error'
|
|
124
133
|
@scrub_headers = ['Authorization']
|
|
@@ -126,10 +135,10 @@ module Rollbar
|
|
|
126
135
|
@safely = false
|
|
127
136
|
@transform = []
|
|
128
137
|
@use_async = false
|
|
138
|
+
@async_json_payload = false
|
|
129
139
|
@use_eventmachine = false
|
|
130
140
|
@verify_ssl_peer = true
|
|
131
141
|
@web_base = DEFAULT_WEB_BASE
|
|
132
|
-
@write_to_file = false
|
|
133
142
|
@send_extra_frame_data = :none
|
|
134
143
|
@project_gem_paths = []
|
|
135
144
|
@use_exception_level_filters_default = false
|
|
@@ -139,11 +148,18 @@ module Rollbar
|
|
|
139
148
|
@log_payload = false
|
|
140
149
|
@collect_user_ip = true
|
|
141
150
|
@anonymize_user_ip = false
|
|
151
|
+
@backtrace_cleaner = nil
|
|
142
152
|
@hooks = {
|
|
143
153
|
:on_error_response => nil, # params: response
|
|
144
154
|
:on_report_internal_error => nil # params: exception
|
|
145
155
|
}
|
|
146
156
|
|
|
157
|
+
@write_to_file = false
|
|
158
|
+
@files_with_pid_name_enabled = false
|
|
159
|
+
@files_processed_enabled = false
|
|
160
|
+
@files_processed_duration = 60
|
|
161
|
+
@files_processed_size = 5 * 1000 * 1000
|
|
162
|
+
|
|
147
163
|
@configured_options = ConfiguredOptions.new(self)
|
|
148
164
|
end
|
|
149
165
|
|
|
@@ -232,9 +248,10 @@ module Rollbar
|
|
|
232
248
|
value.is_a?(Hash) ? use_sidekiq(value) : use_sidekiq
|
|
233
249
|
end
|
|
234
250
|
|
|
235
|
-
def use_thread
|
|
251
|
+
def use_thread(options = {})
|
|
236
252
|
require 'rollbar/delay/thread'
|
|
237
253
|
@use_async = true
|
|
254
|
+
Rollbar::Delay::Thread.options = options
|
|
238
255
|
@async_handler = Rollbar::Delay::Thread
|
|
239
256
|
end
|
|
240
257
|
|
|
@@ -261,7 +278,10 @@ module Rollbar
|
|
|
261
278
|
found = Gem::Specification.each.select { |spec| name === spec.name }
|
|
262
279
|
puts "[Rollbar] No gems found matching #{name.inspect}" if found.empty?
|
|
263
280
|
found
|
|
264
|
-
end
|
|
281
|
+
end
|
|
282
|
+
@project_gem_paths.flatten!
|
|
283
|
+
@project_gem_paths.uniq!
|
|
284
|
+
@project_gem_paths.map!(&:gem_dir)
|
|
265
285
|
end
|
|
266
286
|
|
|
267
287
|
def before_process=(*handler)
|
|
@@ -12,13 +12,9 @@ module Rollbar
|
|
|
12
12
|
|
|
13
13
|
def queue
|
|
14
14
|
@queue ||= queue_class.new(nil, :size => 5) do |payload|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
rescue
|
|
18
|
-
# According to https://github.com/mperham/girl_friday/wiki#error-handling
|
|
19
|
-
# we reraise the exception so it can be handled some way
|
|
20
|
-
raise
|
|
21
|
-
end
|
|
15
|
+
Rollbar.process_from_async_handler(payload)
|
|
16
|
+
|
|
17
|
+
# Do not rescue. GirlFriday will call the error handler.
|
|
22
18
|
end
|
|
23
19
|
end
|
|
24
20
|
end
|
data/lib/rollbar/delay/resque.rb
CHANGED
|
@@ -24,9 +24,8 @@ module Rollbar
|
|
|
24
24
|
|
|
25
25
|
def perform(payload)
|
|
26
26
|
Rollbar.process_from_async_handler(payload)
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
raise
|
|
27
|
+
|
|
28
|
+
# Do not rescue. Resque will call the error handler.
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
|
@@ -17,10 +17,8 @@ module Rollbar
|
|
|
17
17
|
|
|
18
18
|
def perform(*args)
|
|
19
19
|
Rollbar.process_from_async_handler(*args)
|
|
20
|
-
|
|
21
|
-
#
|
|
22
|
-
# and retry it
|
|
23
|
-
raise
|
|
20
|
+
|
|
21
|
+
# Do not rescue. Sidekiq will call the error handler.
|
|
24
22
|
end
|
|
25
23
|
end
|
|
26
24
|
end
|
|
@@ -33,7 +33,7 @@ module Rollbar
|
|
|
33
33
|
|
|
34
34
|
def perform(*args)
|
|
35
35
|
Rollbar.process_from_async_handler(*args)
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
# SuckerPunch can configure an exception handler with:
|
|
38
38
|
#
|
|
39
39
|
# SuckerPunch.exception_handler { # do something here }
|
|
@@ -41,9 +41,8 @@ module Rollbar
|
|
|
41
41
|
# This is just passed to Celluloid.exception_handler which will
|
|
42
42
|
# push the reiceved block to an array of handlers, by default empty, [].
|
|
43
43
|
#
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
raise
|
|
44
|
+
|
|
45
|
+
# Do not rescue. SuckerPunch will call the error handler.
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
48
|
end
|
data/lib/rollbar/delay/thread.rb
CHANGED
|
@@ -9,7 +9,10 @@ module Rollbar
|
|
|
9
9
|
Error = Class.new(StandardError)
|
|
10
10
|
TimeoutError = Class.new(Error)
|
|
11
11
|
|
|
12
|
+
DEFAULT_PRIORITY = 1
|
|
13
|
+
|
|
12
14
|
class << self
|
|
15
|
+
attr_writer :options
|
|
13
16
|
attr_reader :reaper
|
|
14
17
|
|
|
15
18
|
def call(payload)
|
|
@@ -20,6 +23,10 @@ module Rollbar
|
|
|
20
23
|
thread
|
|
21
24
|
end
|
|
22
25
|
|
|
26
|
+
def options
|
|
27
|
+
@options || {}
|
|
28
|
+
end
|
|
29
|
+
|
|
23
30
|
private
|
|
24
31
|
|
|
25
32
|
def threads
|
|
@@ -61,9 +68,16 @@ module Rollbar
|
|
|
61
68
|
end
|
|
62
69
|
end # class << self
|
|
63
70
|
|
|
71
|
+
def priority
|
|
72
|
+
self.class.options[:priority] || DEFAULT_PRIORITY
|
|
73
|
+
end
|
|
74
|
+
|
|
64
75
|
def call(payload)
|
|
76
|
+
priority = self.priority
|
|
77
|
+
|
|
65
78
|
::Thread.new do
|
|
66
79
|
begin
|
|
80
|
+
::Thread.current.priority = priority
|
|
67
81
|
Rollbar.process_from_async_handler(payload)
|
|
68
82
|
rescue StandardError
|
|
69
83
|
# Here we swallow the exception:
|
|
@@ -3,7 +3,6 @@ module Rollbar
|
|
|
3
3
|
class Encoder
|
|
4
4
|
ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII].freeze
|
|
5
5
|
ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1].freeze
|
|
6
|
-
ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }.freeze
|
|
7
6
|
UTF8 = 'UTF-8'.freeze
|
|
8
7
|
BINARY = 'binary'.freeze
|
|
9
8
|
|
|
@@ -21,7 +20,13 @@ module Rollbar
|
|
|
21
20
|
encoded_value = if encoding == ::Encoding::UTF_8 && value.valid_encoding?
|
|
22
21
|
value
|
|
23
22
|
else
|
|
24
|
-
force_encoding(value).encode(
|
|
23
|
+
force_encoding(value).encode(
|
|
24
|
+
*encoding_args(value),
|
|
25
|
+
# Ruby 2.7 requires this to look like keyword args,
|
|
26
|
+
# and Ruby 1.9.3 doesn't understand keyword args, so
|
|
27
|
+
# don't use hash rockets here and both will be happy.
|
|
28
|
+
invalid: :replace, undef: :replace, replace: '' # rubocop:disable Style/HashSyntax
|
|
29
|
+
)
|
|
25
30
|
end
|
|
26
31
|
|
|
27
32
|
object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
|
|
@@ -54,7 +59,6 @@ module Rollbar
|
|
|
54
59
|
def encoding_args(value)
|
|
55
60
|
args = [UTF8]
|
|
56
61
|
args << BINARY if ASCII_ENCODINGS.include?(value.encoding)
|
|
57
|
-
args << ENCODING_OPTIONS
|
|
58
62
|
|
|
59
63
|
args
|
|
60
64
|
end
|
data/lib/rollbar/item.rb
CHANGED
|
@@ -109,6 +109,11 @@ module Rollbar
|
|
|
109
109
|
# the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
|
|
110
110
|
# Ruby's JSON.generate so deeply there's no workaround.
|
|
111
111
|
'not serialized in ActiveSupport < 4.1'
|
|
112
|
+
elsif configuration.use_async && !configuration.async_json_payload
|
|
113
|
+
# The setting allows serialization to be performed by each handler,
|
|
114
|
+
# and this usually means it is actually performed by ActiveSupport,
|
|
115
|
+
# which cannot safely serialize this key.
|
|
116
|
+
'not serialized when async_json_payload is not set'
|
|
112
117
|
else
|
|
113
118
|
scrub(configuration.configured_options.configured)
|
|
114
119
|
end
|
|
@@ -178,13 +183,19 @@ module Rollbar
|
|
|
178
183
|
end
|
|
179
184
|
|
|
180
185
|
def build_extra
|
|
186
|
+
merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
|
|
187
|
+
|
|
181
188
|
if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
|
|
182
|
-
Util.deep_merge(scrub(custom_data),
|
|
189
|
+
Util.deep_merge(scrub(custom_data), merged_extra)
|
|
183
190
|
else
|
|
184
|
-
|
|
191
|
+
merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
|
|
185
192
|
end
|
|
186
193
|
end
|
|
187
194
|
|
|
195
|
+
def error_context
|
|
196
|
+
exception.respond_to?(:rollbar_context) && exception.rollbar_context
|
|
197
|
+
end
|
|
198
|
+
|
|
188
199
|
def scrub(data)
|
|
189
200
|
return data unless data.is_a? Hash
|
|
190
201
|
|
|
@@ -55,7 +55,7 @@ module Rollbar
|
|
|
55
55
|
current_exception = exception
|
|
56
56
|
|
|
57
57
|
while current_exception.respond_to?(:cause) && (cause = current_exception.cause) && cause.is_a?(Exception) && !visited.include?(cause)
|
|
58
|
-
traces
|
|
58
|
+
traces.unshift(trace_data(cause))
|
|
59
59
|
visited << cause
|
|
60
60
|
current_exception = cause
|
|
61
61
|
end
|
|
@@ -74,10 +74,20 @@ module Rollbar
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def map_frames(current_exception)
|
|
77
|
-
|
|
77
|
+
frames = cleaned_backtrace(current_exception).map do |frame|
|
|
78
78
|
Rollbar::Item::Frame.new(self, frame,
|
|
79
79
|
:configuration => configuration).to_h
|
|
80
|
-
end
|
|
80
|
+
end
|
|
81
|
+
frames.reverse!
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def cleaned_backtrace(current_exception)
|
|
85
|
+
normalized_backtrace = exception_backtrace(current_exception)
|
|
86
|
+
if configuration.backtrace_cleaner
|
|
87
|
+
configuration.backtrace_cleaner.clean(normalized_backtrace)
|
|
88
|
+
else
|
|
89
|
+
normalized_backtrace
|
|
90
|
+
end
|
|
81
91
|
end
|
|
82
92
|
|
|
83
93
|
# Returns the backtrace to be sent to our API. There are 3 options:
|
data/lib/rollbar/item/frame.rb
CHANGED
data/lib/rollbar/item/locals.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'rollbar/notifier'
|
|
2
2
|
require 'rollbar/scrubbers/params'
|
|
3
|
+
require 'rollbar/util'
|
|
3
4
|
|
|
4
5
|
module Rollbar
|
|
5
6
|
class Item
|
|
@@ -39,8 +40,51 @@ module Rollbar
|
|
|
39
40
|
end
|
|
40
41
|
end
|
|
41
42
|
|
|
43
|
+
# Prepare objects to be handled by the payload serializer.
|
|
44
|
+
#
|
|
45
|
+
# Hashes and Arrays are traversed. Then all types execpt strings and
|
|
46
|
+
# immediates are exported using #inspect. Sending the object itself to the
|
|
47
|
+
# serializer can result in large recursive expansions, especially in Rails
|
|
48
|
+
# environments with ActiveRecord, ActiveSupport, etc. on the stack.
|
|
49
|
+
# Other export options could be #to_s, #to_h, and #as_json. Several of these
|
|
50
|
+
# will omit the class name, or are not implemented for many types.
|
|
51
|
+
#
|
|
52
|
+
# #inspect has the advantage that it is specifically intended for debugging
|
|
53
|
+
# output. If the user wants more or different information in the payload
|
|
54
|
+
# about a specific type, #inspect is the correct place to implement it.
|
|
55
|
+
# Likewise the default implementation should be oriented toward usefulness
|
|
56
|
+
# in debugging.
|
|
57
|
+
#
|
|
58
|
+
# Because #inspect outputs a string, it can be handled well by the string
|
|
59
|
+
# truncation strategy for large payloads.
|
|
60
|
+
#
|
|
42
61
|
def prepare_value(value)
|
|
43
|
-
value.
|
|
62
|
+
return simple_value?(value) ? value : value.inspect unless value.is_a?(Hash) || value.is_a?(Array)
|
|
63
|
+
|
|
64
|
+
cloned_value = ::Rollbar::Util.deep_copy(value)
|
|
65
|
+
::Rollbar::Util.iterate_and_update_with_block(cloned_value) do |v|
|
|
66
|
+
simple_value?(v) ? v : v.inspect
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
cloned_value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def simple_classes
|
|
73
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
|
74
|
+
[String, Symbol, Integer, Float, TrueClass, FalseClass, NilClass]
|
|
75
|
+
else
|
|
76
|
+
[String, Symbol, Fixnum, Bignum, Float, TrueClass, FalseClass, NilClass] # rubocop:disable Lint/UnifiedInteger
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def simple_value?(value)
|
|
81
|
+
simple_classes.each do |klass|
|
|
82
|
+
# Use instance_of? so that subclasses and module containers will
|
|
83
|
+
# be treated like complex object types, not simple values.
|
|
84
|
+
return true if value.instance_of?(klass)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
false
|
|
44
88
|
end
|
|
45
89
|
|
|
46
90
|
def scrub(hash)
|
|
@@ -83,7 +83,12 @@ module Rollbar
|
|
|
83
83
|
response = ::Rack::Response.new(response_string, app_result[0],
|
|
84
84
|
app_result[1])
|
|
85
85
|
|
|
86
|
-
response.finish
|
|
86
|
+
finished = response.finish
|
|
87
|
+
|
|
88
|
+
# Rack < 2.x Response#finish returns self in array[2]. Rack >= 2.x returns self.body.
|
|
89
|
+
# Always return with the response object here regardless of rack version.
|
|
90
|
+
finished[2] = response
|
|
91
|
+
finished
|
|
87
92
|
end
|
|
88
93
|
|
|
89
94
|
def build_body_with_js(env, body, head_open_end)
|
data/lib/rollbar/notifier.rb
CHANGED
|
@@ -19,7 +19,8 @@ module Rollbar
|
|
|
19
19
|
attr_accessor :last_report
|
|
20
20
|
attr_accessor :scope_object
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
MUTEX = Mutex.new
|
|
23
|
+
EXTENSION_REGEXP = /.rollbar\z/.freeze
|
|
23
24
|
|
|
24
25
|
def initialize(parent_notifier = nil, payload_options = nil, scope = nil)
|
|
25
26
|
if parent_notifier
|
|
@@ -200,18 +201,20 @@ module Rollbar
|
|
|
200
201
|
def process_item(item)
|
|
201
202
|
if configuration.write_to_file
|
|
202
203
|
if configuration.use_async
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
MUTEX.synchronize do
|
|
205
|
+
do_write_item(item)
|
|
205
206
|
end
|
|
206
207
|
else
|
|
207
|
-
|
|
208
|
+
do_write_item(item)
|
|
208
209
|
end
|
|
209
210
|
else
|
|
210
211
|
send_item(item)
|
|
211
212
|
end
|
|
212
213
|
rescue StandardError => e
|
|
213
214
|
log_error("[Rollbar] Error processing the item: #{e.class}, #{e.message}. Item: #{item.payload.inspect}")
|
|
214
|
-
raise e
|
|
215
|
+
raise e unless via_failsafe?(item)
|
|
216
|
+
|
|
217
|
+
log_error('[Rollbar] Item has already failed. Not re-raising')
|
|
215
218
|
end
|
|
216
219
|
|
|
217
220
|
# We will reraise exceptions in this method so async queues
|
|
@@ -238,16 +241,19 @@ module Rollbar
|
|
|
238
241
|
# Using Rollbar.silenced we avoid the above behavior but Sidekiq
|
|
239
242
|
# will have a chance to retry the original job.
|
|
240
243
|
def process_from_async_handler(payload)
|
|
241
|
-
payload = Rollbar::JSON.load(payload) if payload.is_a?(String)
|
|
242
|
-
|
|
243
|
-
item = Item.build_with(payload,
|
|
244
|
-
:notifier => self,
|
|
245
|
-
:configuration => configuration,
|
|
246
|
-
:logger => logger)
|
|
247
|
-
|
|
248
244
|
Rollbar.silenced do
|
|
249
245
|
begin
|
|
250
|
-
|
|
246
|
+
if payload.is_a?(String)
|
|
247
|
+
# The final payload has already been built.
|
|
248
|
+
send_body(payload)
|
|
249
|
+
else
|
|
250
|
+
item = Item.build_with(payload,
|
|
251
|
+
:notifier => self,
|
|
252
|
+
:configuration => configuration,
|
|
253
|
+
:logger => logger)
|
|
254
|
+
|
|
255
|
+
process_item(item)
|
|
256
|
+
end
|
|
251
257
|
rescue StandardError => e
|
|
252
258
|
report_internal_error(e)
|
|
253
259
|
|
|
@@ -509,14 +515,18 @@ module Rollbar
|
|
|
509
515
|
|
|
510
516
|
## Delivery functions
|
|
511
517
|
|
|
512
|
-
def
|
|
513
|
-
|
|
514
|
-
return unless body
|
|
518
|
+
def send_using_eventmachine(body)
|
|
519
|
+
uri = URI.parse(configuration.endpoint)
|
|
515
520
|
|
|
516
|
-
headers = { 'X-Rollbar-Access-Token' =>
|
|
521
|
+
headers = { 'X-Rollbar-Access-Token' => configuration.access_token }
|
|
517
522
|
options = http_proxy_for_em(uri)
|
|
518
523
|
req = EventMachine::HttpRequest.new(uri.to_s, options).post(:body => body, :head => headers)
|
|
519
524
|
|
|
525
|
+
eventmachine_callback(req)
|
|
526
|
+
eventmachine_errback(req)
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def eventmachine_callback(req)
|
|
520
530
|
req.callback do
|
|
521
531
|
if req.response_header.status == 200
|
|
522
532
|
log_info '[Rollbar] Success'
|
|
@@ -525,7 +535,9 @@ module Rollbar
|
|
|
525
535
|
log_info "[Rollbar] Response: #{req.response}"
|
|
526
536
|
end
|
|
527
537
|
end
|
|
538
|
+
end
|
|
528
539
|
|
|
540
|
+
def eventmachine_errback(req)
|
|
529
541
|
req.errback do
|
|
530
542
|
log_warning "[Rollbar] Call to API failed, status code: #{req.response_header.status}"
|
|
531
543
|
log_info "[Rollbar] Error's response: #{req.response}"
|
|
@@ -538,14 +550,20 @@ module Rollbar
|
|
|
538
550
|
body = item.dump
|
|
539
551
|
return unless body
|
|
540
552
|
|
|
541
|
-
uri = URI.parse(configuration.endpoint)
|
|
542
|
-
|
|
543
553
|
if configuration.use_eventmachine
|
|
544
|
-
|
|
554
|
+
send_using_eventmachine(body)
|
|
545
555
|
return
|
|
546
556
|
end
|
|
547
557
|
|
|
548
|
-
|
|
558
|
+
send_body(body)
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
def send_body(body)
|
|
562
|
+
log_info '[Rollbar] Sending json'
|
|
563
|
+
|
|
564
|
+
uri = URI.parse(configuration.endpoint)
|
|
565
|
+
|
|
566
|
+
handle_response(do_post(uri, body, configuration.access_token))
|
|
549
567
|
end
|
|
550
568
|
|
|
551
569
|
def do_post(uri, body, access_token)
|
|
@@ -658,27 +676,24 @@ module Rollbar
|
|
|
658
676
|
end
|
|
659
677
|
end
|
|
660
678
|
|
|
661
|
-
def write_item(item)
|
|
662
|
-
if configuration.use_async
|
|
663
|
-
@file_semaphore.synchronize do
|
|
664
|
-
do_write_item(item)
|
|
665
|
-
end
|
|
666
|
-
else
|
|
667
|
-
do_write_item(item)
|
|
668
|
-
end
|
|
669
|
-
end
|
|
670
|
-
|
|
671
679
|
def do_write_item(item)
|
|
672
680
|
log_info '[Rollbar] Writing item to file'
|
|
673
681
|
|
|
674
682
|
body = item.dump
|
|
675
683
|
return unless body
|
|
676
684
|
|
|
685
|
+
file_name = if configuration.files_with_pid_name_enabled
|
|
686
|
+
configuration.filepath.gsub(EXTENSION_REGEXP, "_#{Process.pid}\\0")
|
|
687
|
+
else
|
|
688
|
+
configuration.filepath
|
|
689
|
+
end
|
|
690
|
+
|
|
677
691
|
begin
|
|
678
|
-
@file ||= File.open(
|
|
692
|
+
@file ||= File.open(file_name, 'a')
|
|
679
693
|
|
|
680
694
|
@file.puts(body)
|
|
681
695
|
@file.flush
|
|
696
|
+
update_file(@file, file_name)
|
|
682
697
|
|
|
683
698
|
log_info '[Rollbar] Success'
|
|
684
699
|
rescue IOError => e
|
|
@@ -686,6 +701,18 @@ module Rollbar
|
|
|
686
701
|
end
|
|
687
702
|
end
|
|
688
703
|
|
|
704
|
+
def update_file(file, file_name)
|
|
705
|
+
return unless configuration.files_processed_enabled
|
|
706
|
+
|
|
707
|
+
time_now = Time.now
|
|
708
|
+
return if configuration.files_processed_duration > time_now - file.birthtime && file.size < configuration.files_processed_size
|
|
709
|
+
|
|
710
|
+
new_file_name = file_name.gsub(EXTENSION_REGEXP, "_processed_#{time_now.to_i}\\0")
|
|
711
|
+
File.rename(file, new_file_name)
|
|
712
|
+
file.close
|
|
713
|
+
@file = File.open(file_name, 'a')
|
|
714
|
+
end
|
|
715
|
+
|
|
689
716
|
def failsafe_reason(message, exception)
|
|
690
717
|
body = ''
|
|
691
718
|
|
|
@@ -737,8 +764,11 @@ module Rollbar
|
|
|
737
764
|
end
|
|
738
765
|
|
|
739
766
|
def process_async_item(item)
|
|
767
|
+
# Send async payloads as JSON string when async_json_payload is set.
|
|
768
|
+
payload = configuration.async_json_payload ? item.dump : item.payload
|
|
769
|
+
|
|
740
770
|
configuration.async_handler ||= default_async_handler
|
|
741
|
-
configuration.async_handler.call(
|
|
771
|
+
configuration.async_handler.call(payload)
|
|
742
772
|
rescue StandardError
|
|
743
773
|
if configuration.failover_handlers.empty?
|
|
744
774
|
log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
|
|
@@ -772,5 +802,9 @@ module Rollbar
|
|
|
772
802
|
uuid_url = Util.uuid_rollbar_url(data, configuration)
|
|
773
803
|
log_info "[Rollbar] Details: #{uuid_url} (only available if report was successful)"
|
|
774
804
|
end
|
|
805
|
+
|
|
806
|
+
def via_failsafe?(item)
|
|
807
|
+
item.payload.fetch('data', {}).fetch(:failsafe, false)
|
|
808
|
+
end
|
|
775
809
|
end
|
|
776
810
|
end
|
|
@@ -14,5 +14,9 @@ module Rollbar
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
if defined?(ActiveSupport) && ActiveSupport.respond_to?(:on_load)
|
|
18
|
+
ActiveSupport.on_load(:action_mailer) do
|
|
19
|
+
# Automatically add to ActionMailer::DeliveryJob
|
|
20
|
+
ActionMailer::DeliveryJob.send(:include, Rollbar::ActiveJob) if defined?(ActionMailer::DeliveryJob)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -12,7 +12,13 @@ module Rollbar
|
|
|
12
12
|
lifecycle.around(:invoke_job, &Delayed.invoke_job_callback)
|
|
13
13
|
lifecycle.after(:failure) do |_, job, _, _|
|
|
14
14
|
data = Rollbar::Delayed.build_job_data(job)
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
# DelayedJob < 4.1 doesn't provide job#error
|
|
17
|
+
if job.class.method_defined? :error
|
|
18
|
+
::Rollbar.scope(:request => data).error(job.error, :use_exception_level_filters => true) if job.error
|
|
19
|
+
elsif job.last_error
|
|
20
|
+
::Rollbar.scope(:request => data).error("Job has failed and won't be retried anymore: " + job.last_error, :use_exception_level_filters => true)
|
|
21
|
+
end
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
@@ -247,7 +247,12 @@ module Rollbar
|
|
|
247
247
|
end
|
|
248
248
|
|
|
249
249
|
def sensitive_headers_list
|
|
250
|
-
Rollbar.configuration.scrub_headers
|
|
250
|
+
return [] unless Rollbar.configuration.scrub_headers && Rollbar.configuration.scrub_headers.is_a?(Array)
|
|
251
|
+
|
|
252
|
+
# Normalize into the expected matching format
|
|
253
|
+
Rollbar.configuration.scrub_headers.map do |header|
|
|
254
|
+
header.split(/[-_]/).map(&:capitalize).join('-').gsub(/^Http-/, '')
|
|
255
|
+
end
|
|
251
256
|
end
|
|
252
257
|
end
|
|
253
258
|
end
|
data/lib/rollbar/scrubbers.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Rollbar
|
|
|
6
6
|
class StringsStrategy
|
|
7
7
|
include ::Rollbar::Truncation::Mixin
|
|
8
8
|
|
|
9
|
-
STRING_THRESHOLDS = [1024, 512, 256].freeze
|
|
9
|
+
STRING_THRESHOLDS = [1024, 512, 256, 128].freeze
|
|
10
10
|
|
|
11
11
|
def self.call(payload)
|
|
12
12
|
new.call(payload)
|
|
@@ -29,7 +29,9 @@ module Rollbar
|
|
|
29
29
|
|
|
30
30
|
def truncate_strings_proc(threshold)
|
|
31
31
|
proc do |value|
|
|
32
|
-
|
|
32
|
+
# Rollbar::Util.truncate will operate on characters, not bytes,
|
|
33
|
+
# so use value.length, not bytesize.
|
|
34
|
+
if value.is_a?(String) && value.length > threshold
|
|
33
35
|
Rollbar::Util.truncate(value, threshold)
|
|
34
36
|
else
|
|
35
37
|
value
|
data/lib/rollbar/util.rb
CHANGED
|
@@ -2,6 +2,10 @@ require 'rollbar/util/hash'
|
|
|
2
2
|
|
|
3
3
|
module Rollbar
|
|
4
4
|
module Util # :nodoc:
|
|
5
|
+
def self.iterate_and_update_with_block(obj, &block)
|
|
6
|
+
iterate_and_update(obj, block)
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
def self.iterate_and_update(obj, block, seen = {})
|
|
6
10
|
return if obj.frozen? || seen[obj.object_id]
|
|
7
11
|
|
data/lib/rollbar/version.rb
CHANGED
data/rollbar.gemspec
CHANGED
|
@@ -13,6 +13,7 @@ Gem::Specification.new do |gem|
|
|
|
13
13
|
gem.homepage = 'https://rollbar.com'
|
|
14
14
|
gem.license = 'MIT'
|
|
15
15
|
gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
16
|
+
gem.files += ['spec/support/rollbar_api.rb'] # useful helper for app spec/tests.
|
|
16
17
|
gem.name = 'rollbar'
|
|
17
18
|
gem.require_paths = ['lib']
|
|
18
19
|
gem.required_ruby_version = '>= 1.9.3'
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'rack/request'
|
|
2
|
+
|
|
3
|
+
class RollbarAPI
|
|
4
|
+
UNAUTHORIZED_ACCESS_TOKEN = 'unauthorized'.freeze
|
|
5
|
+
|
|
6
|
+
def call(env)
|
|
7
|
+
request = Rack::Request.new(env)
|
|
8
|
+
json = JSON.parse(request.body.read)
|
|
9
|
+
|
|
10
|
+
return unauthorized unless authorized?(json, request)
|
|
11
|
+
|
|
12
|
+
return bad_request(json) unless valid_data?(json, request)
|
|
13
|
+
|
|
14
|
+
success(json, request)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
|
|
19
|
+
def authorized?(json, _request)
|
|
20
|
+
json['access_token'] != UNAUTHORIZED_ACCESS_TOKEN
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def response_headers
|
|
24
|
+
{
|
|
25
|
+
'Content-Type' => 'application/json'
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def valid_data?(json, _request)
|
|
30
|
+
!!json['access_token']
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def unauthorized
|
|
34
|
+
[401, response_headers, [unauthorized_body]]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def bad_request(_json)
|
|
38
|
+
[400, response_headers, [bad_request_body]]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def success(json, request)
|
|
42
|
+
[200, response_headers, [success_body(json, request)]]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def unauthorized_body
|
|
46
|
+
result(1, nil, 'invalid access token')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def bad_request_body
|
|
50
|
+
result(1, nil, 'bad request')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def success_body(json, _request)
|
|
54
|
+
result(0, {
|
|
55
|
+
:id => rand(1_000_000),
|
|
56
|
+
:uuid => json['data']['uuid']
|
|
57
|
+
}, nil)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def result(err, body, message)
|
|
61
|
+
{
|
|
62
|
+
:err => err,
|
|
63
|
+
:result => body,
|
|
64
|
+
:message => message
|
|
65
|
+
}.to_json
|
|
66
|
+
end
|
|
67
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rollbar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rollbar, Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Easy and powerful exception tracking for Ruby
|
|
14
14
|
email:
|
|
@@ -95,6 +95,7 @@ files:
|
|
|
95
95
|
- lib/rollbar/plugins/delayed_job.rb
|
|
96
96
|
- lib/rollbar/plugins/delayed_job/job_data.rb
|
|
97
97
|
- lib/rollbar/plugins/delayed_job/plugin.rb
|
|
98
|
+
- lib/rollbar/plugins/error_context.rb
|
|
98
99
|
- lib/rollbar/plugins/goalie.rb
|
|
99
100
|
- lib/rollbar/plugins/rack.rb
|
|
100
101
|
- lib/rollbar/plugins/rails.rb
|
|
@@ -133,6 +134,7 @@ files:
|
|
|
133
134
|
- lib/tasks/benchmark.rake
|
|
134
135
|
- lib/tasks/tasks.rake
|
|
135
136
|
- rollbar.gemspec
|
|
137
|
+
- spec/support/rollbar_api.rb
|
|
136
138
|
homepage: https://rollbar.com
|
|
137
139
|
licenses:
|
|
138
140
|
- MIT
|