appoptics_apm 4.0.2
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 +7 -0
- data/.codeclimate.yml +43 -0
- data/.dockerignore +5 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +82 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Dockerfile +41 -0
- data/Dockerfile_test +66 -0
- data/Gemfile +41 -0
- data/LICENSE +193 -0
- data/README.md +351 -0
- data/Rakefile +202 -0
- data/Vagrantfile +67 -0
- data/appoptics_apm.gemspec +55 -0
- data/build_gems.sh +15 -0
- data/docker-compose.yml +73 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +220 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +124 -0
- data/examples/tracing_background_jobs.rb +53 -0
- data/examples/tracing_forked_processes.rb +99 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +54 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/ext/oboe_metal/src/bson/bson.h +221 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/oboe.h +883 -0
- data/ext/oboe_metal/src/oboe.hpp +793 -0
- data/ext/oboe_metal/src/oboe_debug.h +50 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/delayed_job.gemfile +36 -0
- data/gemfiles/frameworks.gemfile +44 -0
- data/gemfiles/instrumentation_mocked.gemfile +29 -0
- data/gemfiles/libraries.gemfile +85 -0
- data/gemfiles/rails23.gemfile +39 -0
- data/gemfiles/rails30.gemfile +42 -0
- data/gemfiles/rails31.gemfile +44 -0
- data/gemfiles/rails32.gemfile +54 -0
- data/gemfiles/rails40.gemfile +27 -0
- data/gemfiles/rails41.gemfile +27 -0
- data/gemfiles/rails42.gemfile +35 -0
- data/gemfiles/rails50.gemfile +44 -0
- data/gemfiles/rails51.gemfile +44 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm/api/layerinit.rb +39 -0
- data/lib/appoptics_apm/api/logging.rb +359 -0
- data/lib/appoptics_apm/api/memcache.rb +34 -0
- data/lib/appoptics_apm/api/profiling.rb +201 -0
- data/lib/appoptics_apm/api/tracing.rb +152 -0
- data/lib/appoptics_apm/api/util.rb +128 -0
- data/lib/appoptics_apm/api.rb +18 -0
- data/lib/appoptics_apm/base.rb +252 -0
- data/lib/appoptics_apm/config.rb +281 -0
- data/lib/appoptics_apm/frameworks/grape.rb +93 -0
- data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
- data/lib/appoptics_apm/frameworks/rails.rb +116 -0
- data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
- data/lib/appoptics_apm/inst/curb.rb +329 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
- data/lib/appoptics_apm/inst/excon.rb +130 -0
- data/lib/appoptics_apm/inst/faraday.rb +77 -0
- data/lib/appoptics_apm/inst/http.rb +83 -0
- data/lib/appoptics_apm/inst/httpclient.rb +176 -0
- data/lib/appoptics_apm/inst/memcache.rb +102 -0
- data/lib/appoptics_apm/inst/memcached.rb +94 -0
- data/lib/appoptics_apm/inst/mongo.rb +242 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +146 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +50 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
- data/lib/appoptics_apm/loading.rb +66 -0
- data/lib/appoptics_apm/logger.rb +41 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/support.rb +135 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +312 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/appoptics_apm.rb +72 -0
- data/lib/joboe_metal.rb +214 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +187 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
- data/ruby_setup.sh +47 -0
- data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
- data/run_tests_docker.rb +32 -0
- data/test/benchmark/README.md +65 -0
- data/test/benchmark/logging_bench.rb +54 -0
- data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
- data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
- data/test/frameworks/apps/grape_nested.rb +33 -0
- data/test/frameworks/apps/grape_simple.rb +80 -0
- data/test/frameworks/apps/padrino_simple.rb +80 -0
- data/test/frameworks/apps/sinatra_simple.rb +55 -0
- data/test/frameworks/grape_test.rb +286 -0
- data/test/frameworks/padrino_test.rb +222 -0
- data/test/frameworks/rails3x_test.rb +554 -0
- data/test/frameworks/rails4x_test.rb +570 -0
- data/test/frameworks/rails5x_api_test.rb +210 -0
- data/test/frameworks/rails5x_test.rb +376 -0
- data/test/frameworks/rails_shared_tests.rb +172 -0
- data/test/frameworks/sinatra_test.rb +140 -0
- data/test/instrumentation/bunny_client_test.rb +276 -0
- data/test/instrumentation/bunny_consumer_test.rb +204 -0
- data/test/instrumentation/curb_test.rb +398 -0
- data/test/instrumentation/dalli_test.rb +177 -0
- data/test/instrumentation/em_http_request_test.rb +89 -0
- data/test/instrumentation/excon_test.rb +231 -0
- data/test/instrumentation/faraday_test.rb +228 -0
- data/test/instrumentation/http_test.rb +143 -0
- data/test/instrumentation/httpclient_test.rb +320 -0
- data/test/instrumentation/memcache_test.rb +260 -0
- data/test/instrumentation/memcached_test.rb +229 -0
- data/test/instrumentation/mongo_v1_test.rb +479 -0
- data/test/instrumentation/mongo_v2_index_test.rb +124 -0
- data/test/instrumentation/mongo_v2_test.rb +584 -0
- data/test/instrumentation/mongo_v2_view_test.rb +435 -0
- data/test/instrumentation/moped_test.rb +517 -0
- data/test/instrumentation/rack_test.rb +165 -0
- data/test/instrumentation/redis_hashes_test.rb +268 -0
- data/test/instrumentation/redis_keys_test.rb +321 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +163 -0
- data/test/instrumentation/redis_sets_test.rb +296 -0
- data/test/instrumentation/redis_sortedsets_test.rb +328 -0
- data/test/instrumentation/redis_strings_test.rb +349 -0
- data/test/instrumentation/resque_test.rb +185 -0
- data/test/instrumentation/rest-client_test.rb +288 -0
- data/test/instrumentation/sequel_mysql2_test.rb +353 -0
- data/test/instrumentation/sequel_mysql_test.rb +334 -0
- data/test/instrumentation/sequel_pg_test.rb +336 -0
- data/test/instrumentation/sidekiq-client_test.rb +159 -0
- data/test/instrumentation/sidekiq-worker_test.rb +180 -0
- data/test/instrumentation/twitter-cassandra_test.rb +424 -0
- data/test/instrumentation/typhoeus_test.rb +284 -0
- data/test/jobs/delayed_job/db_worker_job.rb +29 -0
- data/test/jobs/delayed_job/error_worker_job.rb +10 -0
- data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
- data/test/jobs/resque/db_worker_job.rb +29 -0
- data/test/jobs/resque/error_worker_job.rb +10 -0
- data/test/jobs/resque/remote_call_worker_job.rb +20 -0
- data/test/jobs/sidekiq/db_worker_job.rb +29 -0
- data/test/jobs/sidekiq/error_worker_job.rb +10 -0
- data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
- data/test/minitest_helper.rb +276 -0
- data/test/mocked/curb_mocked_test.rb +311 -0
- data/test/mocked/excon_mocked_test.rb +166 -0
- data/test/mocked/faraday_mocked_test.rb +93 -0
- data/test/mocked/http_mocked_test.rb +129 -0
- data/test/mocked/httpclient_mocked_test.rb +245 -0
- data/test/mocked/rest_client_mocked_test.rb +103 -0
- data/test/mocked/typhoeus_mocked_test.rb +192 -0
- data/test/models/widget.rb +36 -0
- data/test/profiling/legacy_method_profiling_test.rb +201 -0
- data/test/profiling/method_profiling_test.rb +631 -0
- data/test/queues/delayed_job-client_test.rb +95 -0
- data/test/queues/delayed_job-worker_test.rb +91 -0
- data/test/reporter/reporter_test.rb +14 -0
- data/test/servers/delayed_job.rb +107 -0
- data/test/servers/rackapp_8101.rb +29 -0
- data/test/servers/rails3x_8140.rb +96 -0
- data/test/servers/rails4x_8140.rb +96 -0
- data/test/servers/rails5x_8140.rb +95 -0
- data/test/servers/rails5x_api_8150.rb +78 -0
- data/test/servers/sidekiq.rb +29 -0
- data/test/servers/sidekiq.yml +7 -0
- data/test/servers/sidekiq_initializer.rb +25 -0
- data/test/settings +0 -0
- data/test/support/auto_tracing_test.rb +50 -0
- data/test/support/backcompat_test.rb +276 -0
- data/test/support/config_test.rb +149 -0
- data/test/support/dnt_test.rb +98 -0
- data/test/support/init_report_test.rb +25 -0
- data/test/support/liboboe_settings_test.rb +110 -0
- data/test/support/logging_test.rb +130 -0
- data/test/support/noop_test.rb +88 -0
- data/test/support/sql_sanitize_test.rb +55 -0
- data/test/support/tracing_mode_test.rb +33 -0
- data/test/support/tvalias_test.rb +15 -0
- data/test/support/xtrace_test.rb +41 -0
- metadata +475 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
unless defined?(JRUBY_VERSION)
|
|
5
|
+
require 'minitest_helper'
|
|
6
|
+
require 'webmock/minitest'
|
|
7
|
+
require 'mocha/mini_test'
|
|
8
|
+
WebMock.allow_net_connect!
|
|
9
|
+
|
|
10
|
+
class RestClientMockedTest < Minitest::Test
|
|
11
|
+
|
|
12
|
+
def setup
|
|
13
|
+
WebMock.enable!
|
|
14
|
+
WebMock.disable_net_connect!
|
|
15
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
16
|
+
@sample_rate = AppOpticsAPM::Config[:sample_rate]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def teardown
|
|
21
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
22
|
+
AppOpticsAPM::Config[:sample_rate] = @sample_rate
|
|
23
|
+
AppOpticsAPM::Config[:blacklist] = []
|
|
24
|
+
end
|
|
25
|
+
WebMock.reset!
|
|
26
|
+
WebMock.allow_net_connect!
|
|
27
|
+
WebMock.disable!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_tracing_sampling
|
|
31
|
+
stub_request(:get, "http://127.0.0.1:8101/").to_return(status: 200, body: "", headers: {})
|
|
32
|
+
|
|
33
|
+
AppOpticsAPM::API.start_trace('rest_client_tests') do
|
|
34
|
+
RestClient::Resource.new('http://127.0.0.1:8101').get
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
assert_requested :get, "http://127.0.0.1:8101/", headers: {'X-Trace'=>/^2B[0-9,A-F]*01$/}, times: 1
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_tracing_not_sampling
|
|
41
|
+
stub_request(:get, "http://127.0.0.2:8101/").to_return(status: 200, body: "", headers: {})
|
|
42
|
+
|
|
43
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
44
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
45
|
+
AppOpticsAPM::API.start_trace('rest_client_tests') do
|
|
46
|
+
RestClient::Resource.new('http://127.0.0.2:8101').get
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
assert_requested :get, "http://127.0.0.2:8101/", headers: {'X-Trace'=>/^2B[0-9,A-F]*00$/}, times: 1
|
|
51
|
+
assert_not_requested :get, "http://127.0.0.2:8101/", headers: {'X-Trace'=>/^2B0*$/}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_no_xtrace
|
|
55
|
+
stub_request(:get, "http://127.0.0.3:8101/").to_return(status: 200, body: "", headers: {})
|
|
56
|
+
|
|
57
|
+
RestClient::Resource.new('http://127.0.0.3:8101').get
|
|
58
|
+
|
|
59
|
+
assert_requested :get, "http://127.0.0.3:8101/", times: 1
|
|
60
|
+
assert_not_requested :get, "http://127.0.0.3:8101/", headers: {'X-Trace'=>/^.*$/}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_blacklisted
|
|
64
|
+
stub_request(:get, "http://127.0.0.4:8101/").to_return(status: 200, body: "", headers: {})
|
|
65
|
+
|
|
66
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
67
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.4'
|
|
68
|
+
AppOpticsAPM::API.start_trace('rest_client_tests') do
|
|
69
|
+
RestClient::Resource.new('http://127.0.0.4:8101').get
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
assert_requested :get, "http://127.0.0.4:8101/", times: 1
|
|
74
|
+
assert_not_requested :get, "http://127.0.0.4:8101/", headers: {'X-Trace'=>/^.*$/}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_not_sampling_blacklisted
|
|
78
|
+
stub_request(:get, "http://127.0.0.5:8101/").to_return(status: 200, body: "", headers: {})
|
|
79
|
+
|
|
80
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
81
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
82
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.5'
|
|
83
|
+
AppOpticsAPM::API.start_trace('rest_client_tests') do
|
|
84
|
+
RestClient::Resource.new('http://127.0.0.5:8101').get
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
assert_requested :get, "http://127.0.0.5:8101/", times: 1
|
|
89
|
+
assert_not_requested :get, "http://127.0.0.5:8101/", headers: {'X-Trace'=>/^.*$/}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_preserves_custom_headers
|
|
93
|
+
stub_request(:get, "http://127.0.0.6:8101/").to_return(status: 200, body: "", headers: {})
|
|
94
|
+
|
|
95
|
+
AppOpticsAPM::API.start_trace('rest_client_tests') do
|
|
96
|
+
RestClient::Resource.new('http://127.0.0.6:8101', headers: { 'Custom' => 'specialvalue' }).get
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
assert_requested :get, "http://127.0.0.6:8101/", headers: {'Custom'=>'specialvalue'}, times: 1
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
unless defined?(JRUBY_VERSION)
|
|
5
|
+
require 'minitest_helper'
|
|
6
|
+
require 'mocha/mini_test'
|
|
7
|
+
|
|
8
|
+
class TyphoeusMockedTest < Minitest::Test
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
12
|
+
@sample_rate = AppOpticsAPM::Config[:sample_rate]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def teardown
|
|
17
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
18
|
+
AppOpticsAPM::Config[:sample_rate] = @sample_rate
|
|
19
|
+
AppOpticsAPM::Config[:blacklist] = []
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
############# Typhoeus::Request ##############################################
|
|
24
|
+
|
|
25
|
+
def test_tracing_sampling
|
|
26
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
27
|
+
request = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
28
|
+
request.run
|
|
29
|
+
|
|
30
|
+
assert request.options[:headers]['X-Trace']
|
|
31
|
+
assert_match /^2B[0-9,A-F]*01$/,request.options[:headers]['X-Trace']
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_tracing_not_sampling
|
|
36
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
37
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
38
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
39
|
+
request = Typhoeus::Request.new("http://127.0.0.1:8101/", {:method=>:get})
|
|
40
|
+
request.run
|
|
41
|
+
|
|
42
|
+
assert request.options[:headers]['X-Trace']
|
|
43
|
+
assert_match /^2B[0-9,A-F]*00$/, request.options[:headers]['X-Trace']
|
|
44
|
+
refute_match /^2B0*$/, request.options[:headers]['X-Trace']
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_no_xtrace
|
|
50
|
+
request = Typhoeus::Request.new("http://127.0.0.1:8101/", {:method=>:get})
|
|
51
|
+
request.run
|
|
52
|
+
|
|
53
|
+
refute request.options[:headers]['X-Trace']
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_blacklisted
|
|
57
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
58
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.1'
|
|
59
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
60
|
+
request = Typhoeus::Request.new("http://127.0.0.1:8101/", {:method=>:get})
|
|
61
|
+
request.run
|
|
62
|
+
|
|
63
|
+
refute request.options[:headers]['X-Trace']
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_not_sampling_blacklisted
|
|
69
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
70
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
71
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.1'
|
|
72
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
73
|
+
request = Typhoeus::Request.new("http://127.0.0.1:8101/", {:method=>:get})
|
|
74
|
+
request.run
|
|
75
|
+
|
|
76
|
+
refute request.options[:headers]['X-Trace']
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_preserves_custom_headers
|
|
82
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
83
|
+
request = Typhoeus::Request.new('http://127.0.0.6:8101', headers: { 'Custom' => 'specialvalue' }, :method => :get)
|
|
84
|
+
request.run
|
|
85
|
+
|
|
86
|
+
assert request.options[:headers]['Custom']
|
|
87
|
+
assert_match /specialvalue/, request.options[:headers]['Custom']
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
############# Typhoeus::Hydra ##############################################
|
|
93
|
+
|
|
94
|
+
def test_hydra_tracing_sampling
|
|
95
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
96
|
+
hydra = Typhoeus::Hydra.hydra
|
|
97
|
+
request_1 = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
98
|
+
request_2 = Typhoeus::Request.new("http://127.0.0.2:8101/counting_sheep", {:method=>:get})
|
|
99
|
+
hydra.queue(request_1)
|
|
100
|
+
hydra.queue(request_2)
|
|
101
|
+
hydra.run
|
|
102
|
+
|
|
103
|
+
assert request_1.options[:headers]['X-Trace'], "There is an X-Trace header"
|
|
104
|
+
assert_match /^2B[0-9,A-F]*01$/, request_1.options[:headers]['X-Trace']
|
|
105
|
+
assert request_2.options[:headers]['X-Trace'], "There is an X-Trace header"
|
|
106
|
+
assert_match /^2B[0-9,A-F]*01$/, request_2.options[:headers]['X-Trace']
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_hydra_tracing_not_sampling
|
|
111
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
112
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
113
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
114
|
+
hydra = Typhoeus::Hydra.hydra
|
|
115
|
+
request_1 = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
116
|
+
request_2 = Typhoeus::Request.new("http://127.0.0.2:8101/counting_sheep", {:method=>:get})
|
|
117
|
+
hydra.queue(request_1)
|
|
118
|
+
hydra.queue(request_2)
|
|
119
|
+
hydra.run
|
|
120
|
+
|
|
121
|
+
assert request_1.options[:headers]['X-Trace'], "There is an X-Trace header"
|
|
122
|
+
assert_match /^2B[0-9,A-F]*00$/, request_1.options[:headers]['X-Trace']
|
|
123
|
+
refute_match /^2B0*$/, request_1.options[:headers]['X-Trace']
|
|
124
|
+
assert request_2.options[:headers]['X-Trace'], "There is an X-Trace header"
|
|
125
|
+
assert_match /^2B[0-9,A-F]*00$/, request_2.options[:headers]['X-Trace']
|
|
126
|
+
refute_match /^2B0*$/, request_2.options[:headers]['X-Trace']
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_hydra_no_xtrace
|
|
132
|
+
hydra = Typhoeus::Hydra.hydra
|
|
133
|
+
request_1 = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
134
|
+
request_2 = Typhoeus::Request.new("http://127.0.0.2:8101/counting_sheep", {:method=>:get})
|
|
135
|
+
hydra.queue(request_1)
|
|
136
|
+
hydra.queue(request_2)
|
|
137
|
+
hydra.run
|
|
138
|
+
|
|
139
|
+
refute request_1.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
140
|
+
refute request_2.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def test_hydra_blacklisted
|
|
144
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
145
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.2'
|
|
146
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
147
|
+
hydra = Typhoeus::Hydra.hydra
|
|
148
|
+
request_1 = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
149
|
+
request_2 = Typhoeus::Request.new("http://127.0.0.2:8101/counting_sheep", {:method=>:get})
|
|
150
|
+
hydra.queue(request_1)
|
|
151
|
+
hydra.queue(request_2)
|
|
152
|
+
hydra.run
|
|
153
|
+
|
|
154
|
+
refute request_1.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
155
|
+
refute request_2.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_hydra_not_sampling_blacklisted
|
|
161
|
+
AppOpticsAPM.config_lock.synchronize do
|
|
162
|
+
AppOpticsAPM::Config[:sample_rate] = 0
|
|
163
|
+
AppOpticsAPM::Config.blacklist << '127.0.0.2'
|
|
164
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
165
|
+
hydra = Typhoeus::Hydra.hydra
|
|
166
|
+
request_1 = Typhoeus::Request.new("http://127.0.0.2:8101/", {:method=>:get})
|
|
167
|
+
request_2 = Typhoeus::Request.new("http://127.0.0.2:8101/counting_sheep", {:method=>:get})
|
|
168
|
+
hydra.queue(request_1)
|
|
169
|
+
hydra.queue(request_2)
|
|
170
|
+
hydra.run
|
|
171
|
+
|
|
172
|
+
refute request_1.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
173
|
+
refute request_2.options[:headers]['X-Trace'], "There should not be an X-Trace header"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_hydra_preserves_custom_headers
|
|
180
|
+
AppOpticsAPM::API.start_trace('typhoeus_tests') do
|
|
181
|
+
hydra = Typhoeus::Hydra.hydra
|
|
182
|
+
request = Typhoeus::Request.new('http://127.0.0.6:8101', headers: { 'Custom' => 'specialvalue' }, :method => :get)
|
|
183
|
+
hydra.queue(request)
|
|
184
|
+
hydra.run
|
|
185
|
+
|
|
186
|
+
assert request.options[:headers]['Custom']
|
|
187
|
+
assert_match /specialvalue/, request.options[:headers]['Custom']
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Somehow the Padrino::Reloader v14 is detecting and loading
|
|
2
|
+
# this file when it shouldn't. Block it from loading for
|
|
3
|
+
# Padrino for now.
|
|
4
|
+
unless defined?(Padrino)
|
|
5
|
+
class Widget < ActiveRecord::Base
|
|
6
|
+
def do_work(*args)
|
|
7
|
+
Widget.first
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def do_error(*args)
|
|
11
|
+
raise "FakeTestError"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if Rails.version >= '5.1'
|
|
16
|
+
class CreateWidgets < ActiveRecord::Migration[5.1]
|
|
17
|
+
def change
|
|
18
|
+
create_table :widgets do |t|
|
|
19
|
+
t.string :name
|
|
20
|
+
t.text :description
|
|
21
|
+
t.timestamps
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
class CreateWidgets < ActiveRecord::Migration
|
|
27
|
+
def change
|
|
28
|
+
create_table :widgets do |t|
|
|
29
|
+
t.string :name
|
|
30
|
+
t.text :description
|
|
31
|
+
t.timestamps
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'minitest_helper'
|
|
5
|
+
|
|
6
|
+
describe "LegacyAppOpticsAPMMethodProfiling" do
|
|
7
|
+
before do
|
|
8
|
+
clear_all_traces
|
|
9
|
+
# Conditionally Undefine TestWorker
|
|
10
|
+
# http://stackoverflow.com/questions/11503558/how-to-undefine-class-in-ruby
|
|
11
|
+
Object.send(:remove_const, :TestWorker) if defined?(TestWorker)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should be loaded, defined and ready' do
|
|
15
|
+
defined?(::AppOpticsAPMMethodProfiling).wont_match nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should trace Class methods' do
|
|
19
|
+
class TestWorker
|
|
20
|
+
def self.do_work
|
|
21
|
+
sleep 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
include AppOpticsAPMMethodProfiling
|
|
26
|
+
profile_method :do_work, 'do_work'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
31
|
+
# Call the profiled class method
|
|
32
|
+
TestWorker.do_work
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
traces = get_all_traces
|
|
36
|
+
traces.count.must_equal 4
|
|
37
|
+
|
|
38
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
39
|
+
|
|
40
|
+
kvs = {}
|
|
41
|
+
kvs["Label"] = 'profile_entry'
|
|
42
|
+
kvs["Language"] = "ruby"
|
|
43
|
+
kvs["ProfileName"] = "do_work"
|
|
44
|
+
kvs["FunctionName"] = "do_work"
|
|
45
|
+
kvs["Class"] = "TestWorker"
|
|
46
|
+
|
|
47
|
+
validate_event_keys(traces[1], kvs)
|
|
48
|
+
|
|
49
|
+
traces[1].has_key?("Layer").must_equal false
|
|
50
|
+
traces[1].has_key?("File").must_equal true
|
|
51
|
+
traces[1].has_key?("LineNumber").must_equal true
|
|
52
|
+
|
|
53
|
+
kvs.clear
|
|
54
|
+
kvs["Label"] = "profile_exit"
|
|
55
|
+
kvs["Language"] = "ruby"
|
|
56
|
+
kvs["ProfileName"] = "do_work"
|
|
57
|
+
|
|
58
|
+
validate_event_keys(traces[2], kvs)
|
|
59
|
+
traces[2].has_key?("Layer").must_equal false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should trace Instance methods' do
|
|
63
|
+
class TestWorker
|
|
64
|
+
def do_work
|
|
65
|
+
sleep 1
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
include AppOpticsAPMMethodProfiling
|
|
69
|
+
profile_method :do_work, 'do_work'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
73
|
+
# Call the profiled class method
|
|
74
|
+
tw = TestWorker.new
|
|
75
|
+
tw.do_work
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
traces = get_all_traces
|
|
79
|
+
traces.count.must_equal 4
|
|
80
|
+
|
|
81
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
82
|
+
|
|
83
|
+
kvs = {}
|
|
84
|
+
kvs["Label"] = 'profile_entry'
|
|
85
|
+
kvs["Language"] = "ruby"
|
|
86
|
+
kvs["ProfileName"] = "do_work"
|
|
87
|
+
kvs["FunctionName"] = "do_work"
|
|
88
|
+
kvs["Class"] = "TestWorker"
|
|
89
|
+
|
|
90
|
+
validate_event_keys(traces[1], kvs)
|
|
91
|
+
|
|
92
|
+
traces[1].has_key?("Layer").must_equal false
|
|
93
|
+
traces[1].has_key?("File").must_equal true
|
|
94
|
+
traces[1].has_key?("LineNumber").must_equal true
|
|
95
|
+
|
|
96
|
+
kvs.clear
|
|
97
|
+
kvs["Label"] = "profile_exit"
|
|
98
|
+
kvs["Language"] = "ruby"
|
|
99
|
+
kvs["ProfileName"] = "do_work"
|
|
100
|
+
|
|
101
|
+
validate_event_keys(traces[2], kvs)
|
|
102
|
+
traces[2].has_key?("Layer").must_equal false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should trace Module class methods' do
|
|
106
|
+
module TestWorker
|
|
107
|
+
def self.do_work
|
|
108
|
+
sleep 1
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
class << self
|
|
112
|
+
include AppOpticsAPMMethodProfiling
|
|
113
|
+
profile_method :do_work, 'do_work'
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
118
|
+
# Call the profiled class method
|
|
119
|
+
TestWorker.do_work
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
traces = get_all_traces
|
|
123
|
+
traces.count.must_equal 4
|
|
124
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
125
|
+
|
|
126
|
+
kvs = {}
|
|
127
|
+
kvs["Label"] = 'profile_entry'
|
|
128
|
+
kvs["Language"] = "ruby"
|
|
129
|
+
kvs["ProfileName"] = "do_work"
|
|
130
|
+
kvs["FunctionName"] = "do_work"
|
|
131
|
+
kvs["Module"] = "TestWorker"
|
|
132
|
+
|
|
133
|
+
validate_event_keys(traces[1], kvs)
|
|
134
|
+
|
|
135
|
+
traces[1].has_key?("Layer").must_equal false
|
|
136
|
+
traces[1].has_key?("File").must_equal true
|
|
137
|
+
traces[1].has_key?("LineNumber").must_equal true
|
|
138
|
+
|
|
139
|
+
kvs.clear
|
|
140
|
+
kvs["Label"] = "profile_exit"
|
|
141
|
+
kvs["Language"] = "ruby"
|
|
142
|
+
kvs["ProfileName"] = "do_work"
|
|
143
|
+
|
|
144
|
+
validate_event_keys(traces[2], kvs)
|
|
145
|
+
traces[2].has_key?("Layer").must_equal false
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'should not store arguments and return value by default' do
|
|
149
|
+
class TestWorker
|
|
150
|
+
def self.do_work(_s, _i, _a, _h)
|
|
151
|
+
sleep 1
|
|
152
|
+
return "the zebra is loose"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
class << self
|
|
156
|
+
include AppOpticsAPMMethodProfiling
|
|
157
|
+
# Default call method
|
|
158
|
+
profile_method :do_work, 'do_work'
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
163
|
+
# Call the profiled class method
|
|
164
|
+
TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
traces = get_all_traces
|
|
168
|
+
traces.count.must_equal 4
|
|
169
|
+
|
|
170
|
+
traces[1].has_key?("Args").must_equal false
|
|
171
|
+
traces[2].has_key?("ReturnValue").must_equal false
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'should store arguments and return value when asked' do
|
|
175
|
+
class TestWorker
|
|
176
|
+
def self.do_work(_s, _i, _a, _h)
|
|
177
|
+
sleep 1
|
|
178
|
+
return "the zebra is loose"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class << self
|
|
182
|
+
include AppOpticsAPMMethodProfiling
|
|
183
|
+
profile_method :do_work, 'do_work', true, true
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
188
|
+
# Call the profiled class method
|
|
189
|
+
TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
traces = get_all_traces
|
|
193
|
+
traces.count.must_equal 4
|
|
194
|
+
|
|
195
|
+
traces[1].has_key?("Args").must_equal true
|
|
196
|
+
traces[1]["Args"].must_equal "\"String Argument\"\n203984\n[\"1\", \"2\", 3]\n{:color=>:black}\n"
|
|
197
|
+
|
|
198
|
+
traces[2].has_key?("ReturnValue").must_equal true
|
|
199
|
+
traces[2]["ReturnValue"].must_equal "\"the zebra is loose\"\n"
|
|
200
|
+
end
|
|
201
|
+
end
|