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