scout_apm 3.0.0.pre23 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.rubocop.yml +3 -4
- data/.travis.yml +17 -14
- data/CHANGELOG.markdown +150 -4
- data/Gemfile +2 -8
- data/README.markdown +30 -4
- data/Rakefile +1 -1
- data/ext/allocations/allocations.c +2 -0
- data/gems/README.md +28 -0
- data/gems/octoshark.gemfile +4 -0
- data/gems/rails3.gemfile +5 -0
- data/gems/rails4.gemfile +4 -0
- data/gems/rails5.gemfile +4 -0
- data/gems/rails6.gemfile +4 -0
- data/lib/scout_apm.rb +39 -9
- data/lib/scout_apm/agent.rb +29 -10
- data/lib/scout_apm/agent/exit_handler.rb +0 -1
- data/lib/scout_apm/agent_context.rb +26 -3
- data/lib/scout_apm/app_server_load.rb +7 -2
- data/lib/scout_apm/attribute_arranger.rb +0 -2
- data/lib/scout_apm/auto_instrument.rb +5 -0
- data/lib/scout_apm/auto_instrument/instruction_sequence.rb +31 -0
- data/lib/scout_apm/auto_instrument/layer.rb +23 -0
- data/lib/scout_apm/auto_instrument/parser.rb +27 -0
- data/lib/scout_apm/auto_instrument/rails.rb +175 -0
- data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -1
- data/lib/scout_apm/background_job_integrations/legacy_sneakers.rb +55 -0
- data/lib/scout_apm/background_job_integrations/que.rb +134 -0
- data/lib/scout_apm/background_job_integrations/resque.rb +6 -2
- data/lib/scout_apm/background_job_integrations/shoryuken.rb +124 -0
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +5 -19
- data/lib/scout_apm/background_job_integrations/sneakers.rb +87 -0
- data/lib/scout_apm/config.rb +48 -7
- data/lib/scout_apm/detailed_trace.rb +217 -0
- data/lib/scout_apm/environment.rb +3 -0
- data/lib/scout_apm/error.rb +27 -0
- data/lib/scout_apm/error_service.rb +32 -0
- data/lib/scout_apm/error_service/error_buffer.rb +39 -0
- data/lib/scout_apm/error_service/error_record.rb +211 -0
- data/lib/scout_apm/error_service/ignored_exceptions.rb +66 -0
- data/lib/scout_apm/error_service/middleware.rb +32 -0
- data/lib/scout_apm/error_service/notifier.rb +33 -0
- data/lib/scout_apm/error_service/payload.rb +47 -0
- data/lib/scout_apm/error_service/periodic_work.rb +17 -0
- data/lib/scout_apm/error_service/railtie.rb +11 -0
- data/lib/scout_apm/error_service/sidekiq.rb +80 -0
- data/lib/scout_apm/extensions/transaction_callback_payload.rb +1 -1
- data/lib/scout_apm/fake_store.rb +3 -0
- data/lib/scout_apm/framework_integrations/rails_2.rb +2 -1
- data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +17 -6
- data/lib/scout_apm/git_revision.rb +6 -3
- data/lib/scout_apm/instant/middleware.rb +2 -1
- data/lib/scout_apm/instrument_manager.rb +8 -7
- data/lib/scout_apm/instruments/action_controller_rails_2.rb +3 -1
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +56 -55
- data/lib/scout_apm/instruments/action_view.rb +114 -26
- data/lib/scout_apm/instruments/active_record.rb +66 -19
- data/lib/scout_apm/instruments/http.rb +48 -0
- data/lib/scout_apm/instruments/memcached.rb +43 -0
- data/lib/scout_apm/instruments/mongoid.rb +9 -4
- data/lib/scout_apm/instruments/net_http.rb +8 -1
- data/lib/scout_apm/job_record.rb +4 -2
- data/lib/scout_apm/layaway_file.rb +4 -0
- data/lib/scout_apm/layer.rb +5 -56
- data/lib/scout_apm/layer_children_set.rb +15 -6
- data/lib/scout_apm/layer_converters/converter_base.rb +15 -30
- data/lib/scout_apm/layer_converters/database_converter.rb +2 -15
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +12 -2
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +14 -4
- data/lib/scout_apm/layer_converters/trace_converter.rb +184 -0
- data/lib/scout_apm/limited_layer.rb +0 -7
- data/lib/scout_apm/metric_stats.rb +0 -8
- data/lib/scout_apm/middleware.rb +1 -1
- data/lib/scout_apm/periodic_work.rb +19 -0
- data/lib/scout_apm/remote/message.rb +4 -0
- data/lib/scout_apm/reporter.rb +8 -3
- data/lib/scout_apm/reporting.rb +2 -1
- data/lib/scout_apm/request_histograms.rb +8 -0
- data/lib/scout_apm/serializers/app_server_load_serializer.rb +4 -0
- data/lib/scout_apm/serializers/directive_serializer.rb +4 -0
- data/lib/scout_apm/serializers/payload_serializer.rb +2 -2
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +30 -15
- data/lib/scout_apm/slow_job_record.rb +5 -1
- data/lib/scout_apm/slow_policy/age_policy.rb +33 -0
- data/lib/scout_apm/slow_policy/percent_policy.rb +22 -0
- data/lib/scout_apm/slow_policy/percentile_policy.rb +24 -0
- data/lib/scout_apm/slow_policy/policy.rb +21 -0
- data/lib/scout_apm/slow_policy/speed_policy.rb +16 -0
- data/lib/scout_apm/slow_request_policy.rb +18 -60
- data/lib/scout_apm/slow_transaction.rb +3 -1
- data/lib/scout_apm/store.rb +14 -10
- data/lib/scout_apm/tracked_request.rb +41 -30
- data/lib/scout_apm/transaction_time_consumed.rb +51 -0
- data/lib/scout_apm/utils/active_record_metric_name.rb +16 -3
- data/lib/scout_apm/utils/backtrace_parser.rb +3 -0
- data/lib/scout_apm/utils/marshal_logging.rb +90 -0
- data/lib/scout_apm/utils/sql_sanitizer.rb +10 -1
- data/lib/scout_apm/utils/sql_sanitizer_regex.rb +7 -0
- data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +6 -0
- data/lib/scout_apm/utils/unique_id.rb +27 -0
- data/lib/scout_apm/version.rb +1 -1
- data/scout_apm.gemspec +13 -7
- data/test/test_helper.rb +2 -2
- data/test/unit/agent_context_test.rb +29 -0
- data/test/unit/auto_instrument/assignments-instrumented.rb +31 -0
- data/test/unit/auto_instrument/assignments.rb +31 -0
- data/test/unit/auto_instrument/controller-ast.txt +57 -0
- data/test/unit/auto_instrument/controller-instrumented.rb +49 -0
- data/test/unit/auto_instrument/controller.rb +49 -0
- data/test/unit/auto_instrument/rescue_from-instrumented.rb +13 -0
- data/test/unit/auto_instrument/rescue_from.rb +13 -0
- data/test/unit/auto_instrument_test.rb +54 -0
- data/test/unit/error_service/error_buffer_test.rb +25 -0
- data/test/unit/error_service/ignored_exceptions_test.rb +49 -0
- data/test/unit/extensions/periodic_callbacks_test.rb +2 -2
- data/test/unit/instruments/active_record_test.rb +40 -0
- data/test/unit/layer_children_set_test.rb +9 -0
- data/test/unit/request_histograms_test.rb +17 -0
- data/test/unit/serializers/payload_serializer_test.rb +39 -5
- data/test/unit/slow_request_policy_test.rb +42 -9
- data/test/unit/sql_sanitizer_test.rb +47 -0
- data/test/unit/transaction_time_consumed_test.rb +46 -0
- data/test/unit/utils/active_record_metric_name_test.rb +10 -2
- metadata +101 -19
- data/ext/stacks/extconf.rb +0 -37
- data/ext/stacks/scout_atomics.h +0 -86
- data/ext/stacks/stacks.c +0 -814
- data/lib/scout_apm/slow_job_policy.rb +0 -94
- data/lib/scout_apm/trace_compactor.rb +0 -312
- data/lib/scout_apm/utils/fake_stacks.rb +0 -88
- data/test/unit/instruments/active_record_instruments_test.rb +0 -5
- data/test/unit/slow_job_policy_test.rb +0 -6
- data/tester.rb +0 -53
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
class Assignments
|
3
|
+
def test_op_asgn
|
4
|
+
foo.bar += User.size
|
5
|
+
foo.bar -= User.size
|
6
|
+
end
|
7
|
+
|
8
|
+
def nested_assignment
|
9
|
+
@email ||= if (email = session["email"]).present?
|
10
|
+
User.where(email: email).first
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def paginate_collection(coll)
|
17
|
+
page = (params[:page].present? ? params[:page].to_i : 1)
|
18
|
+
per_page = (params[:per_page].present? ? params[:per_page].to_i : 20)
|
19
|
+
pagination, self.collection = pagy(
|
20
|
+
coll,
|
21
|
+
items: per_page,
|
22
|
+
page: page
|
23
|
+
)
|
24
|
+
headers[PAGINATION_TOTAL_HEADER] = pagination.count.to_s
|
25
|
+
headers[PAGINATION_TOTAL_PAGES_HEADER] = pagination.pages.to_s
|
26
|
+
headers[PAGINATION_PER_PAGE_HEADER] = per_page.to_s
|
27
|
+
headers[PAGINATION_PAGE_HEADER] = pagination.page.to_s
|
28
|
+
headers[PAGINATION_NEXT_PAGE_HEADER] = pagination.next.to_s
|
29
|
+
collection
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
s(:class,
|
2
|
+
s(:const, nil, :ClientsController),
|
3
|
+
s(:const, nil, :ApplicationController),
|
4
|
+
s(:begin,
|
5
|
+
s(:send, nil, :before_action,
|
6
|
+
s(:sym, :check_authorization)),
|
7
|
+
s(:def, :index,
|
8
|
+
s(:args),
|
9
|
+
s(:if,
|
10
|
+
s(:send,
|
11
|
+
s(:send,
|
12
|
+
s(:send, nil, :params), :[],
|
13
|
+
s(:sym, :status)), :==,
|
14
|
+
s(:str, "activated")),
|
15
|
+
s(:ivasgn, :@clients,
|
16
|
+
s(:send,
|
17
|
+
s(:const, nil, :Client), :activated)),
|
18
|
+
s(:ivasgn, :@clients,
|
19
|
+
s(:send,
|
20
|
+
s(:const, nil, :Client), :inactivated)))),
|
21
|
+
s(:def, :create,
|
22
|
+
s(:args),
|
23
|
+
s(:begin,
|
24
|
+
s(:ivasgn, :@client,
|
25
|
+
s(:send,
|
26
|
+
s(:const, nil, :Client), :new,
|
27
|
+
s(:send,
|
28
|
+
s(:send, nil, :params), :[],
|
29
|
+
s(:sym, :client)))),
|
30
|
+
s(:if,
|
31
|
+
s(:send,
|
32
|
+
s(:ivar, :@client), :save),
|
33
|
+
s(:send, nil, :redirect_to,
|
34
|
+
s(:ivar, :@client)),
|
35
|
+
s(:send, nil, :render,
|
36
|
+
s(:str, "new"))))),
|
37
|
+
s(:def, :edit,
|
38
|
+
s(:args),
|
39
|
+
s(:begin,
|
40
|
+
s(:ivasgn, :@client,
|
41
|
+
s(:send,
|
42
|
+
s(:const, nil, :Client), :new,
|
43
|
+
s(:send,
|
44
|
+
s(:send, nil, :params), :[],
|
45
|
+
s(:sym, :client)))),
|
46
|
+
s(:if,
|
47
|
+
s(:send,
|
48
|
+
s(:send, nil, :request), :post?),
|
49
|
+
s(:block,
|
50
|
+
s(:send,
|
51
|
+
s(:ivar, :@client), :transaction),
|
52
|
+
s(:args),
|
53
|
+
s(:send,
|
54
|
+
s(:ivar, :@client), :update_attributes,
|
55
|
+
s(:send,
|
56
|
+
s(:send, nil, :params), :[],
|
57
|
+
s(:sym, :client)))), nil)))))
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
class ClientsController < ApplicationController
|
3
|
+
before_action :check_authorization
|
4
|
+
|
5
|
+
def index
|
6
|
+
if ::ScoutApm::AutoInstrument("params[:status] == \"activated\"",["ROOT/test/unit/auto_instrument/controller.rb:6:in `index'"]){params[:status] == "activated"}
|
7
|
+
@clients = ::ScoutApm::AutoInstrument("Client.activated",["ROOT/test/unit/auto_instrument/controller.rb:7:in `index'"]){Client.activated}
|
8
|
+
else
|
9
|
+
@clients = ::ScoutApm::AutoInstrument("Client.inactivated",["ROOT/test/unit/auto_instrument/controller.rb:9:in `index'"]){Client.inactivated}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
@client = ::ScoutApm::AutoInstrument("Client.new(params[:client])",["ROOT/test/unit/auto_instrument/controller.rb:14:in `create'"]){Client.new(params[:client])}
|
15
|
+
if ::ScoutApm::AutoInstrument("@client.save",["ROOT/test/unit/auto_instrument/controller.rb:15:in `create'"]){@client.save}
|
16
|
+
::ScoutApm::AutoInstrument("redirect_to @client",["ROOT/test/unit/auto_instrument/controller.rb:16:in `create'"]){redirect_to @client}
|
17
|
+
else
|
18
|
+
# This line overrides the default rendering behavior, which
|
19
|
+
# would have been to render the "create" view.
|
20
|
+
::ScoutApm::AutoInstrument("render \"new\"",["ROOT/test/unit/auto_instrument/controller.rb:20:in `create'"]){render "new"}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
@client = ::ScoutApm::AutoInstrument("Client.new(params[:client])",["ROOT/test/unit/auto_instrument/controller.rb:25:in `edit'"]){Client.new(params[:client])}
|
26
|
+
|
27
|
+
if ::ScoutApm::AutoInstrument("request.post?",["ROOT/test/unit/auto_instrument/controller.rb:27:in `edit'"]){request.post?}
|
28
|
+
::ScoutApm::AutoInstrument("@client.transaction do...",["ROOT/test/unit/auto_instrument/controller.rb:28:in `edit'"]){@client.transaction do
|
29
|
+
@client.update_attributes(params[:client])
|
30
|
+
end}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def data
|
35
|
+
@clients = ::ScoutApm::AutoInstrument("Client.all",["ROOT/test/unit/auto_instrument/controller.rb:35:in `data'"]){Client.all}
|
36
|
+
|
37
|
+
formatter = ::ScoutApm::AutoInstrument("proc do |row|...",["ROOT/test/unit/auto_instrument/controller.rb:37:in `data'"]){proc do |row|
|
38
|
+
row.to_json
|
39
|
+
end}
|
40
|
+
|
41
|
+
::ScoutApm::AutoInstrument("respond_with @clients.each(&formatter).join(\"\\n\"), :content_type => 'application/json; boundary=NL'",["ROOT/test/unit/auto_instrument/controller.rb:41:in `data'"]){respond_with @clients.each(&formatter).join("\n"), :content_type => 'application/json; boundary=NL'}
|
42
|
+
end
|
43
|
+
|
44
|
+
def things
|
45
|
+
x = {}
|
46
|
+
x[:this] ||= 'foo'
|
47
|
+
x[:that] &&= ::ScoutApm::AutoInstrument("'foo'.size",["ROOT/test/unit/auto_instrument/controller.rb:47:in `things'"]){'foo'.size}
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
class ClientsController < ApplicationController
|
3
|
+
before_action :check_authorization
|
4
|
+
|
5
|
+
def index
|
6
|
+
if params[:status] == "activated"
|
7
|
+
@clients = Client.activated
|
8
|
+
else
|
9
|
+
@clients = Client.inactivated
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
@client = Client.new(params[:client])
|
15
|
+
if @client.save
|
16
|
+
redirect_to @client
|
17
|
+
else
|
18
|
+
# This line overrides the default rendering behavior, which
|
19
|
+
# would have been to render the "create" view.
|
20
|
+
render "new"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
@client = Client.new(params[:client])
|
26
|
+
|
27
|
+
if request.post?
|
28
|
+
@client.transaction do
|
29
|
+
@client.update_attributes(params[:client])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def data
|
35
|
+
@clients = Client.all
|
36
|
+
|
37
|
+
formatter = proc do |row|
|
38
|
+
row.to_json
|
39
|
+
end
|
40
|
+
|
41
|
+
respond_with @clients.each(&formatter).join("\n"), :content_type => 'application/json; boundary=NL'
|
42
|
+
end
|
43
|
+
|
44
|
+
def things
|
45
|
+
x = {}
|
46
|
+
x[:this] ||= 'foo'
|
47
|
+
x[:that] &&= 'foo'.size
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
class BrokenController < ApplicationController
|
3
|
+
rescue_from Exception do |e|
|
4
|
+
if e.is_a? Pundit::NotAuthorizedError
|
5
|
+
unauthorized_error
|
6
|
+
elsif e.is_a? ActionController::ParameterMissing
|
7
|
+
error(status: 422, message: e.message)
|
8
|
+
else
|
9
|
+
log_error(e)
|
10
|
+
error message: 'Internal error', exception: e
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
class BrokenController < ApplicationController
|
3
|
+
rescue_from Exception do |e|
|
4
|
+
if e.is_a? Pundit::NotAuthorizedError
|
5
|
+
unauthorized_error
|
6
|
+
elsif e.is_a? ActionController::ParameterMissing
|
7
|
+
error(status: 422, message: e.message)
|
8
|
+
else
|
9
|
+
log_error(e)
|
10
|
+
error message: 'Internal error', exception: e
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'scout_apm/auto_instrument'
|
4
|
+
|
5
|
+
class AutoInstrumentTest < Minitest::Test
|
6
|
+
ROOT = File.expand_path("../../", __dir__)
|
7
|
+
|
8
|
+
def source_path(name)
|
9
|
+
File.expand_path("auto_instrument/#{name}.rb", __dir__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def instrumented_path(name)
|
13
|
+
File.expand_path("auto_instrument/#{name}-instrumented.rb", __dir__)
|
14
|
+
end
|
15
|
+
|
16
|
+
def instrumented_source(name)
|
17
|
+
File.read(instrumented_path(name))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Autoinstruments adds a backtrace to each created layer. This is the full path to the
|
21
|
+
# test controller.rb file, which will be different on different environments.
|
22
|
+
# This normalizes backtraces across environments.
|
23
|
+
def normalize_backtrace(string)
|
24
|
+
string.gsub(ROOT, "ROOT")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Use this to automatically update the test fixtures.
|
28
|
+
def update_instrumented_source(name)
|
29
|
+
source = ::ScoutApm::AutoInstrument::Rails.rewrite(source_path(name))
|
30
|
+
source = normalize_backtrace(source)
|
31
|
+
File.write(instrumented_path(name),source)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_controller_rewrite
|
35
|
+
# update_instrumented_source("controller")
|
36
|
+
|
37
|
+
assert_equal instrumented_source("controller"),
|
38
|
+
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("controller")))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_rescue_from_rewrite
|
42
|
+
# update_instrumented_source("rescue_from")
|
43
|
+
|
44
|
+
assert_equal instrumented_source("rescue_from"),
|
45
|
+
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("rescue_from")))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_assignments_rewrite
|
49
|
+
# update_instrumented_source("assignments")
|
50
|
+
|
51
|
+
assert_equal instrumented_source("assignments"),
|
52
|
+
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("assignments")))
|
53
|
+
end
|
54
|
+
end if defined? ScoutApm::AutoInstrument
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ErrorBufferTest < Minitest::Test
|
4
|
+
class FakeError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_captures_and_stores_exceptions_and_env
|
8
|
+
eb = ScoutApm::ErrorService::ErrorBuffer.new(context)
|
9
|
+
eb.capture(ex, env)
|
10
|
+
end
|
11
|
+
|
12
|
+
#### Helpers
|
13
|
+
|
14
|
+
def context
|
15
|
+
ScoutApm::AgentContext.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def env
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
|
22
|
+
def ex(msg="Whoops")
|
23
|
+
FakeError.new(msg)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class IgnoredExceptionsTest < Minitest::Test
|
4
|
+
class FakeError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class SubclassFakeError < FakeError
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_ignores_with_string_match
|
11
|
+
ig = ScoutApm::ErrorService::IgnoredExceptions.new(context, ["RuntimeError"])
|
12
|
+
assert ig.ignored?(RuntimeError.new("something went wrong"))
|
13
|
+
assert !ig.ignored?(FakeError.new("something went wrong"))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_ignores_with_block
|
17
|
+
ig = ScoutApm::ErrorService::IgnoredExceptions.new(context, [])
|
18
|
+
ig.add_callback { |e| e.message == "ignore me" }
|
19
|
+
|
20
|
+
should_ignore = RuntimeError.new("ignore me")
|
21
|
+
should_not_ignore = RuntimeError.new("super legit")
|
22
|
+
|
23
|
+
assert ig.ignored?(should_ignore)
|
24
|
+
assert !ig.ignored?(should_not_ignore)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_ignores_subclasses
|
28
|
+
ig = ScoutApm::ErrorService::IgnoredExceptions.new(context, ["IgnoredExceptionsTest::FakeError"])
|
29
|
+
assert ig.ignored?(SubclassFakeError.new("Subclass"))
|
30
|
+
end
|
31
|
+
|
32
|
+
# Check that a bad exception in the list doesn't stop the whole thing from working
|
33
|
+
def test_does_not_consider_unknown_errors
|
34
|
+
ig = ScoutApm::ErrorService::IgnoredExceptions.new(context, ["ThisDoesNotExist", "IgnoredExceptionsTest::FakeError"])
|
35
|
+
assert ig.ignored?(FakeError.new("ignore this one"))
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_add_module
|
39
|
+
ig = ScoutApm::ErrorService::IgnoredExceptions.new(context, [])
|
40
|
+
ig.add(IgnoredExceptionsTest::FakeError)
|
41
|
+
assert ig.ignored?(FakeError.new("ignore this one"))
|
42
|
+
end
|
43
|
+
|
44
|
+
#### Helpers
|
45
|
+
|
46
|
+
def context
|
47
|
+
ScoutApm::AgentContext.new
|
48
|
+
end
|
49
|
+
end
|
@@ -38,7 +38,7 @@ class PeriodicCallbacksTest < Minitest::Test
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def reporting_period
|
41
|
-
rp = ScoutApm::StoreReportingPeriod.new(
|
41
|
+
rp = ScoutApm::StoreReportingPeriod.new(Time.at(metadata[:agent_time].to_i), ScoutApm::AgentContext.new)
|
42
42
|
rp.absorb_metrics!(metrics)
|
43
43
|
end
|
44
44
|
|
@@ -55,4 +55,4 @@ class PeriodicCallbacksTest < Minitest::Test
|
|
55
55
|
{:app_root=>"/srv/rails_app", :unique_id=>"ID", :agent_version=>"2.4.10", :agent_time=>"1523287920", :agent_pid=>21581, :platform=>"ruby"}
|
56
56
|
end
|
57
57
|
|
58
|
-
end
|
58
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'sqlite3'
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'octoshark'
|
7
|
+
rescue LoadError
|
8
|
+
# Ignore
|
9
|
+
end
|
10
|
+
|
11
|
+
class ActiveRecordTest < Minitest::Test
|
12
|
+
def database_path
|
13
|
+
File.expand_path('test.sqlite3', DATA_FILE_DIR)
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
database = SQLite3::Database.new(database_path)
|
18
|
+
database.execute("DROP TABLE IF EXISTS users;")
|
19
|
+
database.execute("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100));")
|
20
|
+
|
21
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => database_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_instrumentation
|
28
|
+
recorder = FakeRecorder.new
|
29
|
+
agent_context.recorder = recorder
|
30
|
+
|
31
|
+
instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
|
32
|
+
instrument.install
|
33
|
+
|
34
|
+
ScoutApm::Tracer.instrument("Controller", "foo/bar") do
|
35
|
+
user = User.create
|
36
|
+
end
|
37
|
+
|
38
|
+
assert 1, recorder.requests.size
|
39
|
+
end
|
40
|
+
end
|
@@ -71,6 +71,15 @@ class LayerChildrenSetTest < Minitest::Test
|
|
71
71
|
limited_layers.each { |ml| assert_equal 5, ml.count }
|
72
72
|
end
|
73
73
|
|
74
|
+
def test_works_with_marshal
|
75
|
+
s = SET.new(5)
|
76
|
+
10.times do
|
77
|
+
s << make_layer("LayerType", "LayerName")
|
78
|
+
end
|
79
|
+
|
80
|
+
Marshal.dump(s)
|
81
|
+
end
|
82
|
+
|
74
83
|
#############
|
75
84
|
# Helpers #
|
76
85
|
#############
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'scout_apm/request_histograms'
|
4
|
+
|
5
|
+
class RequestHistogramsTest < Minitest::Test
|
6
|
+
def test_as_json_without_activesupport
|
7
|
+
rh = ScoutApm::RequestHistograms.new
|
8
|
+
|
9
|
+
rh.add("foo", 1)
|
10
|
+
rh.add("foo", 2)
|
11
|
+
rh.add("bar", 3)
|
12
|
+
|
13
|
+
j = rh.as_json
|
14
|
+
assert_equal 2, j.size
|
15
|
+
assert_equal ["bar", "foo"], j.keys.sort
|
16
|
+
end
|
17
|
+
end
|
@@ -8,7 +8,7 @@ class PayloadSerializerTest < Minitest::Test
|
|
8
8
|
:unique_id => "unique_idz",
|
9
9
|
:agent_version => 123
|
10
10
|
}
|
11
|
-
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {})
|
11
|
+
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {}, [])
|
12
12
|
|
13
13
|
# symbol keys turn to strings
|
14
14
|
formatted_metadata = {
|
@@ -49,7 +49,7 @@ class PayloadSerializerTest < Minitest::Test
|
|
49
49
|
stats.total_exclusive_time = 0.078132088
|
50
50
|
}
|
51
51
|
}
|
52
|
-
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, metrics, {}, [], [], [], {})
|
52
|
+
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, metrics, {}, [], [], [], {}, [])
|
53
53
|
formatted_metrics = [
|
54
54
|
{
|
55
55
|
"key" => {
|
@@ -69,7 +69,6 @@ class PayloadSerializerTest < Minitest::Test
|
|
69
69
|
"min_call_time" => 0.000613518,
|
70
70
|
"total_call_time" => 0.033245704,
|
71
71
|
"total_exclusive_time" => 0.033245704,
|
72
|
-
"traces" => []
|
73
72
|
},
|
74
73
|
{
|
75
74
|
"key" => {
|
@@ -84,7 +83,6 @@ class PayloadSerializerTest < Minitest::Test
|
|
84
83
|
"min_call_time" => 0.034881757,
|
85
84
|
"total_call_time" => 0.113403176,
|
86
85
|
"total_exclusive_time" => 0.078132088,
|
87
|
-
"traces" => []
|
88
86
|
}
|
89
87
|
]
|
90
88
|
assert_equal formatted_metrics,
|
@@ -96,7 +94,7 @@ class PayloadSerializerTest < Minitest::Test
|
|
96
94
|
:quotie => "here are some \"quotes\"",
|
97
95
|
:payload_version => 2,
|
98
96
|
}
|
99
|
-
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {})
|
97
|
+
payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {}, [])
|
100
98
|
|
101
99
|
# symbol keys turn to strings
|
102
100
|
formatted_metadata = {
|
@@ -110,4 +108,40 @@ class PayloadSerializerTest < Minitest::Test
|
|
110
108
|
json = { "foo" => "\bbar\nbaz\r" }
|
111
109
|
assert_equal json, JSON.parse(ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json))
|
112
110
|
end
|
111
|
+
|
112
|
+
def test_escapes_escaped_quotes
|
113
|
+
# Some escapes haven't ever worked on 1.8.7, and is not the issue I'm
|
114
|
+
# fixing now. Remove this when we drop support for ancient ruby
|
115
|
+
skip if RUBY_VERSION == "1.8.7"
|
116
|
+
|
117
|
+
json = {"foo" => %q|`additional_details` = '{\"amount\":1}'|}
|
118
|
+
result = ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json)
|
119
|
+
assert_equal json, JSON.parse(result)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_escapes_various_special_characters
|
123
|
+
# Some escapes haven't ever worked on 1.8.7, and is not the issue I'm
|
124
|
+
# fixing now. Remove this when we drop support for ancient ruby
|
125
|
+
skip if RUBY_VERSION == "1.8.7"
|
126
|
+
|
127
|
+
json = {"foo" => [
|
128
|
+
%Q|\fbar|,
|
129
|
+
%Q|\rbar|,
|
130
|
+
%Q|\nbar|,
|
131
|
+
%Q|\tbar|,
|
132
|
+
%Q|"bar|,
|
133
|
+
%Q|'bar|,
|
134
|
+
%Q|{bar|,
|
135
|
+
%Q|}bar|,
|
136
|
+
%Q|\\bar|,
|
137
|
+
if RUBY_VERSION == '1.8.7'
|
138
|
+
""
|
139
|
+
else
|
140
|
+
%Q|\\\nbar|
|
141
|
+
end,
|
142
|
+
]}
|
143
|
+
|
144
|
+
result = ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json)
|
145
|
+
assert_equal json, JSON.parse(result)
|
146
|
+
end
|
113
147
|
end
|