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
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
module Opbeat
|
5
|
+
RSpec.describe "sinatra integration" do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
def config
|
9
|
+
@config ||= Opbeat::Configuration.new do |c|
|
10
|
+
c.app_id = 'X'
|
11
|
+
c.organization_id = 'Y'
|
12
|
+
c.secret_token = 'Z'
|
13
|
+
c.disable_worker = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
around do |example|
|
18
|
+
Opbeat.start! config
|
19
|
+
example.call
|
20
|
+
Opbeat.stop!
|
21
|
+
end
|
22
|
+
|
23
|
+
class TestApp < ::Sinatra::Base
|
24
|
+
disable :show_exceptions
|
25
|
+
use Opbeat::Middleware
|
26
|
+
|
27
|
+
get '/' do
|
28
|
+
erb "I am an inline template!"
|
29
|
+
end
|
30
|
+
|
31
|
+
template :tmpl do
|
32
|
+
"I am a template!"
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/tmpl' do
|
36
|
+
erb :tmpl
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def app
|
41
|
+
TestApp
|
42
|
+
end
|
43
|
+
|
44
|
+
it "wraps routes in transactions" do
|
45
|
+
get '/'
|
46
|
+
|
47
|
+
transaction = Opbeat::Client.inst.pending_transactions.last
|
48
|
+
expect(transaction.endpoint).to eq 'GET /'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "traces templates" do
|
52
|
+
get '/tmpl'
|
53
|
+
|
54
|
+
transaction = Opbeat::Client.inst.pending_transactions.last
|
55
|
+
expect(transaction.traces.last.signature).to eq 'tmpl'
|
56
|
+
end
|
57
|
+
|
58
|
+
it "traces inline templates" do
|
59
|
+
get '/'
|
60
|
+
|
61
|
+
transaction = Opbeat::Client.inst.pending_transactions.last
|
62
|
+
expect(transaction.traces.last.signature).to eq 'Inline erb'
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe LineCache do
|
5
|
+
|
6
|
+
let(:path) { "some/file.rb" }
|
7
|
+
let(:lines) { %w{these are the lines} }
|
8
|
+
|
9
|
+
describe ".all" do
|
10
|
+
it "returns the lines of the file at path" do
|
11
|
+
allow(File).to receive(:readlines) { lines }
|
12
|
+
expect(LineCache.all path).to eq lines
|
13
|
+
end
|
14
|
+
it "rescues any exception" do
|
15
|
+
allow(LineCache::CACHE).to receive(:[]) { nil }
|
16
|
+
allow(File).to receive(:readlines).and_raise "BOOM"
|
17
|
+
expect(LineCache.all path).to eq []
|
18
|
+
end
|
19
|
+
it "caches results" do
|
20
|
+
allow(File).to receive(:readlines) { lines }.once
|
21
|
+
LineCache.all path
|
22
|
+
LineCache.all path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".find" do
|
27
|
+
it "returns one line of the file at path" do
|
28
|
+
allow(File).to receive(:readlines) { lines }.once
|
29
|
+
allow(LineCache::CACHE).to receive(:[]) { nil }
|
30
|
+
expect(LineCache.find path, 2).to eq "are"
|
31
|
+
end
|
32
|
+
it "is nil when less than 1" do
|
33
|
+
expect(LineCache.find path, 0).to be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'opbeat'
|
3
|
+
|
4
|
+
module Opbeat
|
5
|
+
describe Logging do
|
6
|
+
class FakeLogger
|
7
|
+
def method_missing name, *args, &block
|
8
|
+
@calls ||= []
|
9
|
+
@calls << [name, *args]
|
10
|
+
end
|
11
|
+
attr_reader :calls
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:logger) { FakeLogger.new }
|
15
|
+
let(:config) { Struct.new(:logger).new(logger) }
|
16
|
+
|
17
|
+
before :each do
|
18
|
+
extend Logging
|
19
|
+
end
|
20
|
+
|
21
|
+
%w{fatal error info debug warn}.map(&:to_sym).each do |level|
|
22
|
+
it "does #{level} with args" do
|
23
|
+
self.send level, "msg"
|
24
|
+
expect(logger.calls.last).to eq [level, "** [Opbeat] msg"]
|
25
|
+
end
|
26
|
+
it "does #{level} with block" do
|
27
|
+
blck = lambda { "msg" }
|
28
|
+
self.send level, &blck
|
29
|
+
expect(logger.calls.last).to eq [level, "** [Opbeat] msg"]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'without a backend logger' do
|
34
|
+
before do
|
35
|
+
config.logger = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should not error' do
|
39
|
+
fatal 'fatalmsg'
|
40
|
+
error 'errormsg'
|
41
|
+
warn 'warnmsg'
|
42
|
+
info 'infomsg'
|
43
|
+
debug 'debugmsg'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'opbeat'
|
3
|
+
|
4
|
+
module Opbeat
|
5
|
+
describe Middleware, start_without_worker: true do
|
6
|
+
|
7
|
+
it "surrounds the request in a transaction" do
|
8
|
+
app = Middleware.new(lambda do |env|
|
9
|
+
[200, {}, ['']]
|
10
|
+
end)
|
11
|
+
status, _, body = app.call(Rack::MockRequest.env_for '/')
|
12
|
+
body.close
|
13
|
+
|
14
|
+
expect(status).to eq 200
|
15
|
+
expect(Opbeat::Client.inst.pending_transactions.length).to be 1
|
16
|
+
expect(Opbeat::Client.inst.current_transaction).to be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "submits on exceptions" do
|
20
|
+
app = Middleware.new(lambda do |env|
|
21
|
+
raise Exception, "BOOM"
|
22
|
+
end)
|
23
|
+
|
24
|
+
expect { app.call(Rack::MockRequest.env_for '/') }.to raise_error(Exception)
|
25
|
+
expect(Opbeat::Client.inst.queue.length).to be 1
|
26
|
+
expect(Opbeat::Client.inst.current_transaction).to be_nil
|
27
|
+
|
28
|
+
expect(Opbeat::Client.inst.queue.length).to be 1
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Normalizers::ActionController do
|
5
|
+
|
6
|
+
let(:config) { Configuration.new }
|
7
|
+
let(:normalizers) { Normalizers.build config }
|
8
|
+
|
9
|
+
describe Normalizers::ActionController::ProcessAction do
|
10
|
+
subject do
|
11
|
+
normalizers.normalizer_for('process_action.action_controller')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "registers" do
|
15
|
+
expect(subject).to be_a Normalizers::ActionController::ProcessAction
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#normalize" do
|
19
|
+
it "normalizes input and updates transaction" do
|
20
|
+
transaction = Struct.new(:endpoint).new(nil)
|
21
|
+
|
22
|
+
result = subject.normalize(transaction, 'process_action.action_controller', {
|
23
|
+
controller: 'SomeController', action: 'index'
|
24
|
+
})
|
25
|
+
|
26
|
+
expect(transaction.endpoint).to eq 'SomeController#index'
|
27
|
+
expect(result).to match ['SomeController#index', 'app.controller.action', nil]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Normalizers::ActionView do
|
5
|
+
|
6
|
+
let(:config) { Configuration.new view_paths: ['/var/www/app/views'] }
|
7
|
+
let(:normalizers) { Normalizers.build config }
|
8
|
+
|
9
|
+
shared_examples_for :a_render_normalizer do |key|
|
10
|
+
describe "#normalize" do
|
11
|
+
it "normalizes an unknown template" do
|
12
|
+
expect(normalize key, {}).to eq ['Unknown template', described_class.const_get(:KIND), nil]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns a local template" do
|
16
|
+
path = 'somewhere/local.html.erb'
|
17
|
+
expect(normalize(key, identifier: path)[0]).to eq 'somewhere/local.html.erb'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "looks up a template in config.view_paths" do
|
21
|
+
path = '/var/www/app/views/users/index.html.erb'
|
22
|
+
expect(normalize(key, identifier: path)[0]).to eq 'users/index.html.erb'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "truncates gem path" do
|
26
|
+
path = Gem.path[0] + '/some/template.html.erb'
|
27
|
+
expect(normalize(key, identifier: path)[0]).to eq '$GEM_PATH/some/template.html.erb'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns absolute if not found in known dirs" do
|
31
|
+
path = '/somewhere/else.html.erb'
|
32
|
+
expect(normalize(key, identifier: path)[0]).to eq 'Absolute path'
|
33
|
+
end
|
34
|
+
|
35
|
+
def normalize key, payload
|
36
|
+
subject.normalize nil, key, payload
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Normalizers::ActionView::RenderTemplate do
|
42
|
+
subject do
|
43
|
+
normalizers.normalizer_for 'render_template.action_view'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "registers" do
|
47
|
+
expect(subject).to be_a Normalizers::ActionView::RenderTemplate
|
48
|
+
end
|
49
|
+
|
50
|
+
it_should_behave_like :a_render_normalizer
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Normalizers::ActionView::RenderPartial do
|
54
|
+
subject do
|
55
|
+
normalizers.normalizer_for 'render_partial.action_view'
|
56
|
+
end
|
57
|
+
|
58
|
+
it "registers" do
|
59
|
+
expect(subject).to be_a Normalizers::ActionView::RenderPartial
|
60
|
+
end
|
61
|
+
|
62
|
+
it_should_behave_like :a_render_normalizer
|
63
|
+
end
|
64
|
+
|
65
|
+
describe Normalizers::ActionView::RenderCollection do
|
66
|
+
subject do
|
67
|
+
normalizers.normalizer_for 'render_collection.action_view'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "registers" do
|
71
|
+
expect(subject).to be_a Normalizers::ActionView::RenderCollection
|
72
|
+
end
|
73
|
+
|
74
|
+
it_should_behave_like :a_render_normalizer
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Normalizers::ActionView do
|
5
|
+
|
6
|
+
let(:config) { Configuration.new view_paths: ['/var/www/app/views'] }
|
7
|
+
let(:normalizers) { Normalizers.build config }
|
8
|
+
|
9
|
+
describe Normalizers::ActiveRecord::SQL do
|
10
|
+
subject { normalizers.normalizer_for 'sql.active_record' }
|
11
|
+
|
12
|
+
it "registers" do
|
13
|
+
expect(subject).to be_a Normalizers::ActiveRecord::SQL
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#normalize" do
|
17
|
+
it "skips SCHEMA queries" do
|
18
|
+
expect(normalize(name: 'SCHEMA')).to be :skip
|
19
|
+
end
|
20
|
+
|
21
|
+
it "skips CACHE queries" do
|
22
|
+
expect(normalize(name: 'CACHE', sql: 'select * from tables')).to be :skip
|
23
|
+
end
|
24
|
+
|
25
|
+
it "normalizes SELECT queries" do
|
26
|
+
sql = 'SELECT "hotdogs".* FROM "hotdogs" WHERE "hotdogs"."topping" = $1 LIMIT 1'
|
27
|
+
signature, kind, extra = normalize(name: 'Hotdogs load', sql: sql)
|
28
|
+
expect(signature).to eq 'SELECT FROM "hotdogs"'
|
29
|
+
expect(kind).to eq 'db.unknown.sql'
|
30
|
+
expect(extra).to eq sql: sql
|
31
|
+
end
|
32
|
+
|
33
|
+
it "normalizes INSERT queries" do
|
34
|
+
sig, _, _ = normalize(name: 'Hotdogs create',
|
35
|
+
sql: 'insert into "hotdogs" (kind, topping) values ($1, $2)')
|
36
|
+
expect(sig).to eq 'INSERT INTO "hotdogs"'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "normalizes UPDATE queries" do
|
40
|
+
sig, _, _ = normalize(name: 'Hotdogs update',
|
41
|
+
sql: 'update "hotdogs" (topping) values ($1) where id=1')
|
42
|
+
expect(sig).to eq 'UPDATE "hotdogs"'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "normalizes DELETE queries" do
|
46
|
+
sig, _, _ = normalize(name: 'Hotdogs delete',
|
47
|
+
sql: 'delete from "hotdogs" where id=1')
|
48
|
+
expect(sig).to eq 'DELETE FROM "hotdogs"'
|
49
|
+
end
|
50
|
+
|
51
|
+
context "inside AR" do
|
52
|
+
before do
|
53
|
+
module ::ActiveRecord; class Base; end; end unless defined? ActiveRecord
|
54
|
+
allow(::ActiveRecord::Base).to receive(:connection) { double(adapter_name: 'MySQL') }
|
55
|
+
end
|
56
|
+
it "knows the ar adapter" do
|
57
|
+
_, kind, _ = normalize(name: 'Hotdogs load',
|
58
|
+
sql: 'select * from "hotdogs"')
|
59
|
+
expect(kind).to eq 'db.mysql.sql'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def normalize payload
|
64
|
+
subject.normalize nil, 'sql.active_record', payload
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Normalizers do
|
5
|
+
|
6
|
+
let(:config) { Configuration.new }
|
7
|
+
|
8
|
+
describe Normalizers::Default do
|
9
|
+
it "skips" do
|
10
|
+
normalizer = Normalizers::Default.new config
|
11
|
+
expect(normalizer.normalize 1, 2, 3).to eq :skip
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Subscriber do
|
5
|
+
|
6
|
+
let(:config) { Configuration.new }
|
7
|
+
let(:client) { Client.new config }
|
8
|
+
|
9
|
+
subject do
|
10
|
+
Subscriber.new config, client
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#register!" do
|
14
|
+
it "subscribes to ActiveSupport::Notifications" do
|
15
|
+
expect(ActiveSupport::Notifications).to receive(:subscribe)
|
16
|
+
subject.register!
|
17
|
+
end
|
18
|
+
it "unregisters first if already registered" do
|
19
|
+
subject.register!
|
20
|
+
expect(subject).to receive(:unregister!)
|
21
|
+
expect(ActiveSupport::Notifications).to receive(:subscribe)
|
22
|
+
subject.register!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#unregister" do
|
27
|
+
it "unsubscribes to AS::Notifications" do
|
28
|
+
expect(ActiveSupport::Notifications).to receive(:unsubscribe)
|
29
|
+
subject.register!
|
30
|
+
subject.unregister!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "ActiveSupport::Notifications API", start_without_worker: true do
|
35
|
+
let(:message_args) do
|
36
|
+
[
|
37
|
+
'process_action.action_controller',
|
38
|
+
nil,
|
39
|
+
{ controller: 'Controller', action: 'index' }
|
40
|
+
]
|
41
|
+
end
|
42
|
+
describe "#start" do
|
43
|
+
it "adds a new notification to current transaction" do
|
44
|
+
transaction = Opbeat.transaction 'Test'
|
45
|
+
|
46
|
+
expect do
|
47
|
+
subject.start(*message_args)
|
48
|
+
end.to change(transaction.notifications, :length).by 1
|
49
|
+
|
50
|
+
transaction.release
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#finish" do
|
55
|
+
it "adds a trace to current transaction" do
|
56
|
+
transaction = Opbeat.transaction 'Test'
|
57
|
+
|
58
|
+
expect do
|
59
|
+
subject.start(*message_args)
|
60
|
+
subject.finish(*message_args)
|
61
|
+
end.to change(transaction.traces, :length).by 1
|
62
|
+
|
63
|
+
transaction.release
|
64
|
+
end
|
65
|
+
it "adds a stack of parents", mock_time: true do
|
66
|
+
transaction = Opbeat.transaction 'Rack' do
|
67
|
+
subject.start(*message_args)
|
68
|
+
travel 100
|
69
|
+
Opbeat.trace('thing-1') do
|
70
|
+
travel 100
|
71
|
+
end
|
72
|
+
travel 100
|
73
|
+
subject.finish(*message_args)
|
74
|
+
end.done(200)
|
75
|
+
|
76
|
+
expect(transaction.traces.length).to eq 3
|
77
|
+
expect(transaction.traces.last.parents.map(&:signature)).to eq ['transaction', 'Controller#index']
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|