opbeat 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/.travis.yml +19 -28
- data/.yardopts +3 -0
- data/Gemfile +4 -2
- data/HISTORY.md +3 -0
- data/LICENSE +7 -196
- data/README.md +96 -177
- data/Rakefile +19 -13
- data/gemfiles/Gemfile.base +28 -0
- data/gemfiles/Gemfile.rails-3.2.x +3 -0
- data/gemfiles/Gemfile.rails-4.0.x +3 -0
- data/gemfiles/Gemfile.rails-4.1.x +3 -0
- data/gemfiles/Gemfile.rails-4.2.x +3 -0
- data/lib/opbeat.rb +113 -93
- data/lib/opbeat/capistrano.rb +3 -4
- data/lib/opbeat/client.rb +243 -82
- data/lib/opbeat/configuration.rb +51 -64
- data/lib/opbeat/data_builders.rb +16 -0
- data/lib/opbeat/data_builders/error.rb +27 -0
- data/lib/opbeat/data_builders/transactions.rb +85 -0
- data/lib/opbeat/error.rb +1 -2
- data/lib/opbeat/error_message.rb +71 -0
- data/lib/opbeat/error_message/exception.rb +12 -0
- data/lib/opbeat/error_message/http.rb +62 -0
- data/lib/opbeat/error_message/stacktrace.rb +75 -0
- data/lib/opbeat/error_message/user.rb +23 -0
- data/lib/opbeat/filter.rb +53 -43
- data/lib/opbeat/http_client.rb +141 -0
- data/lib/opbeat/injections.rb +83 -0
- data/lib/opbeat/injections/json.rb +19 -0
- data/lib/opbeat/injections/net_http.rb +43 -0
- data/lib/opbeat/injections/redis.rb +23 -0
- data/lib/opbeat/injections/sequel.rb +32 -0
- data/lib/opbeat/injections/sinatra.rb +56 -0
- data/lib/opbeat/{capistrano → integration}/capistrano2.rb +6 -6
- data/lib/opbeat/{capistrano → integration}/capistrano3.rb +3 -3
- data/lib/opbeat/{integrations → integration}/delayed_job.rb +6 -11
- data/lib/opbeat/integration/rails/inject_exceptions_catcher.rb +23 -0
- data/lib/opbeat/integration/railtie.rb +53 -0
- data/lib/opbeat/integration/resque.rb +16 -0
- data/lib/opbeat/integration/sidekiq.rb +38 -0
- data/lib/opbeat/line_cache.rb +21 -0
- data/lib/opbeat/logging.rb +37 -0
- data/lib/opbeat/middleware.rb +59 -0
- data/lib/opbeat/normalizers.rb +65 -0
- data/lib/opbeat/normalizers/action_controller.rb +21 -0
- data/lib/opbeat/normalizers/action_view.rb +71 -0
- data/lib/opbeat/normalizers/active_record.rb +41 -0
- data/lib/opbeat/sql_summarizer.rb +27 -0
- data/lib/opbeat/subscriber.rb +80 -0
- data/lib/opbeat/tasks.rb +20 -18
- data/lib/opbeat/trace.rb +47 -0
- data/lib/opbeat/trace_helpers.rb +29 -0
- data/lib/opbeat/transaction.rb +99 -0
- data/lib/opbeat/util.rb +26 -0
- data/lib/opbeat/util/constantize.rb +54 -0
- data/lib/opbeat/util/inspector.rb +75 -0
- data/lib/opbeat/version.rb +1 -1
- data/lib/opbeat/worker.rb +55 -0
- data/opbeat.gemspec +6 -14
- data/spec/opbeat/client_spec.rb +216 -29
- data/spec/opbeat/configuration_spec.rb +34 -38
- data/spec/opbeat/data_builders/error_spec.rb +43 -0
- data/spec/opbeat/data_builders/transactions_spec.rb +51 -0
- data/spec/opbeat/error_message/exception_spec.rb +22 -0
- data/spec/opbeat/error_message/http_spec.rb +65 -0
- data/spec/opbeat/error_message/stacktrace_spec.rb +56 -0
- data/spec/opbeat/error_message/user_spec.rb +28 -0
- data/spec/opbeat/error_message_spec.rb +78 -0
- data/spec/opbeat/filter_spec.rb +21 -99
- data/spec/opbeat/http_client_spec.rb +64 -0
- data/spec/opbeat/injections/net_http_spec.rb +37 -0
- data/spec/opbeat/injections/sequel_spec.rb +33 -0
- data/spec/opbeat/injections/sinatra_spec.rb +13 -0
- data/spec/opbeat/injections_spec.rb +49 -0
- data/spec/opbeat/integration/delayed_job_spec.rb +35 -0
- data/spec/opbeat/integration/json_spec.rb +41 -0
- data/spec/opbeat/integration/rails_spec.rb +88 -0
- data/spec/opbeat/integration/redis_spec.rb +20 -0
- data/spec/opbeat/integration/resque_spec.rb +42 -0
- data/spec/opbeat/integration/sidekiq_spec.rb +40 -0
- data/spec/opbeat/integration/sinatra_spec.rb +66 -0
- data/spec/opbeat/line_cache_spec.rb +38 -0
- data/spec/opbeat/logging_spec.rb +47 -0
- data/spec/opbeat/middleware_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_controller_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_view_spec.rb +77 -0
- data/spec/opbeat/normalizers/active_record_spec.rb +70 -0
- data/spec/opbeat/normalizers_spec.rb +16 -0
- data/spec/opbeat/sql_summarizer_spec.rb +6 -0
- data/spec/opbeat/subscriber_spec.rb +83 -0
- data/spec/opbeat/trace_spec.rb +43 -0
- data/spec/opbeat/transaction_spec.rb +98 -0
- data/spec/opbeat/util/inspector_spec.rb +40 -0
- data/spec/opbeat/util_spec.rb +20 -0
- data/spec/opbeat/worker_spec.rb +54 -0
- data/spec/opbeat_spec.rb +49 -0
- data/spec/spec_helper.rb +79 -6
- metadata +89 -149
- data/Makefile +0 -3
- data/gemfiles/rails30.gemfile +0 -9
- data/gemfiles/rails31.gemfile +0 -9
- data/gemfiles/rails32.gemfile +0 -9
- data/gemfiles/rails40.gemfile +0 -9
- data/gemfiles/rails41.gemfile +0 -9
- data/gemfiles/rails42.gemfile +0 -9
- data/gemfiles/ruby192_rails31.gemfile +0 -10
- data/gemfiles/ruby192_rails32.gemfile +0 -10
- data/gemfiles/sidekiq31.gemfile +0 -11
- data/lib/opbeat/better_attr_accessor.rb +0 -44
- data/lib/opbeat/event.rb +0 -223
- data/lib/opbeat/integrations/resque.rb +0 -22
- data/lib/opbeat/integrations/sidekiq.rb +0 -32
- data/lib/opbeat/interfaces.rb +0 -35
- data/lib/opbeat/interfaces/exception.rb +0 -16
- data/lib/opbeat/interfaces/http.rb +0 -57
- data/lib/opbeat/interfaces/message.rb +0 -19
- data/lib/opbeat/interfaces/stack_trace.rb +0 -50
- data/lib/opbeat/linecache.rb +0 -25
- data/lib/opbeat/logger.rb +0 -21
- data/lib/opbeat/rack.rb +0 -46
- data/lib/opbeat/rails/middleware/debug_exceptions_catcher.rb +0 -22
- data/lib/opbeat/railtie.rb +0 -26
- data/spec/opbeat/better_attr_accessor_spec.rb +0 -99
- data/spec/opbeat/event_spec.rb +0 -138
- data/spec/opbeat/integrations/delayed_job_spec.rb +0 -38
- data/spec/opbeat/logger_spec.rb +0 -55
- data/spec/opbeat/opbeat_spec.rb +0 -64
- data/spec/opbeat/rack_spec.rb +0 -117
|
@@ -1,50 +1,46 @@
|
|
|
1
|
-
require
|
|
2
|
-
require 'opbeat'
|
|
1
|
+
require 'spec_helper'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# Make sure we reset the env in case something leaks in
|
|
7
|
-
ENV.delete('OPBEAT_ORGANIZATION_ID')
|
|
8
|
-
ENV.delete('OPBEAT_APP_ID')
|
|
9
|
-
ENV.delete('OPBEAT_SECRET_TOKEN')
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
shared_examples 'a complete configuration' do
|
|
13
|
-
it 'should have a server' do
|
|
14
|
-
expect(subject[:server]).to eq('http://opbeat.localdomain/opbeat')
|
|
15
|
-
end
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe Configuration do
|
|
16
5
|
|
|
17
|
-
it
|
|
18
|
-
|
|
6
|
+
it "has defaults" do
|
|
7
|
+
conf = Configuration.new
|
|
8
|
+
expect(conf.timeout).to be 100
|
|
19
9
|
end
|
|
20
10
|
|
|
21
|
-
it
|
|
22
|
-
|
|
11
|
+
it "can initialize with a hash" do
|
|
12
|
+
conf = Configuration.new timeout: 1000
|
|
13
|
+
expect(conf.timeout).to be 1000
|
|
23
14
|
end
|
|
24
15
|
|
|
25
|
-
it
|
|
26
|
-
|
|
16
|
+
it "yields itself to a given block" do
|
|
17
|
+
conf = Configuration.new do |c|
|
|
18
|
+
c.timeout = 1000
|
|
19
|
+
end
|
|
20
|
+
expect(conf.timeout).to be 1000
|
|
27
21
|
end
|
|
28
|
-
end
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
describe "#validate" do
|
|
24
|
+
let(:auth_opts) { { app_id: 'x', organization_id: 'y', secret_token: 'z' } }
|
|
25
|
+
it "is true when all auth options are set" do
|
|
26
|
+
expect(Configuration.new(auth_opts).validate!).to be true
|
|
27
|
+
end
|
|
28
|
+
it "is true" do
|
|
29
|
+
expect(Configuration.new(auth_opts).validate!).to be true
|
|
30
|
+
end
|
|
31
|
+
it "needs an app_id" do
|
|
32
|
+
auth_opts.delete(:app_id)
|
|
33
|
+
expect(Configuration.new(auth_opts).validate!).to be false
|
|
34
|
+
end
|
|
35
|
+
it "needs an organization_id" do
|
|
36
|
+
auth_opts.delete(:organization_id)
|
|
37
|
+
expect(Configuration.new(auth_opts).validate!).to be false
|
|
38
|
+
end
|
|
39
|
+
it "needs a secret token" do
|
|
40
|
+
auth_opts.delete(:secret_token)
|
|
41
|
+
expect(Configuration.new(auth_opts).validate!).to be false
|
|
42
|
+
end
|
|
36
43
|
end
|
|
37
|
-
it_should_behave_like 'a complete configuration'
|
|
38
|
-
end
|
|
39
44
|
|
|
40
|
-
context 'being initialized with an environment variable' do
|
|
41
|
-
subject do
|
|
42
|
-
ENV['OPBEAT_ORGANIZATION_ID'] = '42'
|
|
43
|
-
ENV['OPBEAT_APP_ID'] = '43'
|
|
44
|
-
ENV['OPBEAT_SECRET_TOKEN'] = '67890'
|
|
45
|
-
ENV['OPBEAT_SERVER'] = 'http://opbeat.localdomain/opbeat'
|
|
46
|
-
Opbeat::Configuration.new
|
|
47
|
-
end
|
|
48
|
-
it_should_behave_like 'a complete configuration'
|
|
49
45
|
end
|
|
50
46
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
module DataBuilders
|
|
5
|
+
RSpec.describe Error do
|
|
6
|
+
|
|
7
|
+
let(:config) { Configuration.new }
|
|
8
|
+
|
|
9
|
+
subject do
|
|
10
|
+
Error.new config
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def real_exception
|
|
14
|
+
1 / 0
|
|
15
|
+
rescue => e
|
|
16
|
+
e
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#build" do
|
|
20
|
+
it "builds an error dict from an exception" do
|
|
21
|
+
error_message = ErrorMessage.from_exception config, real_exception
|
|
22
|
+
expect(subject.build error_message).to match({
|
|
23
|
+
message: String,
|
|
24
|
+
timestamp: Integer,
|
|
25
|
+
level: :error,
|
|
26
|
+
logger: 'root',
|
|
27
|
+
culprit: "opbeat/data_builders/error_spec.rb:14:in `/'",
|
|
28
|
+
machine: nil,
|
|
29
|
+
extra: nil,
|
|
30
|
+
param_message: nil,
|
|
31
|
+
exception: Hash,
|
|
32
|
+
stacktrace: Hash
|
|
33
|
+
})
|
|
34
|
+
end
|
|
35
|
+
it "converts to json just fine" do
|
|
36
|
+
error_message = ErrorMessage.from_exception config, real_exception
|
|
37
|
+
expect { JSON.dump subject.build(error_message) }.to_not raise_error
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
module DataBuilders
|
|
5
|
+
RSpec.describe Transactions, mock_time: true, start_without_worker: true do
|
|
6
|
+
|
|
7
|
+
describe "#build" do
|
|
8
|
+
subject do
|
|
9
|
+
transaction1 = Transaction.new(nil, 'endpoint', 'special.kind')
|
|
10
|
+
transaction2 = Transaction.new(nil, 'endpoint', 'special.kind')
|
|
11
|
+
transaction3 = Transaction.new(nil, 'endpoint', 'special.kind')
|
|
12
|
+
travel 100
|
|
13
|
+
transaction1.done 200
|
|
14
|
+
transaction2.done 200
|
|
15
|
+
transaction3.done 500
|
|
16
|
+
|
|
17
|
+
transaction4 = Opbeat.transaction('endpoint', 'special.kind') do
|
|
18
|
+
travel 100
|
|
19
|
+
Opbeat.trace 'things' do
|
|
20
|
+
travel 100
|
|
21
|
+
end
|
|
22
|
+
Opbeat.trace 'things' do
|
|
23
|
+
travel 100
|
|
24
|
+
end
|
|
25
|
+
end.done(500)
|
|
26
|
+
|
|
27
|
+
transactions = [transaction1, transaction2, transaction3, transaction4]
|
|
28
|
+
|
|
29
|
+
DataBuilders::Transactions.new(Configuration.new).build transactions
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "combines transactions by result" do
|
|
33
|
+
data = subject
|
|
34
|
+
expect(data[:transactions].length).to be 2
|
|
35
|
+
expect(data[:transactions].map { |t| t[:result] }).to eq [200, 500]
|
|
36
|
+
expect(data[:transactions].map { |t| t[:durations] }.flatten).to eq [100.0, 100.0, 100.0, 300.0]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "combines traces" do
|
|
40
|
+
data = subject
|
|
41
|
+
expect(data[:traces].length). to be 2
|
|
42
|
+
expect(data[:traces].first[:durations].length).to be 4
|
|
43
|
+
expect(data[:traces].last[:durations].flatten).to eq [100.0, 300.0, 100.0, 300.0]
|
|
44
|
+
expect(data[:traces].last[:start_time].round).to eq 150
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe ErrorMessage::Exception do
|
|
5
|
+
|
|
6
|
+
class ::Thing
|
|
7
|
+
class Error < StandardError
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe ".from" do
|
|
12
|
+
it "initializes an object from an actual exception" do
|
|
13
|
+
exception = Thing::Error.new "BOOM"
|
|
14
|
+
obj = ErrorMessage::Exception.from(exception)
|
|
15
|
+
expect(obj.type).to eq "Thing::Error"
|
|
16
|
+
expect(obj.value).to eq "BOOM"
|
|
17
|
+
expect(obj.module).to eq "Thing"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe ErrorMessage::HTTP do
|
|
5
|
+
|
|
6
|
+
describe ".from_rack_env" do
|
|
7
|
+
let(:config) { Configuration.new }
|
|
8
|
+
|
|
9
|
+
it "initializes with a rack env" do
|
|
10
|
+
filter = Filter.new config
|
|
11
|
+
|
|
12
|
+
env = Rack::MockRequest.env_for '/nested/path?a=1&password=SECRET', {
|
|
13
|
+
'HTTP_COOKIE' => 'user_id=1',
|
|
14
|
+
'REMOTE_ADDR' => '1.2.3.4',
|
|
15
|
+
'HTTP_USER_AGENT' => 'test-agent 1.2/3',
|
|
16
|
+
'HTTP_FOO' => 'bar'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
http = ErrorMessage::HTTP.from_rack_env env, filter: filter
|
|
20
|
+
|
|
21
|
+
expect(http.url).to eq 'http://example.org/nested/path'
|
|
22
|
+
expect(http.method).to eq 'GET'
|
|
23
|
+
expect(http.query_string).to eq 'a=1&password=[FILTERED]'
|
|
24
|
+
expect(http.cookies).to eq('user_id=1')
|
|
25
|
+
expect(http.remote_host).to eq '1.2.3.4'
|
|
26
|
+
expect(http.http_host).to eq 'example.org:80'
|
|
27
|
+
expect(http.user_agent).to eq 'test-agent 1.2/3'
|
|
28
|
+
|
|
29
|
+
expect(http.headers).to eq({
|
|
30
|
+
'Cookie' => 'user_id=1',
|
|
31
|
+
'User-Agent' => 'test-agent 1.2/3',
|
|
32
|
+
'Foo' => 'bar'
|
|
33
|
+
})
|
|
34
|
+
expect(http.env).to eq(env.select do |k,v|
|
|
35
|
+
!k.match(/(^HTTP_|[a-z])/) # starting with HTTP_ or lower case
|
|
36
|
+
end)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "adds form data" do
|
|
40
|
+
env = Rack::MockRequest.env_for '/', {
|
|
41
|
+
'REQUEST_METHOD' => 'POST',
|
|
42
|
+
input: 'thing=hotdog&accept=1'
|
|
43
|
+
}
|
|
44
|
+
http = ErrorMessage::HTTP.from_rack_env env
|
|
45
|
+
|
|
46
|
+
expect(http.data).to eq({
|
|
47
|
+
'thing' => 'hotdog',
|
|
48
|
+
'accept' => '1'
|
|
49
|
+
})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "adds body" do
|
|
53
|
+
env = Rack::MockRequest.env_for '/', {
|
|
54
|
+
'REQUEST_METHOD' => 'POST',
|
|
55
|
+
'CONTENT_TYPE' => 'application/json',
|
|
56
|
+
input: { thing: 'hotdog' }.to_json
|
|
57
|
+
}
|
|
58
|
+
http = ErrorMessage::HTTP.from_rack_env env
|
|
59
|
+
|
|
60
|
+
expect(http.data).to eq('{"thing":"hotdog"}')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe ErrorMessage::Stacktrace do
|
|
5
|
+
|
|
6
|
+
def real_exception
|
|
7
|
+
1 / 0
|
|
8
|
+
rescue => e
|
|
9
|
+
e
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:config) { Configuration.new }
|
|
13
|
+
let(:exception) { real_exception }
|
|
14
|
+
|
|
15
|
+
describe ".from" do
|
|
16
|
+
it "initializes from an exception" do
|
|
17
|
+
stacktrace = ErrorMessage::Stacktrace.from config, exception
|
|
18
|
+
expect(stacktrace.frames).to_not be_empty
|
|
19
|
+
|
|
20
|
+
# so meta
|
|
21
|
+
last_frame = stacktrace.frames.first
|
|
22
|
+
expect(last_frame.filename).to eq "opbeat/error_message/stacktrace_spec.rb"
|
|
23
|
+
expect(last_frame.lineno).to be 7
|
|
24
|
+
expect(last_frame.abs_path).to_not be_nil
|
|
25
|
+
expect(last_frame.function).to eq "/"
|
|
26
|
+
expect(last_frame.vars).to be_nil
|
|
27
|
+
|
|
28
|
+
expect(last_frame.pre_context.last).to match(/def real_exception/)
|
|
29
|
+
expect(last_frame.context_line).to match(/1 \/ 0/)
|
|
30
|
+
expect(last_frame.post_context.first).to match(/rescue/)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when context lines are off" do
|
|
34
|
+
let(:config) { Configuration.new context_lines: nil }
|
|
35
|
+
it "initializes too" do
|
|
36
|
+
stacktrace = ErrorMessage::Stacktrace.from config, exception
|
|
37
|
+
expect(stacktrace.frames).to_not be_empty
|
|
38
|
+
|
|
39
|
+
last_frame = stacktrace.frames.last
|
|
40
|
+
expect(last_frame.pre_context).to be_nil
|
|
41
|
+
expect(last_frame.context_line).to be_nil
|
|
42
|
+
expect(last_frame.post_context).to be_nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "#to_h" do
|
|
48
|
+
it "is a hash" do
|
|
49
|
+
hsh = ErrorMessage::Stacktrace.from(config, exception).to_h
|
|
50
|
+
expect(hsh).to be_a Hash
|
|
51
|
+
expect(hsh.keys).to eq [:frames]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe ErrorMessage::User do
|
|
5
|
+
|
|
6
|
+
let(:config) { Configuration.new }
|
|
7
|
+
|
|
8
|
+
class Controller
|
|
9
|
+
def current_user
|
|
10
|
+
Struct.new(:id, :email, :username).new(1, 'john@example.com', 'leroy')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe ".from_rack_env" do
|
|
15
|
+
it "initializes from rack env" do
|
|
16
|
+
env = Rack::MockRequest.env_for '/', {
|
|
17
|
+
'action_controller.instance' => Controller.new
|
|
18
|
+
}
|
|
19
|
+
user = ErrorMessage::User.from_rack_env config, env
|
|
20
|
+
|
|
21
|
+
expect(user.id).to be 1
|
|
22
|
+
expect(user.email).to eq 'john@example.com'
|
|
23
|
+
expect(user.username).to eq 'leroy'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe ErrorMessage do
|
|
5
|
+
|
|
6
|
+
let(:config) { Configuration.new }
|
|
7
|
+
|
|
8
|
+
def real_exception
|
|
9
|
+
1 / 0
|
|
10
|
+
rescue => e
|
|
11
|
+
e
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "#initialize" do
|
|
15
|
+
it "sets attrs by hash" do
|
|
16
|
+
error = ErrorMessage.new config, 'Error', level: :warn
|
|
17
|
+
expect(error.level).to eq :warn
|
|
18
|
+
end
|
|
19
|
+
it "yields itself" do
|
|
20
|
+
error = ErrorMessage.new(config, 'Error') { |m| m.level = :warn }
|
|
21
|
+
expect(error.level).to eq :warn
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe ".from_exception" do
|
|
26
|
+
it "initializes from an exception" do
|
|
27
|
+
error = ErrorMessage.from_exception config, real_exception
|
|
28
|
+
expect(error.message).to eq 'ZeroDivisionError: divided by 0'
|
|
29
|
+
expect(error.level).to eq :error
|
|
30
|
+
|
|
31
|
+
expect(error.exception.type).to eq 'ZeroDivisionError'
|
|
32
|
+
expect(error.exception.value).to eq 'divided by 0'
|
|
33
|
+
expect(error.exception.module).to eq ''
|
|
34
|
+
|
|
35
|
+
expect(error.stacktrace.frames.length).to_not be 0
|
|
36
|
+
expect(error.stacktrace.frames.map(&:class).uniq)
|
|
37
|
+
.to eq [ErrorMessage::Stacktrace::Frame]
|
|
38
|
+
expect(error.culprit).to eq "opbeat/error_message_spec.rb:9:in `/'"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "skips excluded exceptions" do
|
|
42
|
+
class ::SleepDeprivationError < StandardError; end
|
|
43
|
+
exception = SleepDeprivationError.new('so tired')
|
|
44
|
+
config.excluded_exceptions += %w{SleepDeprivationError}
|
|
45
|
+
|
|
46
|
+
error = ErrorMessage.from_exception config, exception
|
|
47
|
+
expect(error).to be_nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "with a rack env" do
|
|
51
|
+
it "adds rack env to message" do
|
|
52
|
+
env = Rack::MockRequest.env_for '/'
|
|
53
|
+
error = ErrorMessage.from_exception config, real_exception, rack_env: env
|
|
54
|
+
|
|
55
|
+
expect(error.http).to be_a(ErrorMessage::HTTP)
|
|
56
|
+
expect(error.http.url).to eq 'http://example.org/'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class DummyController
|
|
60
|
+
def current_user
|
|
61
|
+
Struct.new(:id, :email, :username).new(1, 'john@example.com', 'leroy')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "adds user from controller" do
|
|
66
|
+
env = Rack::MockRequest.env_for '/', {
|
|
67
|
+
'action_controller.instance' => DummyController.new
|
|
68
|
+
}
|
|
69
|
+
error = ErrorMessage.from_exception config, real_exception, rack_env: env
|
|
70
|
+
|
|
71
|
+
expect(error.user).to be_a(ErrorMessage::User)
|
|
72
|
+
expect(error.user.id).to be 1
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
data/spec/opbeat/filter_spec.rb
CHANGED
|
@@ -1,101 +1,23 @@
|
|
|
1
|
-
require
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
describe
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
expect(vars["foo"]).to eq("bar")
|
|
23
|
-
expect(vars["password"]).to eq(Opbeat::Filter::MASK)
|
|
24
|
-
expect(vars["the_secret"]).to eq(Opbeat::Filter::MASK)
|
|
25
|
-
expect(vars["a_password_here"]).to eq(Opbeat::Filter::MASK)
|
|
26
|
-
expect(vars["mypasswd"]).to eq(Opbeat::Filter::MASK)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'should filter http query_string by default' do
|
|
30
|
-
data = {
|
|
31
|
-
'http' => {
|
|
32
|
-
'query_string' => 'foo=bar&password=secret'
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
filter = Opbeat::Filter.new
|
|
37
|
-
result = filter.process_event_hash(data)
|
|
38
|
-
|
|
39
|
-
expect(result["http"]["query_string"]).to eq('foo=bar&password=' + Opbeat::Filter::MASK)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'should filter http cookies by default' do
|
|
43
|
-
data = {
|
|
44
|
-
'http' => {
|
|
45
|
-
'cookies' => 'foo=bar;password=secret'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
filter = Opbeat::Filter.new
|
|
50
|
-
result = filter.process_event_hash(data)
|
|
51
|
-
|
|
52
|
-
expect(result["http"]["cookies"]).to eq('foo=bar;password=' + Opbeat::Filter::MASK)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it 'should not filter env, extra or headers' do
|
|
56
|
-
data = {
|
|
57
|
-
'http' => {
|
|
58
|
-
'env' => { 'password' => 'hello' },
|
|
59
|
-
'extra' => { 'password' => 'hello' },
|
|
60
|
-
'headers' => { 'password' => 'hello' }
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
filter = Opbeat::Filter.new
|
|
65
|
-
result = filter.process_event_hash(data)
|
|
66
|
-
|
|
67
|
-
expect(result).to eq(data)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it 'should be configurable' do
|
|
71
|
-
data = {
|
|
72
|
-
'http' => {
|
|
73
|
-
'data' => {
|
|
74
|
-
'foo' => 'secret',
|
|
75
|
-
'bar' => 'secret',
|
|
76
|
-
'-baz-' => 'secret',
|
|
77
|
-
'password' => 'public',
|
|
78
|
-
'the_secret' => 'public',
|
|
79
|
-
'a_password_here' => 'public',
|
|
80
|
-
'mypasswd' => 'public'
|
|
81
|
-
},
|
|
82
|
-
'query_string' => 'foo=secret&password=public',
|
|
83
|
-
'cookies' => 'foo=secret;password=public'
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
filter = Opbeat::Filter.new [:foo, 'bar', /baz/]
|
|
88
|
-
result = filter.process_event_hash(data)
|
|
89
|
-
|
|
90
|
-
vars = result["http"]["data"]
|
|
91
|
-
expect(vars["foo"]).to eq(Opbeat::Filter::MASK)
|
|
92
|
-
expect(vars["bar"]).to eq(Opbeat::Filter::MASK)
|
|
93
|
-
expect(vars["-baz-"]).to eq(Opbeat::Filter::MASK)
|
|
94
|
-
expect(vars["password"]).to eq("public")
|
|
95
|
-
expect(vars["the_secret"]).to eq("public")
|
|
96
|
-
expect(vars["a_password_here"]).to eq("public")
|
|
97
|
-
expect(vars["mypasswd"]).to eq("public")
|
|
98
|
-
expect(result["http"]["query_string"]).to eq('foo=' + Opbeat::Filter::MASK + '&password=public')
|
|
99
|
-
expect(result["http"]["cookies"]).to eq('foo=' + Opbeat::Filter::MASK + ';password=public')
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Opbeat
|
|
4
|
+
RSpec.describe Filter do
|
|
5
|
+
let(:config) { Configuration.new filter_parameters: [/password/, 'passwd'] }
|
|
6
|
+
|
|
7
|
+
subject do
|
|
8
|
+
Filter.new config
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "#apply" do
|
|
12
|
+
it "filters a string" do
|
|
13
|
+
filtered = subject.apply "password=SECRET&foo=bar"
|
|
14
|
+
expect(filtered).to eq 'password=[FILTERED]&foo=bar'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "filters a hash" do
|
|
18
|
+
filtered = subject.apply({ passwd: 'SECRET' })
|
|
19
|
+
expect(filtered).to eq({ passwd: '[FILTERED]' })
|
|
20
|
+
end
|
|
21
|
+
end
|
|
100
22
|
end
|
|
101
23
|
end
|